From 3de6ee87ac36a0c64b4b6b107685574a13d63606 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 13 Apr 2017 15:52:42 +0700 Subject: [PATCH 01/93] Line items to camelCase --- hyperion/lib/hyperion/amazon/amazon.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyperion/lib/hyperion/amazon/amazon.ex b/hyperion/lib/hyperion/amazon/amazon.ex index bae94b0df2..6870d43edb 100644 --- a/hyperion/lib/hyperion/amazon/amazon.ex +++ b/hyperion/lib/hyperion/amazon/amazon.ex @@ -110,7 +110,7 @@ defmodule Hyperion.Amazon do result: %{ referenceNumber: order["AmazonOrderId"], paymentState: "Captured", - line_items: %{ + lineItems: %{ skus: get_sku_map(items, token), }, lineItemAdjustments: [], From 04496e17b68da06fd2901f3332b1406f324ed71f Mon Sep 17 00:00:00 2001 From: Diokuz Date: Thu, 13 Apr 2017 08:21:22 +0300 Subject: [PATCH 02/93] add route --- ashes/src/components/orders/order.jsx | 11 ++++++----- ashes/src/modules/orders/details.js | 7 +++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ashes/src/components/orders/order.jsx b/ashes/src/components/orders/order.jsx index 96517efa97..62b4a8a544 100644 --- a/ashes/src/components/orders/order.jsx +++ b/ashes/src/components/orders/order.jsx @@ -1,3 +1,5 @@ +// @flow + // libs import React, { Element } from 'react'; import _ from 'lodash'; @@ -35,14 +37,12 @@ import type { StateToProps, DispatchToProps, Props, StateType, ReduxState, Order const shippingClaims = readAction(frn.mdl.shipment); const fraudClaims = readAction(frn.oms.fraud); -const orderRefNum = props => { - return props.params.order; -}; +const orderRefNum = props => props.params.order; const mapStateToProps = (state: ReduxState): StateToProps => { return { details: state.orders.details, - isFetching: _.get(state.asyncActions, 'getOrder.inProgress', null), + isFetching: _.get(state.asyncActions, 'getOrder.inProgress', false), fetchError: _.get(state.asyncActions, 'getOrder.err', null), }; }; @@ -60,7 +60,7 @@ export default class Order extends React.Component { componentDidMount() { this.props.clearFetchErrors(); - this.props.fetchOrder(this.orderRefNum); + this.props.fetchAmazonOrder(this.orderRefNum); } componentWillReceiveProps(nextProps: Props): void { @@ -252,6 +252,7 @@ export default class Order extends React.Component { get contents(): Element<*> { const order = this.order; + return (
diff --git a/ashes/src/modules/orders/details.js b/ashes/src/modules/orders/details.js index 201387863b..f494d5739b 100644 --- a/ashes/src/modules/orders/details.js +++ b/ashes/src/modules/orders/details.js @@ -18,6 +18,11 @@ const _getOrder = createAsyncActions( (refNum: string) => Api.get(`/orders/${refNum}`) ); +const _getAmazonOrder = createAsyncActions( + 'getAmazonOrder', + (refNum: string) => Api.get(`/hyperion/orders/111-5296499-9653858/full`) // ${refNum} +); + const _updateOrder = createAsyncActions( 'updateOrder', (id: number, data: Object) => Api.patch(`/orders/${id}`, data) @@ -29,6 +34,7 @@ const _updateShipments = createAsyncActions( ); export const fetchOrder = _getOrder.perform; +export const fetchAmazonOrder = _getAmazonOrder.perform; export const updateOrder = _updateOrder.perform; export const updateShipments = _updateShipments.perform; export const clearFetchErrors =_getOrder.clearErrors; @@ -47,6 +53,7 @@ export function increaseRemorsePeriod(refNum: string) { const reducer = createReducer({ [_getOrder.succeeded]: orderSucceeded, + [_getAmazonOrder.succeeded]: orderSucceeded, [_updateOrder.succeeded]: orderSucceeded, [_updateShipments.succeeded]: (state) => state, }, initialState); From f15e2d7b0a7c5b714cf99347e925f558f85d35ee Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Mon, 17 Apr 2017 17:07:52 +0700 Subject: [PATCH 03/93] Wrap paymentMethods with list --- hyperion/env.dev.template | 5 +++++ hyperion/lib/hyperion/amazon/amazon.ex | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/hyperion/env.dev.template b/hyperion/env.dev.template index 71482fdc8b..109ebde11c 100644 --- a/hyperion/env.dev.template +++ b/hyperion/env.dev.template @@ -20,3 +20,8 @@ PHOENIX_URL=your-developer-appliance-url PHOENIX_PASSWORD=api-password PHOENIX_USER=user PHOENIX_ORG=org + +# misc +PUSH_CHECK_INTERVAL=5 +CREATE_ASHES_PLUGIN=true + diff --git a/hyperion/lib/hyperion/amazon/amazon.ex b/hyperion/lib/hyperion/amazon/amazon.ex index 6870d43edb..9f58399a41 100644 --- a/hyperion/lib/hyperion/amazon/amazon.ex +++ b/hyperion/lib/hyperion/amazon/amazon.ex @@ -146,14 +146,14 @@ defmodule Hyperion.Amazon do zip: order["ShippingAddress"]["PostalCode"], isDefault: false }, - paymentMethods: %{ + paymentMethods: [%{ id: 0, amount: (String.to_float(order["OrderTotal"]["Amount"]) * 100 |> round), currentBalance: 0, availableBalance: 0, createdAt: order["PurchaseDate"], type: order["PaymentMethodDetails"]["PaymentMethodDetail"] - }, + }], orderState: order["OrderStatus"], shippingState: "---", fraudScore: 0, From 43259f8f65c825891c44d652dfb83a95d6876ed4 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Mon, 10 Apr 2017 16:16:37 +0700 Subject: [PATCH 04/93] Add Amazon order and payload --- .../app/models/cord/AmazonOrder.scala | 56 +++++++++++++++++++ .../app/payloads/AmazonOrderPayloads.scala | 13 +++++ phoenix-scala/app/utils/db/SearchTerms.scala | 16 ++++++ 3 files changed, 85 insertions(+) create mode 100644 phoenix-scala/app/models/cord/AmazonOrder.scala create mode 100644 phoenix-scala/app/payloads/AmazonOrderPayloads.scala diff --git a/phoenix-scala/app/models/cord/AmazonOrder.scala b/phoenix-scala/app/models/cord/AmazonOrder.scala new file mode 100644 index 0000000000..a591c3d165 --- /dev/null +++ b/phoenix-scala/app/models/cord/AmazonOrder.scala @@ -0,0 +1,56 @@ +package models.cord + +import java.time.Instant +import shapeless._ +import slick.driver.PostgresDriver.api._ +import utils.Money.Currency +import utils.db._ + +case class AmazonOrder(id: Int = 0, + amazonOrderId: String = "", + orderTotal: Int = 0, + paymentMethodDetail: String = "", + orderType: String = "", + currency: Currency = Currency.USD, + orderStatus: String = "", + createdAt: Instant = Instant.now, + updatedAt: Instant = Instant.now, + archivedAt: Option[Instant] = None) + extends FoxModel[AmazonOrder] + +object AmazonOrder { +// val namePattern = "[^@]+" +} + +class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") { + def id = column[Int]("id", O.PrimaryKey, O.AutoInc) + def amazonOrderId = column[String]("amazon_order_id") + def orderTotal = column[Int]("order_total") + def paymentMethodDetail = column[String]("payment_method_detail") + def orderType = column[String]("order_type") + def currency = column[Currency]("currency") + def orderStatus = column[String]("order_status") + def createdAt = column[Instant]("created_at") + def updatedAt = column[Instant]("updated_at") + def archivedAt = column[Instant]("archived_at") + + def * = + (id, + amazonOrderId, + orderTotal, + paymentMethodDetail, + orderType, + currency, + orderStatus, + createdAt, + updatedAt, + archivedAt) <> ((AmazonOrder.apply _).tupled, AmazonOrder.unapply) +} + +object AmazonOrders + extends FoxTableQuery[AmazonOrder, AmazonOrders](new AmazonOrders(_)) + with ReturningId[AmazonOrder, AmazonOrders] + with SearchByAmazonOrderId[AmazonOrder, AmazonOrders] { + + val returningLens: Lens[AmazonOrder, Int] = lens[AmazonOrder].id +} diff --git a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala new file mode 100644 index 0000000000..c14d051897 --- /dev/null +++ b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala @@ -0,0 +1,13 @@ +package payloads + +import utils.Money.Currency +import java.time.Instant + +object ChannelPayloads { + case class CreateAmazonOrderPayload(amazonOrderId: Option[Int] = None, + orderTotal: Option[Int] = None, + paymentMethodDetail: String, + orderType: String, + currency: Currency, + orderStatus: Instant) +} \ No newline at end of file diff --git a/phoenix-scala/app/utils/db/SearchTerms.scala b/phoenix-scala/app/utils/db/SearchTerms.scala index d7277b7362..f8a5b935a4 100644 --- a/phoenix-scala/app/utils/db/SearchTerms.scala +++ b/phoenix-scala/app/utils/db/SearchTerms.scala @@ -53,6 +53,22 @@ trait SearchByRefNum[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T } } +trait SearchByAmazonOrderId[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T] { + + override def primarySearchTerm = "amazonOrderId" + + def findOneByAmazonOrderId(amazonOrderId: String): DBIO[Option[M]] + + def mustFindByRefNum(amazonOrderId: String, notFoundFailure: String ⇒ Failure = notFound404K)( + implicit ec: EC, + db: DB): DbResultT[M] = { + findOneByAmazonOrderId(amazonOrderId).dbresult.flatMap { + case Some(model) ⇒ DbResultT.good(model) + case None ⇒ DbResultT.failure(notFoundFailure(amazonOrderId)) + } + } +} + trait SearchByCode[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T] { override def primarySearchTerm = "code" From 13db2119a4960fe61cc4d9dfde6d78086a04ff39 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 11 Apr 2017 14:17:50 +0700 Subject: [PATCH 05/93] Add response, routes and service --- .../app/models/cord/AmazonOrder.scala | 34 ++++++++-- .../app/payloads/AmazonOrderPayloads.scala | 11 ++-- .../responses/cord/AmazonOrderResponse.scala | 65 +++++++++++++++++++ .../app/routes/admin/AmazonOrderRoutes.scala | 35 ++++++++++ phoenix-scala/app/server/Main.scala | 1 + .../services/orders/AmazonOrderManager.scala | 29 +++++++++ phoenix-scala/app/utils/db/SearchTerms.scala | 7 +- 7 files changed, 166 insertions(+), 16 deletions(-) create mode 100644 phoenix-scala/app/responses/cord/AmazonOrderResponse.scala create mode 100644 phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala create mode 100644 phoenix-scala/app/services/orders/AmazonOrderManager.scala diff --git a/phoenix-scala/app/models/cord/AmazonOrder.scala b/phoenix-scala/app/models/cord/AmazonOrder.scala index a591c3d165..9d5f75e8a1 100644 --- a/phoenix-scala/app/models/cord/AmazonOrder.scala +++ b/phoenix-scala/app/models/cord/AmazonOrder.scala @@ -1,10 +1,13 @@ package models.cord import java.time.Instant + import shapeless._ -import slick.driver.PostgresDriver.api._ import utils.Money.Currency +import utils.db.ExPostgresDriver.api._ import utils.db._ +import failures._ +import payloads.AmazonOrderPayloads.CreateAmazonOrderPayload case class AmazonOrder(id: Int = 0, amazonOrderId: String = "", @@ -13,13 +16,23 @@ case class AmazonOrder(id: Int = 0, orderType: String = "", currency: Currency = Currency.USD, orderStatus: String = "", + purchaseDate: Instant, createdAt: Instant = Instant.now, - updatedAt: Instant = Instant.now, - archivedAt: Option[Instant] = None) + updatedAt: Instant = Instant.now) extends FoxModel[AmazonOrder] object AmazonOrder { -// val namePattern = "[^@]+" + def build(payload: CreateAmazonOrderPayload): AmazonOrder = + AmazonOrder(id = 0, + amazonOrderId = payload.amazonOrderId, + orderTotal = Option[payload.orderTotal], + paymentMethodDetail = payload.paymentMethodDetail, + orderType = payload.orderType, + currency = payload.currency, + orderStatus = payload.orderStatus, + purchaseDate = payload.purchaseDate, + createdAt = Instant.now, + updatedAt = Instant.now) } class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") { @@ -30,9 +43,9 @@ class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") def orderType = column[String]("order_type") def currency = column[Currency]("currency") def orderStatus = column[String]("order_status") + def purchaseDate = column[Instant]("purchased_date") def createdAt = column[Instant]("created_at") def updatedAt = column[Instant]("updated_at") - def archivedAt = column[Instant]("archived_at") def * = (id, @@ -42,9 +55,9 @@ class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") orderType, currency, orderStatus, + purchaseDate, createdAt, - updatedAt, - archivedAt) <> ((AmazonOrder.apply _).tupled, AmazonOrder.unapply) + updatedAt) <> ((AmazonOrder.apply _).tupled, AmazonOrder.unapply) } object AmazonOrders @@ -53,4 +66,11 @@ object AmazonOrders with SearchByAmazonOrderId[AmazonOrder, AmazonOrders] { val returningLens: Lens[AmazonOrder, Int] = lens[AmazonOrder].id + + def findOneByAmazonOrderId(amazonOrderId: String): DBIO[Option[AmazonOrder]] = + filter(_.amazonOrderId === amazonOrderId).one + + def mustFindOneOr404(amazonOrderId: String)(implicit ec: EC): DbResultT[AmazonOrder] = + findOneByAmazonOrderId(amazonOrderId).mustFindOr( + NotFoundFailure404(s"Amazon order with id=$amazonOrderId not found")) } diff --git a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala index c14d051897..eac51e4bdf 100644 --- a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala +++ b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala @@ -3,11 +3,12 @@ package payloads import utils.Money.Currency import java.time.Instant -object ChannelPayloads { +object AmazonOrderPayloads { case class CreateAmazonOrderPayload(amazonOrderId: Option[Int] = None, orderTotal: Option[Int] = None, paymentMethodDetail: String, - orderType: String, - currency: Currency, - orderStatus: Instant) -} \ No newline at end of file + orderType: String = "", + currency: Currency = Currency.USD, + orderStatus: String = "", + purchaseDate: Instant) +} diff --git a/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala new file mode 100644 index 0000000000..eb3be6930d --- /dev/null +++ b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala @@ -0,0 +1,65 @@ +package responses.cord + +import java.time.Instant +import models.cord.AmazonOrder +import utils.Money.Currency +import responses._ + +case class AmazonOrderResponse(id: Int, + amazonOrderId: String = "", + orderTotal: Int = 0, + paymentMethodDetail: String = "", + orderType: String = "", + currency: Currency = Currency.USD, + orderStatus: String = "", + purchaseDate: Instant, + createdAt: Instant = Instant.now, + updatedAt: Instant = Instant.now) + extends ResponseItem + +object AmazonOrderResponse { + case class Root(id: Int, + amazonOrderId: String, + orderTotal: Int, + paymentMethodDetail: String, + orderType: String, + currency: Currency, + orderStatus: String, + purchaseDate: Instant) + + def build(amazonOrder: AmazonOrder): Root = + Root(id = amazonOrder.id, + amazonOrderId = amazonOrder.amazonOrderId, + orderTotal = amazonOrder.orderTotal, + paymentMethodDetail = amazonOrder.paymentMethodDetail, + orderType = amazonOrder.orderType, + currency = amazonOrder.currency, + orderStatus = amazonOrder.orderStatus, + purchaseDate = amazonOrder.purchaseDate) + + case class AmazonOrderInfo(amazonOrderId: String, + orderTotal: Int, + paymentMethodDetail: String, + orderType: String, + currency: Currency, + orderStatus: String, + purchaseDate: Instant, + createdAt: Instant, + updatedAt: Instant) + + object AmazonOrderInfo { + def fromAmazonOrder(amazonOrder: AmazonOrder): AmazonOrderInfo = { + AmazonOrderInfo(amazonOrderId = amazonOrder.amazonOrderId, + orderTotal = amazonOrder.orderTotal, + paymentMethodDetail = amazonOrder.paymentMethodDetail, + orderType = amazonOrder.orderType, + currency = amazonOrder.currency, + orderStatus = amazonOrder.orderStatus, + purchaseDate = amazonOrder.purchaseDate, + createdAt = amazonOrder.createdAt, + updatedAt = amazonOrder.updatedAt) + } + } + + type ListAmazonOrdersAnswer = Seq[AmazonOrderInfo] +} diff --git a/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala new file mode 100644 index 0000000000..5c38d54483 --- /dev/null +++ b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala @@ -0,0 +1,35 @@ +package routes.admin + +import akka.http.scaladsl.server.Directives._ +import akka.http.scaladsl.server.Route +import utils.http.JsonSupport._ +import models.account.User +import org.json4s.native.JsonParser.StringVal +import payloads.AmazonOrderPayloads._ +import services.AmazonOrderManager +import responses.cord.AmazonOrderResponse._ +import services.Authenticator.AuthData +import utils.aliases._ +import utils.http.CustomDirectives._ +import utils.http.Http._ + +object AmazonOrderRoutes { + def routes(implicit ec: EC, db: DB, auth: AU): Route = { + activityContext(auth) { implicit ac ⇒ + pathPrefix("amazon_orders") { + (get & pathEnd) { + getOrFailures { + AmazonOrderManager.listAmazonOrders() + } + } ~ + pathPrefix(Segment) { amazonOrderId ⇒ + (get & pathEnd) { + getOrFailures { + AmazonOrderManager.findByAmazonOrderId(amazonOrderId) + } + } + } + } + } + } +} diff --git a/phoenix-scala/app/server/Main.scala b/phoenix-scala/app/server/Main.scala index c623d3e016..4b4f87cfc3 100644 --- a/phoenix-scala/app/server/Main.scala +++ b/phoenix-scala/app/server/Main.scala @@ -101,6 +101,7 @@ class Service( routes.admin.NotificationRoutes.routes ~ routes.admin.AssignmentsRoutes.routes ~ routes.admin.OrderRoutes.routes ~ + routes.admin.AmazonOrderRoutes.routes ~ routes.admin.CartRoutes.routes ~ routes.admin.CustomerRoutes.routes ~ routes.admin.CustomerGroupsRoutes.routes ~ diff --git a/phoenix-scala/app/services/orders/AmazonOrderManager.scala b/phoenix-scala/app/services/orders/AmazonOrderManager.scala new file mode 100644 index 0000000000..6c08c5dd34 --- /dev/null +++ b/phoenix-scala/app/services/orders/AmazonOrderManager.scala @@ -0,0 +1,29 @@ +package services + +import cats.implicits._ +import payloads.AmazonOrderPayloads._ +import models.cord._ +import responses.cord.AmazonOrderResponse +import responses.cord.AmazonOrderResponse._ +import responses.cord.AmazonOrderResponse.AmazonOrderInfo._ +import utils.aliases._ +import utils.db._ + +object AmazonOrderManager { + def findByAmazonOrderId(amazonOrderId: String)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrderResponse.Root] = + for { + amazonOrder <- * <~ AmazonOrders.mustFindOneOr404(amazonOrderId) + } yield AmazonOrderResponse.build(amazonOrder) + + def createAmazonOrder(payload: CreateAmazonOrderPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrderResponse.Root] = + for { + amazonOrder <- * <~ AmazonOrders.create(AmazonOrder.build(payload)) + } AmazonOrderResponse.build(amazonOrder) + + def listAmazonOrders()(implicit ec: EC, db: DB, ac: AC): DbResultT[ListAmazonOrdersAnswer] = { + for { + amazonOrders ← * <~ AmazonOrders.result + } yield amazonOrders.map(AmazonOrderInfo.fromAmazonOrder) + } + +} diff --git a/phoenix-scala/app/utils/db/SearchTerms.scala b/phoenix-scala/app/utils/db/SearchTerms.scala index f8a5b935a4..23beadc84a 100644 --- a/phoenix-scala/app/utils/db/SearchTerms.scala +++ b/phoenix-scala/app/utils/db/SearchTerms.scala @@ -59,14 +59,13 @@ trait SearchByAmazonOrderId[M <: FoxModel[M], T <: FoxTable[M]] extends SearchBy def findOneByAmazonOrderId(amazonOrderId: String): DBIO[Option[M]] - def mustFindByRefNum(amazonOrderId: String, notFoundFailure: String ⇒ Failure = notFound404K)( - implicit ec: EC, - db: DB): DbResultT[M] = { + def mustFindByAmazonOrderId( + amazonOrderId: String, + notFoundFailure: String ⇒ Failure = notFound404K)(implicit ec: EC, db: DB): DbResultT[M] = findOneByAmazonOrderId(amazonOrderId).dbresult.flatMap { case Some(model) ⇒ DbResultT.good(model) case None ⇒ DbResultT.failure(notFoundFailure(amazonOrderId)) } - } } trait SearchByCode[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T] { From 6664280059503fa0e261065562369bc3c7778d85 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 11 Apr 2017 15:31:23 +0700 Subject: [PATCH 06/93] Fix Errors --- phoenix-scala/README.md | 1 + .../app/models/cord/AmazonOrder.scala | 3 ++- .../app/payloads/AmazonOrderPayloads.scala | 4 ++-- .../app/routes/admin/AmazonOrderRoutes.scala | 20 ++++++++++--------- .../services/orders/AmazonOrderManager.scala | 19 +++++------------- .../sql/V4.117__create_amazon_orders.sql | 12 +++++++++++ 6 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 phoenix-scala/sql/V4.117__create_amazon_orders.sql diff --git a/phoenix-scala/README.md b/phoenix-scala/README.md index a6da6cb2d7..84a4f16739 100644 --- a/phoenix-scala/README.md +++ b/phoenix-scala/README.md @@ -19,6 +19,7 @@ - `sbt '~re-start'`: reloads the application automatically on code changes - `sbt seed`: execute the seeds +- `sbt seedDemo`: execute demo seeds: admins, random data for orders and so on... - `sbt test`: run all of the unit and integration tests - `sbt '~test:compile`: re-compiles the application automatically on code changes diff --git a/phoenix-scala/app/models/cord/AmazonOrder.scala b/phoenix-scala/app/models/cord/AmazonOrder.scala index 9d5f75e8a1..51fc0f4643 100644 --- a/phoenix-scala/app/models/cord/AmazonOrder.scala +++ b/phoenix-scala/app/models/cord/AmazonOrder.scala @@ -6,6 +6,7 @@ import shapeless._ import utils.Money.Currency import utils.db.ExPostgresDriver.api._ import utils.db._ +import utils.aliases._ import failures._ import payloads.AmazonOrderPayloads.CreateAmazonOrderPayload @@ -25,7 +26,7 @@ object AmazonOrder { def build(payload: CreateAmazonOrderPayload): AmazonOrder = AmazonOrder(id = 0, amazonOrderId = payload.amazonOrderId, - orderTotal = Option[payload.orderTotal], + orderTotal = payload.orderTotal, paymentMethodDetail = payload.paymentMethodDetail, orderType = payload.orderType, currency = payload.currency, diff --git a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala index eac51e4bdf..b00809c214 100644 --- a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala +++ b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala @@ -4,8 +4,8 @@ import utils.Money.Currency import java.time.Instant object AmazonOrderPayloads { - case class CreateAmazonOrderPayload(amazonOrderId: Option[Int] = None, - orderTotal: Option[Int] = None, + case class CreateAmazonOrderPayload(amazonOrderId: String = "", + orderTotal: Int, paymentMethodDetail: String, orderType: String = "", currency: Currency = Currency.USD, diff --git a/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala index 5c38d54483..7659c6e8c2 100644 --- a/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala +++ b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala @@ -6,8 +6,9 @@ import utils.http.JsonSupport._ import models.account.User import org.json4s.native.JsonParser.StringVal import payloads.AmazonOrderPayloads._ -import services.AmazonOrderManager +import services.AmazonOrderManager._ import responses.cord.AmazonOrderResponse._ +import responses.cord.AmazonOrderResponse import services.Authenticator.AuthData import utils.aliases._ import utils.http.CustomDirectives._ @@ -17,15 +18,16 @@ object AmazonOrderRoutes { def routes(implicit ec: EC, db: DB, auth: AU): Route = { activityContext(auth) { implicit ac ⇒ pathPrefix("amazon_orders") { - (get & pathEnd) { - getOrFailures { - AmazonOrderManager.listAmazonOrders() - } - } ~ +// (get & pathEnd) { +// getOrFailures { +// AmazonOrderManager.listAmazonOrders() +// } +// } ~ + pathPrefix(Segment) { amazonOrderId ⇒ - (get & pathEnd) { - getOrFailures { - AmazonOrderManager.findByAmazonOrderId(amazonOrderId) + (post & pathEnd & entity(as[CreateAmazonOrderPayload])) { payload ⇒ + mutateOrFailures { + createAmazonOrder(payload) } } } diff --git a/phoenix-scala/app/services/orders/AmazonOrderManager.scala b/phoenix-scala/app/services/orders/AmazonOrderManager.scala index 6c08c5dd34..50f241eee6 100644 --- a/phoenix-scala/app/services/orders/AmazonOrderManager.scala +++ b/phoenix-scala/app/services/orders/AmazonOrderManager.scala @@ -10,20 +10,11 @@ import utils.aliases._ import utils.db._ object AmazonOrderManager { - def findByAmazonOrderId(amazonOrderId: String)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrderResponse.Root] = + def createAmazonOrder(payload: CreateAmazonOrderPayload)( + implicit ec: EC, + db: DB, + au: AU): DbResultT[AmazonOrderResponse.Root] = for { - amazonOrder <- * <~ AmazonOrders.mustFindOneOr404(amazonOrderId) + amazonOrder ← * <~ AmazonOrders.create(AmazonOrder.build(payload)) } yield AmazonOrderResponse.build(amazonOrder) - - def createAmazonOrder(payload: CreateAmazonOrderPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrderResponse.Root] = - for { - amazonOrder <- * <~ AmazonOrders.create(AmazonOrder.build(payload)) - } AmazonOrderResponse.build(amazonOrder) - - def listAmazonOrders()(implicit ec: EC, db: DB, ac: AC): DbResultT[ListAmazonOrdersAnswer] = { - for { - amazonOrders ← * <~ AmazonOrders.result - } yield amazonOrders.map(AmazonOrderInfo.fromAmazonOrder) - } - } diff --git a/phoenix-scala/sql/V4.117__create_amazon_orders.sql b/phoenix-scala/sql/V4.117__create_amazon_orders.sql new file mode 100644 index 0000000000..132bf293eb --- /dev/null +++ b/phoenix-scala/sql/V4.117__create_amazon_orders.sql @@ -0,0 +1,12 @@ +create table amazon_orders( + id bigserial primary key, + amazon_order_id generic_string, + order_total integer not null default 0, + payment_method_detail generic_string, + order_type generic_string, + currency currency, + order_status generic_string, + purchased_date timestamp, + updated_at timestamp, + created_at timestamp +) \ No newline at end of file From 49b52f5654db62aa7de34eb4e1dec9fbe4f0458a Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 11 Apr 2017 17:30:05 +0700 Subject: [PATCH 07/93] Make order creation idempotent --- .../app/models/cord/AmazonOrder.scala | 44 ++++++++++++------- .../services/orders/AmazonOrderManager.scala | 23 +++++++--- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/phoenix-scala/app/models/cord/AmazonOrder.scala b/phoenix-scala/app/models/cord/AmazonOrder.scala index 51fc0f4643..6bd8ea0c3a 100644 --- a/phoenix-scala/app/models/cord/AmazonOrder.scala +++ b/phoenix-scala/app/models/cord/AmazonOrder.scala @@ -34,6 +34,33 @@ object AmazonOrder { purchaseDate = payload.purchaseDate, createdAt = Instant.now, updatedAt = Instant.now) + + def fromExistingAmazonOrder(existingOrder: AmazonOrder): AmazonOrder = + AmazonOrder(id = existingOrder.id, + amazonOrderId = existingOrder.amazonOrderId, + orderTotal = existingOrder.orderTotal, + paymentMethodDetail = existingOrder.paymentMethodDetail, + orderType = existingOrder.orderType, + currency = existingOrder.currency, + orderStatus = existingOrder.orderStatus, + purchaseDate = existingOrder.purchaseDate, + createdAt = existingOrder.createdAt, + updatedAt = existingOrder.updatedAt) +} + +object AmazonOrders + extends FoxTableQuery[AmazonOrder, AmazonOrders](new AmazonOrders(_)) + with ReturningId[AmazonOrder, AmazonOrders] + with SearchByAmazonOrderId[AmazonOrder, AmazonOrders] { + + val returningLens: Lens[AmazonOrder, Int] = lens[AmazonOrder].id + + def findOneByAmazonOrderId(amazonOrderId: String): DBIO[Option[AmazonOrder]] = + filter(_.amazonOrderId === amazonOrderId).one + + def mustFindOneOr404(amazonOrderId: String)(implicit ec: EC): DbResultT[AmazonOrder] = + findOneByAmazonOrderId(amazonOrderId).mustFindOr( + NotFoundFailure404(s"Amazon order with id=$amazonOrderId not found")) } class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") { @@ -44,7 +71,7 @@ class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") def orderType = column[String]("order_type") def currency = column[Currency]("currency") def orderStatus = column[String]("order_status") - def purchaseDate = column[Instant]("purchased_date") + def purchaseDate = column[Instant]("purchase_date") def createdAt = column[Instant]("created_at") def updatedAt = column[Instant]("updated_at") @@ -60,18 +87,3 @@ class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") createdAt, updatedAt) <> ((AmazonOrder.apply _).tupled, AmazonOrder.unapply) } - -object AmazonOrders - extends FoxTableQuery[AmazonOrder, AmazonOrders](new AmazonOrders(_)) - with ReturningId[AmazonOrder, AmazonOrders] - with SearchByAmazonOrderId[AmazonOrder, AmazonOrders] { - - val returningLens: Lens[AmazonOrder, Int] = lens[AmazonOrder].id - - def findOneByAmazonOrderId(amazonOrderId: String): DBIO[Option[AmazonOrder]] = - filter(_.amazonOrderId === amazonOrderId).one - - def mustFindOneOr404(amazonOrderId: String)(implicit ec: EC): DbResultT[AmazonOrder] = - findOneByAmazonOrderId(amazonOrderId).mustFindOr( - NotFoundFailure404(s"Amazon order with id=$amazonOrderId not found")) -} diff --git a/phoenix-scala/app/services/orders/AmazonOrderManager.scala b/phoenix-scala/app/services/orders/AmazonOrderManager.scala index 50f241eee6..4c9c4e6462 100644 --- a/phoenix-scala/app/services/orders/AmazonOrderManager.scala +++ b/phoenix-scala/app/services/orders/AmazonOrderManager.scala @@ -4,8 +4,6 @@ import cats.implicits._ import payloads.AmazonOrderPayloads._ import models.cord._ import responses.cord.AmazonOrderResponse -import responses.cord.AmazonOrderResponse._ -import responses.cord.AmazonOrderResponse.AmazonOrderInfo._ import utils.aliases._ import utils.db._ @@ -13,8 +11,21 @@ object AmazonOrderManager { def createAmazonOrder(payload: CreateAmazonOrderPayload)( implicit ec: EC, db: DB, - au: AU): DbResultT[AmazonOrderResponse.Root] = - for { - amazonOrder ← * <~ AmazonOrders.create(AmazonOrder.build(payload)) - } yield AmazonOrderResponse.build(amazonOrder) + au: AU): DbResultT[AmazonOrderResponse.Root] = { + + val amazonOrderT = for { + result ← * <~ AmazonOrders + .findOneByAmazonOrderId(payload.amazonOrderId) + .findOrCreateExtended(AmazonOrders.create(AmazonOrder.build(payload))) + (existingOrder, foundOrCreated) = result + } yield result + + amazonOrderT.map { + case (existingOrder, foundOrCreated) ⇒ + AmazonOrderResponse.build(AmazonOrder.fromExistingAmazonOrder(existingOrder)) + } + } +// for { +// amazonOrder ← * <~ AmazonOrders.create(AmazonOrder.build(payload)) +// } yield AmazonOrderResponse.build(amazonOrder) } From 082864fbbe86819185a6608ae2307f53262daaf2 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 11 Apr 2017 17:30:53 +0700 Subject: [PATCH 08/93] Fix routes and response --- .../responses/cord/AmazonOrderResponse.scala | 27 +------------------ .../app/routes/admin/AmazonOrderRoutes.scala | 8 +++--- 2 files changed, 4 insertions(+), 31 deletions(-) diff --git a/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala index eb3be6930d..cbebf6afdc 100644 --- a/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala +++ b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala @@ -18,6 +18,7 @@ case class AmazonOrderResponse(id: Int, extends ResponseItem object AmazonOrderResponse { + case class Root(id: Int, amazonOrderId: String, orderTotal: Int, @@ -36,30 +37,4 @@ object AmazonOrderResponse { currency = amazonOrder.currency, orderStatus = amazonOrder.orderStatus, purchaseDate = amazonOrder.purchaseDate) - - case class AmazonOrderInfo(amazonOrderId: String, - orderTotal: Int, - paymentMethodDetail: String, - orderType: String, - currency: Currency, - orderStatus: String, - purchaseDate: Instant, - createdAt: Instant, - updatedAt: Instant) - - object AmazonOrderInfo { - def fromAmazonOrder(amazonOrder: AmazonOrder): AmazonOrderInfo = { - AmazonOrderInfo(amazonOrderId = amazonOrder.amazonOrderId, - orderTotal = amazonOrder.orderTotal, - paymentMethodDetail = amazonOrder.paymentMethodDetail, - orderType = amazonOrder.orderType, - currency = amazonOrder.currency, - orderStatus = amazonOrder.orderStatus, - purchaseDate = amazonOrder.purchaseDate, - createdAt = amazonOrder.createdAt, - updatedAt = amazonOrder.updatedAt) - } - } - - type ListAmazonOrdersAnswer = Seq[AmazonOrderInfo] } diff --git a/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala index 7659c6e8c2..56edfed830 100644 --- a/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala +++ b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala @@ -24,11 +24,9 @@ object AmazonOrderRoutes { // } // } ~ - pathPrefix(Segment) { amazonOrderId ⇒ - (post & pathEnd & entity(as[CreateAmazonOrderPayload])) { payload ⇒ - mutateOrFailures { - createAmazonOrder(payload) - } + (post & pathEnd & entity(as[CreateAmazonOrderPayload])) { payload ⇒ + mutateOrFailures { + createAmazonOrder(payload) } } } From 25803a30f4f01caababd29ab66688752067d76cb Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Wed, 12 Apr 2017 17:04:00 +0700 Subject: [PATCH 09/93] Add amazon_order_search_view and stuff --- green-river/README.md | 7 ++++ .../src/main/resources/application.conf | 1 + .../src/main/scala/consumer/Workers.scala | 3 +- .../admin/AmazonOrdersSearchView.scala | 23 ++++++++++ .../R__amazon_orders_search_view_triggers.sql | 42 +++++++++++++++++++ .../sql/V4.117__create_amazon_orders.sql | 21 ++++++++-- 6 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala create mode 100644 phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql diff --git a/green-river/README.md b/green-river/README.md index 233767f86f..d638092f75 100644 --- a/green-river/README.md +++ b/green-river/README.md @@ -2,3 +2,10 @@ An event-sourcing system based on Kafka that utilizes bottledwater to capture all of the changes that occur in Postgres and pipe them into Kafka. It's built in Scala and powers logging and searching capabilities in the system. + +### tasks + +All tasks should be run with env `localhost` when running green-river locally. + +To create mappings run `sbt -Denv=localhost createMappings` +To start Green-river run `sbt -Denv=localhost '~re-start'` diff --git a/green-river/src/main/resources/application.conf b/green-river/src/main/resources/application.conf index 8553a3f2b4..3bc5baf485 100644 --- a/green-river/src/main/resources/application.conf +++ b/green-river/src/main/resources/application.conf @@ -7,6 +7,7 @@ kafka.indices { admin = [ "failed_authorizations_search_view", + "amazon_orders_search_view" ] } diff --git a/green-river/src/main/scala/consumer/Workers.scala b/green-river/src/main/scala/consumer/Workers.scala index a8e34aea84..403539e7fe 100644 --- a/green-river/src/main/scala/consumer/Workers.scala +++ b/green-river/src/main/scala/consumer/Workers.scala @@ -189,6 +189,7 @@ object Workers { "store_credits_search_view" → StoreCreditsSearchView(), "scoped_activity_trails" → ActivityConnectionTransformer(connectionInfo), "taxonomies_search_view" → TaxonomiesSearchView(), - "taxons_search_view" → TaxonsSearchView() + "taxons_search_view" → TaxonsSearchView(), + "amazon_orders_search_view" → AmazonOrdersSearchView() ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala new file mode 100644 index 0000000000..ab9250e35c --- /dev/null +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala @@ -0,0 +1,23 @@ +package consumer.elastic.mappings.admin + +import com.sksamuel.elastic4s.ElasticDsl.{mapping ⇒ esMapping, _} +import com.sksamuel.elastic4s.mappings.FieldType._ +import consumer.aliases._ +import consumer.elastic.AvroTransformer +import consumer.elastic.mappings.dateFormat + +final case class AmazonOrdersSearchView()(implicit ec: EC) extends AvroTransformer { + def topic() = "amazon_orders_search_view" + def mapping() = esMapping(topic()).fields( + field("id", LongType), + field("amazonOrderId", StringType).index("not_analyzed"), + field("orderTotal", IntegerType), + field("paymentMethodDetail", StringType).index("not_analyzed"), + field("orderType", StringType).index("not_analyzed"), + field("currency", StringType).index("not_analyzed"), + field("orderStatus", StringType).index("not_analyzed"), + field("purchaseDate", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat), + field("deletedAt", DateType).format(dateFormat) + ) +} diff --git a/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql b/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql new file mode 100644 index 0000000000..ca1891952f --- /dev/null +++ b/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql @@ -0,0 +1,42 @@ +-- insert amazon order function +create or replace function update_amazon_orders_view_insert_fn() returns trigger as $$ + begin + insert into amazon_orders_search_view ( + id, + amazon_order_id, + order_total, + payment_method_detail, + order_type, + currency, + order_status, + purchase_date, + updated_at, + created_at + ) select distinct on (new.id) + new.id as id, + new.amazon_order_id as amazon_order_id, + new.order_total as order_total, + new.payment_method_detail as payment_method_detail, + new.order_type as order_type, + new.currency as currency, + new.order_status as order_status, + to_char(new.purchase_date, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as purchase_date, + to_char(new.created_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as created_at, + to_char(new.updated_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as updated_at; + return null; + end; +$$ language plpgsql; + + +-- delete amazon order function +drop function if exists update_amazon_orders_view_delete_fn(); + +-- recreate insert amazon order trigger +drop trigger if exists update_amazon_orders_view_insert_trigger on amazon_orders; +create trigger update_amazon_orders_view_insert_trigger + after insert on amazon_orders + for each row + execute procedure update_amazon_orders_view_insert_fn(); + +-- recreate delete amazon order trigger +drop trigger if exists update_amazon_orders_view_delete_trigger on amazon_orders; diff --git a/phoenix-scala/sql/V4.117__create_amazon_orders.sql b/phoenix-scala/sql/V4.117__create_amazon_orders.sql index 132bf293eb..5b5d2da1ae 100644 --- a/phoenix-scala/sql/V4.117__create_amazon_orders.sql +++ b/phoenix-scala/sql/V4.117__create_amazon_orders.sql @@ -6,7 +6,20 @@ create table amazon_orders( order_type generic_string, currency currency, order_status generic_string, - purchased_date timestamp, - updated_at timestamp, - created_at timestamp -) \ No newline at end of file + purchase_date generic_timestamp, + updated_at generic_timestamp, + created_at generic_timestamp +); + +create table amazon_orders_search_view ( + id bigint primary key, + amazon_order_id generic_string, + order_total integer not null default 0, + payment_method_detail generic_string, + order_type generic_string, + currency currency, + order_status generic_string, + purchase_date json_timestamp, + updated_at json_timestamp, + created_at json_timestamp +); From 1f28d25e2d9abaf8135719073cbb1bfa6fdd7627 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Wed, 12 Apr 2017 17:04:18 +0700 Subject: [PATCH 10/93] Fix seeds to run in development env --- phoenix-scala/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phoenix-scala/build.sbt b/phoenix-scala/build.sbt index 5215c8ab7c..aa04f77eaf 100644 --- a/phoenix-scala/build.sbt +++ b/phoenix-scala/build.sbt @@ -88,7 +88,7 @@ lazy val seeder = (project in file("seeder")) reformatOnCompileSettings, // scalafmt, Revolver.settings, // we cannot fork and set javaOptions simply, as it causes some weird issue with db schema creation - initialize ~= (_ => System.setProperty("phoenix.env", "test" )), + initialize ~= (_ => System.setProperty("phoenix.env", "development" )), assemblyMergeStrategy in assembly := { case PathList("org", "joda", "time", xs @ _ *) ⇒ MergeStrategy.first From 85c957c0f78b53530a292cc181a6e2be14eee58b Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Wed, 12 Apr 2017 17:11:11 +0700 Subject: [PATCH 11/93] Remove unused stuff --- phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala | 6 ------ phoenix-scala/app/services/orders/AmazonOrderManager.scala | 3 --- 2 files changed, 9 deletions(-) diff --git a/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala index 56edfed830..59cf58a780 100644 --- a/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala +++ b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala @@ -18,12 +18,6 @@ object AmazonOrderRoutes { def routes(implicit ec: EC, db: DB, auth: AU): Route = { activityContext(auth) { implicit ac ⇒ pathPrefix("amazon_orders") { -// (get & pathEnd) { -// getOrFailures { -// AmazonOrderManager.listAmazonOrders() -// } -// } ~ - (post & pathEnd & entity(as[CreateAmazonOrderPayload])) { payload ⇒ mutateOrFailures { createAmazonOrder(payload) diff --git a/phoenix-scala/app/services/orders/AmazonOrderManager.scala b/phoenix-scala/app/services/orders/AmazonOrderManager.scala index 4c9c4e6462..51f7455d16 100644 --- a/phoenix-scala/app/services/orders/AmazonOrderManager.scala +++ b/phoenix-scala/app/services/orders/AmazonOrderManager.scala @@ -25,7 +25,4 @@ object AmazonOrderManager { AmazonOrderResponse.build(AmazonOrder.fromExistingAmazonOrder(existingOrder)) } } -// for { -// amazonOrder ← * <~ AmazonOrders.create(AmazonOrder.build(payload)) -// } yield AmazonOrderResponse.build(amazonOrder) } From 38593b74b8987afde92e6990f6025f05b6cc7839 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Wed, 12 Apr 2017 17:27:15 +0700 Subject: [PATCH 12/93] Fix GR mapping --- .../elastic/mappings/admin/AmazonOrdersSearchView.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala index ab9250e35c..023d88e9bd 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala @@ -17,7 +17,7 @@ final case class AmazonOrdersSearchView()(implicit ec: EC) extends AvroTransform field("currency", StringType).index("not_analyzed"), field("orderStatus", StringType).index("not_analyzed"), field("purchaseDate", DateType).format(dateFormat), + field("createdAt", DateType).format(dateFormat) field("updatedAt", DateType).format(dateFormat), - field("deletedAt", DateType).format(dateFormat) ) } From f504a9d8391f637a9680ec250481614508a6c829 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Wed, 12 Apr 2017 17:29:53 +0700 Subject: [PATCH 13/93] Fix typo --- .../elastic/mappings/admin/AmazonOrdersSearchView.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala index 023d88e9bd..1ee91b1596 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala @@ -17,7 +17,7 @@ final case class AmazonOrdersSearchView()(implicit ec: EC) extends AvroTransform field("currency", StringType).index("not_analyzed"), field("orderStatus", StringType).index("not_analyzed"), field("purchaseDate", DateType).format(dateFormat), - field("createdAt", DateType).format(dateFormat) + field("createdAt", DateType).format(dateFormat), field("updatedAt", DateType).format(dateFormat), ) } From 431ac3dd0bad43f58e4be00dda6c5186be587181 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Wed, 12 Apr 2017 17:30:51 +0700 Subject: [PATCH 14/93] Fix typo --- .../elastic/mappings/admin/AmazonOrdersSearchView.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala index 1ee91b1596..9dd2355514 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala @@ -18,6 +18,6 @@ final case class AmazonOrdersSearchView()(implicit ec: EC) extends AvroTransform field("orderStatus", StringType).index("not_analyzed"), field("purchaseDate", DateType).format(dateFormat), field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat) ) } From 487d2f4ffad3f6428acb1694b89fc60357dc499e Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 13 Apr 2017 16:00:29 +0700 Subject: [PATCH 15/93] Add update action to AmazonOrder --- .../app/payloads/AmazonOrderPayloads.scala | 2 ++ .../app/routes/admin/AmazonOrderRoutes.scala | 7 ++++++ .../services/orders/AmazonOrderManager.scala | 9 ++++++++ .../R__amazon_orders_search_view_triggers.sql | 23 +++++++++++++++++++ 4 files changed, 41 insertions(+) diff --git a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala index b00809c214..34a87df261 100644 --- a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala +++ b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala @@ -11,4 +11,6 @@ object AmazonOrderPayloads { currency: Currency = Currency.USD, orderStatus: String = "", purchaseDate: Instant) + + case class UpdateAmazonOrderPayload(orderStatus: String) } diff --git a/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala index 59cf58a780..b7f9f8e4d0 100644 --- a/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala +++ b/phoenix-scala/app/routes/admin/AmazonOrderRoutes.scala @@ -22,6 +22,13 @@ object AmazonOrderRoutes { mutateOrFailures { createAmazonOrder(payload) } + } ~ + pathPrefix(Segment) { amazonOrderId ⇒ + (patch & pathEnd & entity(as[UpdateAmazonOrderPayload])) { payload ⇒ + mutateOrFailures { + updateAmazonOrder(amazonOrderId, payload) + } + } } } } diff --git a/phoenix-scala/app/services/orders/AmazonOrderManager.scala b/phoenix-scala/app/services/orders/AmazonOrderManager.scala index 51f7455d16..949dda7f8d 100644 --- a/phoenix-scala/app/services/orders/AmazonOrderManager.scala +++ b/phoenix-scala/app/services/orders/AmazonOrderManager.scala @@ -25,4 +25,13 @@ object AmazonOrderManager { AmazonOrderResponse.build(AmazonOrder.fromExistingAmazonOrder(existingOrder)) } } + def updateAmazonOrder(amazonOrderId: String, payload: UpdateAmazonOrderPayload)( + implicit ec: EC, + db: DB, + au: AU): DbResultT[AmazonOrderResponse.Root] = + for { + amazonOrder ← * <~ AmazonOrders.mustFindOneOr404(amazonOrderId) + up ← * <~ AmazonOrders.update(amazonOrder, + amazonOrder.copy(orderStatus = payload.orderStatus)) + } yield AmazonOrderResponse.build(up) } diff --git a/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql b/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql index ca1891952f..b7514e2ec2 100644 --- a/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql +++ b/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql @@ -27,6 +27,22 @@ create or replace function update_amazon_orders_view_insert_fn() returns trigger end; $$ language plpgsql; +create or replace function update_amazon_orders_view_update_fn() returns trigger as $$ + begin + update amazon_orders_search_view set + amazon_order_id = new.amazon_order_id, + order_total = new.order_total, + payment_method_detail = new.payment_method_detail, + order_type = new.order_type, + currency = new.currency, + order_status = new.order_status, + purchase_date = to_char(new.purchase_date, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), + created_at = to_char(new.created_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), + updated_at = to_char(new.updated_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') + where id = new.id; + return null; + end; +$$ language plpgsql; -- delete amazon order function drop function if exists update_amazon_orders_view_delete_fn(); @@ -38,5 +54,12 @@ create trigger update_amazon_orders_view_insert_trigger for each row execute procedure update_amazon_orders_view_insert_fn(); +-- recreate update customer group trigger +drop trigger if exists update_amazon_orders_view_update_fn on amazon_orders; +create trigger update_amazon_orders_view_update_trigger + after update on amazon_orders + for each row + execute procedure update_amazon_orders_view_update_fn(); + -- recreate delete amazon order trigger drop trigger if exists update_amazon_orders_view_delete_trigger on amazon_orders; From 8e9efbbeec6e28b6663b71dfd1ae650ae7e278c1 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 14 Apr 2017 16:07:58 +0700 Subject: [PATCH 16/93] Revert greenriver changes --- .../src/main/resources/application.conf | 3 +-- .../src/main/scala/consumer/Workers.scala | 3 +-- .../admin/AmazonOrdersSearchView.scala | 23 ------------------- 3 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala diff --git a/green-river/src/main/resources/application.conf b/green-river/src/main/resources/application.conf index 3bc5baf485..ad6f76c473 100644 --- a/green-river/src/main/resources/application.conf +++ b/green-river/src/main/resources/application.conf @@ -6,8 +6,7 @@ kafka.indices { ] admin = [ - "failed_authorizations_search_view", - "amazon_orders_search_view" + "failed_authorizations_search_view" ] } diff --git a/green-river/src/main/scala/consumer/Workers.scala b/green-river/src/main/scala/consumer/Workers.scala index 403539e7fe..a8e34aea84 100644 --- a/green-river/src/main/scala/consumer/Workers.scala +++ b/green-river/src/main/scala/consumer/Workers.scala @@ -189,7 +189,6 @@ object Workers { "store_credits_search_view" → StoreCreditsSearchView(), "scoped_activity_trails" → ActivityConnectionTransformer(connectionInfo), "taxonomies_search_view" → TaxonomiesSearchView(), - "taxons_search_view" → TaxonsSearchView(), - "amazon_orders_search_view" → AmazonOrdersSearchView() + "taxons_search_view" → TaxonsSearchView() ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala deleted file mode 100644 index 9dd2355514..0000000000 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/AmazonOrdersSearchView.scala +++ /dev/null @@ -1,23 +0,0 @@ -package consumer.elastic.mappings.admin - -import com.sksamuel.elastic4s.ElasticDsl.{mapping ⇒ esMapping, _} -import com.sksamuel.elastic4s.mappings.FieldType._ -import consumer.aliases._ -import consumer.elastic.AvroTransformer -import consumer.elastic.mappings.dateFormat - -final case class AmazonOrdersSearchView()(implicit ec: EC) extends AvroTransformer { - def topic() = "amazon_orders_search_view" - def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("amazonOrderId", StringType).index("not_analyzed"), - field("orderTotal", IntegerType), - field("paymentMethodDetail", StringType).index("not_analyzed"), - field("orderType", StringType).index("not_analyzed"), - field("currency", StringType).index("not_analyzed"), - field("orderStatus", StringType).index("not_analyzed"), - field("purchaseDate", DateType).format(dateFormat), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat) - ) -} From 55c3091eaec6d627268c8838cb5149dfeaac3db4 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 14 Apr 2017 16:09:17 +0700 Subject: [PATCH 17/93] Extend order and add triggers --- .../app/models/cord/AmazonOrder.scala | 16 +++++ .../app/payloads/AmazonOrderPayloads.scala | 4 ++ .../responses/cord/AmazonOrderResponse.scala | 18 ++++- .../R__amazon_orders_search_view_triggers.sql | 65 ------------------ ..._orders_to_orders_search_view_triggers.sql | 67 +++++++++++++++++++ .../sql/V4.117__create_amazon_orders.sql | 16 +---- 6 files changed, 106 insertions(+), 80 deletions(-) delete mode 100644 phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql create mode 100644 phoenix-scala/sql/R__amazon_orders_to_orders_search_view_triggers.sql diff --git a/phoenix-scala/app/models/cord/AmazonOrder.scala b/phoenix-scala/app/models/cord/AmazonOrder.scala index 6bd8ea0c3a..1384a2bf70 100644 --- a/phoenix-scala/app/models/cord/AmazonOrder.scala +++ b/phoenix-scala/app/models/cord/AmazonOrder.scala @@ -9,6 +9,7 @@ import utils.db._ import utils.aliases._ import failures._ import payloads.AmazonOrderPayloads.CreateAmazonOrderPayload +import com.github.tminglei.slickpg.LTree case class AmazonOrder(id: Int = 0, amazonOrderId: String = "", @@ -18,6 +19,9 @@ case class AmazonOrder(id: Int = 0, currency: Currency = Currency.USD, orderStatus: String = "", purchaseDate: Instant, + scope: LTree, + customerName: String, + customerEmail: String, createdAt: Instant = Instant.now, updatedAt: Instant = Instant.now) extends FoxModel[AmazonOrder] @@ -32,6 +36,9 @@ object AmazonOrder { currency = payload.currency, orderStatus = payload.orderStatus, purchaseDate = payload.purchaseDate, + scope = payload.scope, + customerName = payload.customerName, + customerEmail = payload.customerEmail, createdAt = Instant.now, updatedAt = Instant.now) @@ -44,6 +51,9 @@ object AmazonOrder { currency = existingOrder.currency, orderStatus = existingOrder.orderStatus, purchaseDate = existingOrder.purchaseDate, + scope = existingOrder.scope, + customerName = existingOrder.customerName, + customerEmail = existingOrder.customerEmail, createdAt = existingOrder.createdAt, updatedAt = existingOrder.updatedAt) } @@ -72,6 +82,9 @@ class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") def currency = column[Currency]("currency") def orderStatus = column[String]("order_status") def purchaseDate = column[Instant]("purchase_date") + def scope = column[LTree]("scope") + def customerName = column[String]("customer_name") + def customerEmail = column[String]("customer_email") def createdAt = column[Instant]("created_at") def updatedAt = column[Instant]("updated_at") @@ -84,6 +97,9 @@ class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") currency, orderStatus, purchaseDate, + scope, + customerName, + customerEmail, createdAt, updatedAt) <> ((AmazonOrder.apply _).tupled, AmazonOrder.unapply) } diff --git a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala index 34a87df261..d007afe48c 100644 --- a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala +++ b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala @@ -2,6 +2,7 @@ package payloads import utils.Money.Currency import java.time.Instant +import com.github.tminglei.slickpg.LTree object AmazonOrderPayloads { case class CreateAmazonOrderPayload(amazonOrderId: String = "", @@ -10,6 +11,9 @@ object AmazonOrderPayloads { orderType: String = "", currency: Currency = Currency.USD, orderStatus: String = "", + scope: LTree, + customerName: String = "", + customerEmail: String = "", purchaseDate: Instant) case class UpdateAmazonOrderPayload(orderStatus: String) diff --git a/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala index cbebf6afdc..934d6a7874 100644 --- a/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala +++ b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala @@ -4,6 +4,7 @@ import java.time.Instant import models.cord.AmazonOrder import utils.Money.Currency import responses._ +import com.github.tminglei.slickpg.LTree case class AmazonOrderResponse(id: Int, amazonOrderId: String = "", @@ -13,6 +14,9 @@ case class AmazonOrderResponse(id: Int, currency: Currency = Currency.USD, orderStatus: String = "", purchaseDate: Instant, + scope: LTree, + customerName: String = "", + customerEmail: String = "", createdAt: Instant = Instant.now, updatedAt: Instant = Instant.now) extends ResponseItem @@ -26,7 +30,12 @@ object AmazonOrderResponse { orderType: String, currency: Currency, orderStatus: String, - purchaseDate: Instant) + purchaseDate: Instant, + scope: LTree, + customerName: String = "", + customerEmail: String = "", + createdAt: Instant, + updatedAt: Instant) def build(amazonOrder: AmazonOrder): Root = Root(id = amazonOrder.id, @@ -36,5 +45,10 @@ object AmazonOrderResponse { orderType = amazonOrder.orderType, currency = amazonOrder.currency, orderStatus = amazonOrder.orderStatus, - purchaseDate = amazonOrder.purchaseDate) + purchaseDate = amazonOrder.purchaseDate, + scope = amazonOrder.scope, + customerName = amazonOrder.customerName, + customerEmail = amazonOrder.customerEmail, + createdAt = amazonOrder.createdAt, + updatedAt = amazonOrder.updatedAt) } diff --git a/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql b/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql deleted file mode 100644 index b7514e2ec2..0000000000 --- a/phoenix-scala/sql/R__amazon_orders_search_view_triggers.sql +++ /dev/null @@ -1,65 +0,0 @@ --- insert amazon order function -create or replace function update_amazon_orders_view_insert_fn() returns trigger as $$ - begin - insert into amazon_orders_search_view ( - id, - amazon_order_id, - order_total, - payment_method_detail, - order_type, - currency, - order_status, - purchase_date, - updated_at, - created_at - ) select distinct on (new.id) - new.id as id, - new.amazon_order_id as amazon_order_id, - new.order_total as order_total, - new.payment_method_detail as payment_method_detail, - new.order_type as order_type, - new.currency as currency, - new.order_status as order_status, - to_char(new.purchase_date, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as purchase_date, - to_char(new.created_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as created_at, - to_char(new.updated_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as updated_at; - return null; - end; -$$ language plpgsql; - -create or replace function update_amazon_orders_view_update_fn() returns trigger as $$ - begin - update amazon_orders_search_view set - amazon_order_id = new.amazon_order_id, - order_total = new.order_total, - payment_method_detail = new.payment_method_detail, - order_type = new.order_type, - currency = new.currency, - order_status = new.order_status, - purchase_date = to_char(new.purchase_date, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), - created_at = to_char(new.created_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), - updated_at = to_char(new.updated_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') - where id = new.id; - return null; - end; -$$ language plpgsql; - --- delete amazon order function -drop function if exists update_amazon_orders_view_delete_fn(); - --- recreate insert amazon order trigger -drop trigger if exists update_amazon_orders_view_insert_trigger on amazon_orders; -create trigger update_amazon_orders_view_insert_trigger - after insert on amazon_orders - for each row - execute procedure update_amazon_orders_view_insert_fn(); - --- recreate update customer group trigger -drop trigger if exists update_amazon_orders_view_update_fn on amazon_orders; -create trigger update_amazon_orders_view_update_trigger - after update on amazon_orders - for each row - execute procedure update_amazon_orders_view_update_fn(); - --- recreate delete amazon order trigger -drop trigger if exists update_amazon_orders_view_delete_trigger on amazon_orders; diff --git a/phoenix-scala/sql/R__amazon_orders_to_orders_search_view_triggers.sql b/phoenix-scala/sql/R__amazon_orders_to_orders_search_view_triggers.sql new file mode 100644 index 0000000000..38c955bdff --- /dev/null +++ b/phoenix-scala/sql/R__amazon_orders_to_orders_search_view_triggers.sql @@ -0,0 +1,67 @@ +create or replace function update_orders_search_view_from_amazon_orders_insert_fn() returns trigger as $$ + begin + insert into orders_search_view ( + id, + scope, + reference_number, + state, + placed_at, + currency, + sub_total, + shipping_total, + adjustments_total, + taxes_total, + grand_total, + customer) + select distinct on (new.id) + -- order + ((select max(id) from orders_search_view group by id order by id DESC limit 1) + 1) as id, + new.scope as scope, + new.amazon_order_id as reference_number, + new.order_status as state, + to_char(new.purchase_date, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as placed_at, + new.currency as currency, + -- totals + 0 as sub_total, + 0 as shipping_total, + 0 as adjustments_total, + 0 as taxes_total, + new.order_total as grand_total, + -- customer + json_build_object( + 'id', 0, + 'name', ao.customer_name, + 'email', ao.customer_email, + 'is_blacklisted', false, + 'joined_at', null, + 'rank', null, + 'revenue', null + )::jsonb as customer + from amazon_orders as ao + where (new.amazon_order_id = ao.amazon_order_id); + return null; + end; +$$ language plpgsql; + +-- update customer group function +create or replace function update_orders_search_view_from_amazon_orders_update_fn() returns trigger as $$ + begin + update orders_search_view set + state = new.order_status + where reference_number = new.amazon_order_id; + return null; + end; +$$ language plpgsql; + +drop trigger if exists update_orders_search_view_from_amazon_orders_insert_trigger on amazon_orders; +create trigger update_orders_search_view_from_amazon_orders_insert_trigger + after insert on amazon_orders + for each row + execute procedure update_orders_search_view_from_amazon_orders_insert_fn(); + +drop trigger if exists update_orders_search_view_from_amazon_orders_update_trigger on amazon_orders; +create trigger update_orders_search_view_from_amazon_orders_update_trigger + after update on amazon_orders + for each row + execute procedure update_orders_search_view_from_amazon_orders_update_fn(); + diff --git a/phoenix-scala/sql/V4.117__create_amazon_orders.sql b/phoenix-scala/sql/V4.117__create_amazon_orders.sql index 5b5d2da1ae..7b2eb9bf85 100644 --- a/phoenix-scala/sql/V4.117__create_amazon_orders.sql +++ b/phoenix-scala/sql/V4.117__create_amazon_orders.sql @@ -7,19 +7,9 @@ create table amazon_orders( currency currency, order_status generic_string, purchase_date generic_timestamp, + scope ltree, + customer_name generic_string, + customer_email generic_string, updated_at generic_timestamp, created_at generic_timestamp ); - -create table amazon_orders_search_view ( - id bigint primary key, - amazon_order_id generic_string, - order_total integer not null default 0, - payment_method_detail generic_string, - order_type generic_string, - currency currency, - order_status generic_string, - purchase_date json_timestamp, - updated_at json_timestamp, - created_at json_timestamp -); From 6d63447448294bab2f658523c406734171d24598 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Mon, 17 Apr 2017 15:00:52 +0700 Subject: [PATCH 18/93] Make seeds run in test env --- phoenix-scala/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phoenix-scala/build.sbt b/phoenix-scala/build.sbt index aa04f77eaf..5215c8ab7c 100644 --- a/phoenix-scala/build.sbt +++ b/phoenix-scala/build.sbt @@ -88,7 +88,7 @@ lazy val seeder = (project in file("seeder")) reformatOnCompileSettings, // scalafmt, Revolver.settings, // we cannot fork and set javaOptions simply, as it causes some weird issue with db schema creation - initialize ~= (_ => System.setProperty("phoenix.env", "development" )), + initialize ~= (_ => System.setProperty("phoenix.env", "test" )), assemblyMergeStrategy in assembly := { case PathList("org", "joda", "time", xs @ _ *) ⇒ MergeStrategy.first From 53e00d90bafbc5e79ba87315bf3642542ee32bad Mon Sep 17 00:00:00 2001 From: Diokuz Date: Fri, 14 Apr 2017 09:31:11 +0300 Subject: [PATCH 19/93] add flow to order --- ashes/src/components/common/state.jsx | 2 +- .../customer-card/customer-card.jsx | 52 ++++++++----------- .../src/components/customers/title-block.css | 19 ++++--- .../discounts-panel/discounts-panel.jsx | 7 ++- .../gift-cards/choose-customers.jsx | 5 ++ .../components/gift-cards/customer-row.jsx | 7 +-- ashes/src/components/link/index-link.jsx | 1 + ashes/src/components/orders/details.jsx | 8 ++- ashes/src/components/orders/order-coupons.jsx | 19 ++----- ashes/src/interfaces/paragons/customer.js | 9 +++- ashes/src/modules/orders/details.js | 16 +++++- ashes/src/paragons/order.js | 9 ++-- 12 files changed, 83 insertions(+), 71 deletions(-) diff --git a/ashes/src/components/common/state.jsx b/ashes/src/components/common/state.jsx index 4bd65af163..7c2d399bf1 100644 --- a/ashes/src/components/common/state.jsx +++ b/ashes/src/components/common/state.jsx @@ -58,7 +58,7 @@ export const states = { const State = (props): Element<*> => { return ( - {get(states, [props.model, props.value], '[Invalid]')} + {get(states, [props.model, props.value], props.value)} ); }; diff --git a/ashes/src/components/customer-card/customer-card.jsx b/ashes/src/components/customer-card/customer-card.jsx index 65b000a75c..7dd259ac17 100644 --- a/ashes/src/components/customer-card/customer-card.jsx +++ b/ashes/src/components/customer-card/customer-card.jsx @@ -8,26 +8,12 @@ import TextFit from 'components/text-fit/text-fit'; import styles from 'components/customers/title-block.css'; type Props = { - customer: { - id: number, - name: string, - email: string, - isGuest: boolean, - groups: Array, - avatarUrl?: string, - rank: number, - phoneNumber: string, - location: string, - }, + customer: Customer, }; export default class CustomerInfo extends Component { props: Props; - ensureNotEmpty(val: number|string) { - return val ? {val} :  ; - } - customerLink(text: string) { const params = { customerId: this.props.customer.id }; @@ -48,7 +34,7 @@ export default class CustomerInfo extends Component {
); } else { - return
None
; + return
None
; } } @@ -61,7 +47,7 @@ export default class CustomerInfo extends Component { if (customer.avatarUrl) { avatar = ; } else { - avatar = ; + avatar = ; } return ( @@ -88,20 +74,26 @@ export default class CustomerInfo extends Component {
    -
  • - -
    {this.ensureNotEmpty(customer.id)}
    -
  • -
  • - -
    {this.ensureNotEmpty(customer.phoneNumber)}
    -
  • -
  • - -
    {this.ensureNotEmpty(customer.location)}
    -
  • + {customer.id && +
  • + +
    {customer.id}
    +
  • + } + {customer.phoneNumber && +
  • + +
    {customer.phoneNumber}
    +
  • + } + {customer.location && +
  • + +
    {customer.location}
    +
  • + }
  • - + {this.customerGroups}
diff --git a/ashes/src/components/customers/title-block.css b/ashes/src/components/customers/title-block.css index c54be8f3e4..7469df6710 100644 --- a/ashes/src/components/customers/title-block.css +++ b/ashes/src/components/customers/title-block.css @@ -95,21 +95,22 @@ display: inline-block; width: 50%; + &:only-child { + width: 100%; + } + & > li { height: 40px; display: flex; align-items: center; & > i { - width: 40px; - font-style: normal; font-size: 22px; - line-height: 24px; - text-align: center; color: var(--decor6); } &.fc-customer-info-days > i { + margin-right: 8px; font-size: 15px; font-weight: 700; line-height: 20px; @@ -117,10 +118,15 @@ } } +.value { + margin-left: 8px; + width: 90%; + word-wrap: break-word; +} + .group { padding: 5px 10px; - margin-right: 5px; - margin-bottom: 5px; + margin: 0 5px 5px 8px; display: inline-block; vertical-align: top; font-size: 14px; @@ -134,4 +140,5 @@ .guest { color: var(--decor8); padding-top: 5px; + margin-left: 8px; } diff --git a/ashes/src/components/discounts-panel/discounts-panel.jsx b/ashes/src/components/discounts-panel/discounts-panel.jsx index 90f32391aa..b4de099f0d 100644 --- a/ashes/src/components/discounts-panel/discounts-panel.jsx +++ b/ashes/src/components/discounts-panel/discounts-panel.jsx @@ -1,9 +1,7 @@ - /* @flow */ import React, { Component } from 'react'; import _ from 'lodash'; -import classNames from 'classnames'; import ContentBox from 'components/content-box/content-box'; import PanelHeader from 'components/panel-header/panel-header'; @@ -13,7 +11,7 @@ import TableView from 'components/table/tableview'; import styles from './discounts-panel.css'; type Props = { - promotion: Object, + promotion: ?Object, }; const viewColumns = [ @@ -31,11 +29,13 @@ export default class DiscountsPanel extends Component { get discounts(): Array { const { promotion } = this.props; + return promotion ? [promotion] : []; } get viewContent() { const discounts = this.discounts; + if (_.isEmpty(discounts)) { return
No discounts applied.
; } else { @@ -60,7 +60,6 @@ export default class DiscountsPanel extends Component { } render() { - return ( ; } diff --git a/ashes/src/components/gift-cards/customer-row.jsx b/ashes/src/components/gift-cards/customer-row.jsx index 44f2e66f96..a5d3515153 100644 --- a/ashes/src/components/gift-cards/customer-row.jsx +++ b/ashes/src/components/gift-cards/customer-row.jsx @@ -5,12 +5,7 @@ import React from 'react'; import { Checkbox } from '../checkbox/checkbox'; type Props = { - customer: { - id: number, - email: string, - phoneNumber?: string, - name: string, - }, + customer: Customer, checked?: boolean, onToggle?: (id: number) => void, }; diff --git a/ashes/src/components/link/index-link.jsx b/ashes/src/components/link/index-link.jsx index 43e7b4dd75..6bb43771a0 100644 --- a/ashes/src/components/link/index-link.jsx +++ b/ashes/src/components/link/index-link.jsx @@ -1,4 +1,5 @@ /* @flow */ + import React, { Component, Element } from 'react'; import Link from './link'; diff --git a/ashes/src/components/orders/details.jsx b/ashes/src/components/orders/details.jsx index 50b4635172..b7b83f3ec0 100644 --- a/ashes/src/components/orders/details.jsx +++ b/ashes/src/components/orders/details.jsx @@ -38,10 +38,14 @@ export default class OrderDetails extends Component {
- + {order.channel !== 'Amazon.com' && + + } - + {order.channel !== 'Amazon.com' && + + }
diff --git a/ashes/src/components/orders/order-coupons.jsx b/ashes/src/components/orders/order-coupons.jsx index 5d70f1d9d8..d3a4654d5d 100644 --- a/ashes/src/components/orders/order-coupons.jsx +++ b/ashes/src/components/orders/order-coupons.jsx @@ -1,16 +1,13 @@ /* @flow */ -import React, { Component, Element } from 'react'; -import _ from 'lodash'; +import React, { Component } from 'react'; import ContentBox from 'components/content-box/content-box'; import CouponsPanel from 'components/coupons-panel/coupons-panel'; import PanelHeader from 'components/panel-header/panel-header'; type Props = { - order: { - coupon: Object, - }, + coupon: ?Object, }; const columns = [ @@ -22,17 +19,11 @@ const columns = [ export default class OrderCoupons extends Component { props: Props; - get coupons(): Array { - const coupon = _.get(this.props, 'order.coupon'); - - if (!coupon) return []; - - return [coupon]; - } - render() { const title = ; - const content = ; + const coupons = this.props.coupon ? [this.props.coupon] : []; + const content = ; + return ( , + avatarUrl?: string, + rank?: number, + location?: string, +}; diff --git a/ashes/src/modules/orders/details.js b/ashes/src/modules/orders/details.js index f494d5739b..6cc6e2f416 100644 --- a/ashes/src/modules/orders/details.js +++ b/ashes/src/modules/orders/details.js @@ -40,7 +40,19 @@ export const updateShipments = _updateShipments.perform; export const clearFetchErrors =_getOrder.clearErrors; function orderSucceeded(state: State, payload: Object): State { - const order: OrderParagon = new OrderParagon(payload.result || payload); + const res = payload.result || payload; + const order: OrderParagon = new OrderParagon(res); + + return { ...state, order }; +} + +function amazonOrderSucceeded(state: State, payload: Object): State { + const res = payload.result || payload; + + res.paymentMethods = [res.paymentMethods]; + res.customer.id = res.customer.email; + + const order: OrderParagon = new OrderParagon(res); return { ...state, order }; } @@ -53,7 +65,7 @@ export function increaseRemorsePeriod(refNum: string) { const reducer = createReducer({ [_getOrder.succeeded]: orderSucceeded, - [_getAmazonOrder.succeeded]: orderSucceeded, + [_getAmazonOrder.succeeded]: amazonOrderSucceeded, [_updateOrder.succeeded]: orderSucceeded, [_updateShipments.succeeded]: (state) => state, }, initialState); diff --git a/ashes/src/paragons/order.js b/ashes/src/paragons/order.js index dd30c046b2..52012d0948 100644 --- a/ashes/src/paragons/order.js +++ b/ashes/src/paragons/order.js @@ -75,7 +75,6 @@ export const stateTitles = { }; // this map taken from scala code - export const allowedStateTransitions = { [states.cart]: [states.fraudHold, states.remorseHold, states.canceled, states.fulfillmentStarted], [states.fraudHold]: [states.manualHold, states.remorseHold, states.fulfillmentStarted, states.canceled], @@ -95,6 +94,7 @@ export default class OrderParagon { constructor(order: Order) { Object.assign(this, order); const skus = _.get(order, 'lineItems.skus'); + if (skus) { this.lineItems.skus = collectLineItems(skus); } @@ -103,15 +103,16 @@ export default class OrderParagon { lineItems: Object; orderState: string; referenceNumber: string; - customer: Object; - promotion: Object; - coupon: Object; + customer: Customer; paymentMethods: Array; orderState: string; remorsePeriodEnd: string; shippingState: string; paymentState: string; placedAt: string; + promotion: ?Object; + coupon: ?Object; + channel: ?string; get entityId(): string { return this.referenceNumber; From 494f379bf0ca026ebda517c772c34090af1ba7ee Mon Sep 17 00:00:00 2001 From: Diokuz Date: Mon, 17 Apr 2017 16:04:46 +0300 Subject: [PATCH 20/93] add amazon order subroute --- ashes/src/components/orders/order.jsx | 31 ++++++++++++++----- ashes/src/components/orders/orderTypes.js | 1 + ashes/src/components/orders/sub-nav.jsx | 15 ++++++--- .../src/components/payment/payment-method.jsx | 2 +- .../payments-panel/payments-panel.jsx | 4 +-- .../taxonomies/taxons/new-taxon-modal.jsx | 4 +-- .../elastic/request/aggregations/wrappings.js | 2 +- ashes/src/modules/orders/details.js | 1 - ashes/src/routes/orders.js | 3 ++ ashes/test/unit/lib/language-utils.js | 2 +- .../unit/modules/customers/credit-cards.js | 2 +- 11 files changed, 46 insertions(+), 21 deletions(-) diff --git a/ashes/src/components/orders/order.jsx b/ashes/src/components/orders/order.jsx index 62b4a8a544..0f1889be61 100644 --- a/ashes/src/components/orders/order.jsx +++ b/ashes/src/components/orders/order.jsx @@ -60,13 +60,14 @@ export default class Order extends React.Component { componentDidMount() { this.props.clearFetchErrors(); - this.props.fetchAmazonOrder(this.orderRefNum); + this.fetchOrder(); } componentWillReceiveProps(nextProps: Props): void { if (this.orderRefNum != orderRefNum(nextProps)) { - this.props.fetchOrder(orderRefNum(nextProps)); + this.fetchOrder(orderRefNum(nextProps)); } + if (_.get(nextProps, 'details.order.state') !== 'remorseHold') { if (this.updateInterval != null) { clearInterval(this.updateInterval); @@ -82,6 +83,16 @@ export default class Order extends React.Component { } } + fetchOrder(customOrderNum?: number): void { + const orderNum = customOrderNum || this.orderRefNum; + + if (this.props.route.amazon) { + this.props.fetchAmazonOrder(orderNum); + } else { + this.props.fetchOrder(orderNum); + } + } + get changeOptions(): Object { return { header: 'Confirm', @@ -138,13 +149,13 @@ export default class Order extends React.Component { } get subNav(): Element<*> { - return ; + return ; } @autobind onRemorseCountdownFinish() { if (this.updateInterval == null) { - this.updateInterval = setInterval(() => this.props.fetchOrder(this.orderRefNum), 5000); + this.updateInterval = setInterval(() => this.fetchOrder(), 5000); } } @@ -180,9 +191,11 @@ export default class Order extends React.Component { const order = this.order; const claims = getClaims(); - if (order.orderState === 'canceled' || - order.orderState === 'shipped') { - return ; + if (order.orderState.toLowerCase() === 'canceled' || + order.orderState.toLowerCase() === 'shipped') { + const status = order.shippingState === '---' ? order.orderState : order.shippingState; + + return ; } let holdStates = ['manualHold']; @@ -200,12 +213,14 @@ export default class Order extends React.Component { allowedStateTransitions[order.orderState].indexOf(state) != -1; }); + const items = _.map(visibleAndSortedOrderStates, state => [state, states.order[state]]); + return ( [state, states.order[state]])} + items={items} placeholder={'Order state'} value={order.orderState} onChange={this.onStateChange} diff --git a/ashes/src/components/orders/orderTypes.js b/ashes/src/components/orders/orderTypes.js index 95af28e7b6..172817df1a 100644 --- a/ashes/src/components/orders/orderTypes.js +++ b/ashes/src/components/orders/orderTypes.js @@ -21,6 +21,7 @@ export type DispatchToProps = { export type OwnProps = { children: any; // @todo params: Object; + route: Object; }; export type Props = OwnProps & StateToProps & DispatchToProps; diff --git a/ashes/src/components/orders/sub-nav.jsx b/ashes/src/components/orders/sub-nav.jsx index 3ab7eaeb94..c22e810fe0 100644 --- a/ashes/src/components/orders/sub-nav.jsx +++ b/ashes/src/components/orders/sub-nav.jsx @@ -13,13 +13,20 @@ const notesClaims = readAction(frn.note.order); const shippingClaims = readAction(frn.mdl.shipment); const activityClaims = readAction(frn.activity.order); -const SubNav = props => { - const { order } = props; - const params = {order: order.referenceNumber}; +const SubNav = ({ order, isAmazon, className = '' }) => { + const params = { order: order.referenceNumber }; const claims = getClaims(); + if (isAmazon) { + return ( + + Details + + ); + } + return ( - + Details Shipments Notes diff --git a/ashes/src/components/payment/payment-method.jsx b/ashes/src/components/payment/payment-method.jsx index 9704f2d247..cfe02f840a 100644 --- a/ashes/src/components/payment/payment-method.jsx +++ b/ashes/src/components/payment/payment-method.jsx @@ -16,7 +16,7 @@ type Props = { paymentMethod: TPaymentMethod; type?: string; className?: string; -} +}; function getIconType(type, paymentMethod) { switch (type) { diff --git a/ashes/src/components/payments-panel/payments-panel.jsx b/ashes/src/components/payments-panel/payments-panel.jsx index 09564a3147..fc3077c447 100644 --- a/ashes/src/components/payments-panel/payments-panel.jsx +++ b/ashes/src/components/payments-panel/payments-panel.jsx @@ -78,13 +78,13 @@ export default class PaymentsPanel extends Component { @autobind renderRow(row: PaymentMethod) { const { order } = this.props; - const customerId = order.customer.id; const referenceNumber = order.referenceNumber; + const key = row.id != null ? row.id : row.code; return ( { frn: frn.activity.order, }), ]), + router.read('amazon-order', { path: 'amazon/:order', component: Order, amazon: true }, [ + router.read('amazon-order-details', { component: OrderDetails, isIndex: true }), + ]), ]); return ( diff --git a/ashes/test/unit/lib/language-utils.js b/ashes/test/unit/lib/language-utils.js index f7ba26fdb3..8577e2e4bb 100644 --- a/ashes/test/unit/lib/language-utils.js +++ b/ashes/test/unit/lib/language-utils.js @@ -1,4 +1,4 @@ -const { default: formatCurrency, stringToCurrency } = requireSource('lib/language-utils', [ +const { stringToCurrency } = requireSource('lib/language-utils', [ 'codeToName' ]); diff --git a/ashes/test/unit/modules/customers/credit-cards.js b/ashes/test/unit/modules/customers/credit-cards.js index 176d5b02a6..fae2ec2521 100644 --- a/ashes/test/unit/modules/customers/credit-cards.js +++ b/ashes/test/unit/modules/customers/credit-cards.js @@ -2,7 +2,7 @@ import nock from 'nock'; import sinon from 'sinon'; import stripe from 'lib/stripe'; -const { default: reducer, ...actions } = importSource('modules/customers/credit-cards.js', [ +const actions = importSource('modules/customers/credit-cards.js', [ 'fetchCreditCards', 'requestCustomerCreditCards', 'receiveCustomerCreditCards', From 1428b1aee19335b003899e826f7001fa873e3297 Mon Sep 17 00:00:00 2001 From: Diokuz Date: Mon, 17 Apr 2017 16:06:35 +0300 Subject: [PATCH 21/93] fix some unused vars --- ashes/src/components/orders/shipments/unshipped-items.jsx | 1 - ashes/src/components/products/options/option-list.jsx | 2 +- ashes/src/components/products/options/value-edit-dialog.jsx | 2 +- ashes/src/components/promotions/discounts/counter.jsx | 2 +- ashes/src/components/promotions/discounts/currency.jsx | 2 +- ashes/src/components/promotions/widgets/select-products.jsx | 4 ++-- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ashes/src/components/orders/shipments/unshipped-items.jsx b/ashes/src/components/orders/shipments/unshipped-items.jsx index 42e16eb8f2..3f8cb22ba3 100644 --- a/ashes/src/components/orders/shipments/unshipped-items.jsx +++ b/ashes/src/components/orders/shipments/unshipped-items.jsx @@ -1,7 +1,6 @@ /* @flow */ // libs -import _ from 'lodash'; import React, { Component, Element } from 'react'; import { autobind } from 'core-decorators'; diff --git a/ashes/src/components/products/options/option-list.jsx b/ashes/src/components/products/options/option-list.jsx index 9360aede8c..caae196ae0 100644 --- a/ashes/src/components/products/options/option-list.jsx +++ b/ashes/src/components/products/options/option-list.jsx @@ -5,7 +5,7 @@ import React, { Component, Element } from 'react'; import { autobind } from 'core-decorators'; import _ from 'lodash'; -import { assoc, dissoc } from 'sprout-data'; +import { assoc } from 'sprout-data'; import { autoAssignVariants } from 'paragons/variants'; import { skuId } from 'paragons/product'; diff --git a/ashes/src/components/products/options/value-edit-dialog.jsx b/ashes/src/components/products/options/value-edit-dialog.jsx index 31aa88a281..b32f27334b 100644 --- a/ashes/src/components/products/options/value-edit-dialog.jsx +++ b/ashes/src/components/products/options/value-edit-dialog.jsx @@ -103,7 +103,7 @@ class ValueEditDialog extends Component { } } - render() { + render(): Element<*> { return ( { +const CounterWidget = (props: Props): Element<*> => { const value = toNumber(props.value); const setValue = value => { props.onChange(value); diff --git a/ashes/src/components/promotions/discounts/currency.jsx b/ashes/src/components/promotions/discounts/currency.jsx index 03ab646627..7a42e9ddc1 100644 --- a/ashes/src/components/promotions/discounts/currency.jsx +++ b/ashes/src/components/promotions/discounts/currency.jsx @@ -10,7 +10,7 @@ type Props = { onChange: Function }; -const Currency = (props: Props) => { +const Currency = (props: Props): Element<*> => { return ( Date: Tue, 18 Apr 2017 09:38:01 +0300 Subject: [PATCH 22/93] cr fixes --- ashes/src/components/orders/details.jsx | 4 +++- ashes/src/modules/orders/details.js | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ashes/src/components/orders/details.jsx b/ashes/src/components/orders/details.jsx index b7b83f3ec0..7a1eb5b423 100644 --- a/ashes/src/components/orders/details.jsx +++ b/ashes/src/components/orders/details.jsx @@ -51,7 +51,9 @@ export default class OrderDetails extends Component {
- + {order.channel !== 'Amazon.com' && + + }
diff --git a/ashes/src/modules/orders/details.js b/ashes/src/modules/orders/details.js index 76e03913e3..4f2624dc86 100644 --- a/ashes/src/modules/orders/details.js +++ b/ashes/src/modules/orders/details.js @@ -20,7 +20,7 @@ const _getOrder = createAsyncActions( const _getAmazonOrder = createAsyncActions( 'getAmazonOrder', - (refNum: string) => Api.get(`/hyperion/orders/111-5296499-9653858/full`) // ${refNum} + (refNum: string) => Api.get(`/hyperion/orders/${refNum}/full`) ); const _updateOrder = createAsyncActions( @@ -40,14 +40,13 @@ export const updateShipments = _updateShipments.perform; export const clearFetchErrors =_getOrder.clearErrors; function orderSucceeded(state: State, payload: Object): State { - const res = payload.result || payload; - const order: OrderParagon = new OrderParagon(res); + const order: OrderParagon = new OrderParagon(payload.result); return { ...state, order }; } function amazonOrderSucceeded(state: State, payload: Object): State { - const res = payload.result || payload; + const res = payload.result; res.customer.id = res.customer.email; From 04e77173b678d05a675ab78f1a2c74651206c4f5 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 18 Apr 2017 15:29:25 +0700 Subject: [PATCH 23/93] Store amazon orders and customers to phoenix --- hyperion/lib/hyperion/amazon/credentials.ex | 1 - hyperion/lib/hyperion/api.ex | 3 +- hyperion/lib/hyperion/jwt_auth.ex | 10 +++++ hyperion/lib/hyperion/phoenix_scala/client.ex | 41 ++++++++++++++++--- .../workers/amazon/customers_orders_worker.ex | 11 +++-- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/hyperion/lib/hyperion/amazon/credentials.ex b/hyperion/lib/hyperion/amazon/credentials.ex index 574df40827..82955f74bc 100644 --- a/hyperion/lib/hyperion/amazon/credentials.ex +++ b/hyperion/lib/hyperion/amazon/credentials.ex @@ -2,7 +2,6 @@ defmodule Hyperion.Amazon.Credentials do alias Hyperion.PhoenixScala.Client, warn: true def mws_config(token) do - Client.get_credentials(token) |> build_cfg end diff --git a/hyperion/lib/hyperion/api.ex b/hyperion/lib/hyperion/api.ex index a062e2c37f..536a012b6f 100644 --- a/hyperion/lib/hyperion/api.ex +++ b/hyperion/lib/hyperion/api.ex @@ -25,8 +25,7 @@ defmodule Hyperion.API do def customer_id(conn) do token = jwt(conn) try do - {:ok, data} = Hyperion.JwtAuth.verify(token) - data[:scope] + Hyperion.JwtAuth.get_scope(token) rescue RuntimeError -> raise NotAllowed end diff --git a/hyperion/lib/hyperion/jwt_auth.ex b/hyperion/lib/hyperion/jwt_auth.ex index a83d315a98..12da81c656 100644 --- a/hyperion/lib/hyperion/jwt_auth.ex +++ b/hyperion/lib/hyperion/jwt_auth.ex @@ -9,6 +9,16 @@ defmodule Hyperion.JwtAuth do JsonWebToken.verify(payload, opts) end + @doc """ + Verifies token and returning scope + """ + def get_scope(token) do + case verify(token) do + {:ok, data} -> data["scope"] + _ -> raise RuntimeError + end + end + defp key do RsaUtil.public_key(Application.fetch_env!(:hyperion, :public_key), "") end diff --git a/hyperion/lib/hyperion/phoenix_scala/client.ex b/hyperion/lib/hyperion/phoenix_scala/client.ex index 26c85c446e..844f3ad92f 100644 --- a/hyperion/lib/hyperion/phoenix_scala/client.ex +++ b/hyperion/lib/hyperion/phoenix_scala/client.ex @@ -1,5 +1,6 @@ defmodule Hyperion.PhoenixScala.Client do use HTTPoison.Base + require Logger @moduledoc """ Provides simple access to Phoenix-scala API @@ -80,16 +81,44 @@ defmodule Hyperion.PhoenixScala.Client do @doc """ Creates new customer in Phoenix from Amazon order """ - def create_customer(%{name: name, email: email}) do - params = Poison.encode!(%{name: name, email: email}) - token = login() - {st, resp} = post("/api/v1/customers", params, make_request_headers(token)) + def create_customer(payload, token) do + params = Poison.encode!(%{name: payload["BuyerName"], email: payload["BuyerName"]}) + {_, resp} = post("/api/v1/customers", params, make_request_headers(token)) + case resp.status_code do + # status_code = 400 means customer already exists + code when code in [200, 400] -> payload + _ -> + Logger.error("Customer creation error: #{inspect(resp)}") + raise %PhoenixError{message: inspect(resp)} + end + end + + def create_order(payload, token) do + params = Poison.encode!(%{amazonOrderId: payload["amazonOrderId"], + orderTotal: String.to_float(payload["OrderTotal"]["Amount"]) * 100, + paymentMethodDetail: payload["PaymentMethodDetails"]["PaymentMethodDetail"], + orderType: payload["OrderType"], + currency: payload["OrderTotal"]["Currency"], + orderStatus: payload["OrderStatus"], + purchaseDate: "2017-03-08T19:38:36Z", + scope: Hyperion.JwtAuth.get_scope(token), + customerName: payload["BuyerName"], + customerEmail: payload["BuyerEmail"]}) + {st, resp} = post("/api/v1/amazon_orders", params, make_request_headers(token)) case resp.status_code do - code when code == 200 -> parse_response({st, resp}, token) - _ -> %{status: resp.status_code, error: resp.body["errors"]} + code when code in [200, 201] -> parse_response({st, resp}, token) + _ -> + Logger.error("Order creation error: #{inspect(resp)}") + raise %PhoenixError{message: inspect(resp)} end end + def create_order_and_customer(payload) do + token = login() + create_customer(payload, token) + |> create_order(token) + end + @doc """ Returns MWS credentials stored in Phoenix plugins """ diff --git a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex index d67ace4ba3..301a546bf5 100644 --- a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex +++ b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex @@ -23,7 +23,7 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do defp do_work() do try do fetch_amazon_orders() - |> store_customers() + |> store_customers_and_orders() rescue e in RuntimeError -> Logger.error "Error while fetching orders from Amazon: #{e.message}" end @@ -42,13 +42,12 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do end end - defp store_customers(orders) do + defp store_customers_and_orders(orders) do case orders["Orders"]["Order"] do list when is_list(list) -> Enum.each(list, fn order -> - Client.create_customer(%{name: order["Order"]["BuyerName"], - email: order["Order"]["BuyerEmail"]}) - end) - map when is_map(map) -> Client.create_customer(%{name: map["BuyerName"], email: map["BuyerEmail"]}) + Client.create_order_and_customer(order) + end) + map when is_map(map) -> Client.create_order_and_customer(map) empty when empty in [%{}, []] -> nil end end From d2a45938cbe1b75ddc693cc7d9301b2dd1a70ed2 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 18 Apr 2017 15:32:08 +0700 Subject: [PATCH 24/93] Fix get_scope function --- hyperion/lib/hyperion/jwt_auth.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyperion/lib/hyperion/jwt_auth.ex b/hyperion/lib/hyperion/jwt_auth.ex index 12da81c656..a4459f090e 100644 --- a/hyperion/lib/hyperion/jwt_auth.ex +++ b/hyperion/lib/hyperion/jwt_auth.ex @@ -14,7 +14,7 @@ defmodule Hyperion.JwtAuth do """ def get_scope(token) do case verify(token) do - {:ok, data} -> data["scope"] + {:ok, data} -> data[:scope] _ -> raise RuntimeError end end From e1209cd9888db299b6ab2dc9b189e5061b55c473 Mon Sep 17 00:00:00 2001 From: Diokuz Date: Tue, 18 Apr 2017 13:31:40 +0300 Subject: [PATCH 25/93] add isAmazon for row --- ashes/src/components/orders/order-row.jsx | 23 ++++++++++++++++++----- ashes/src/components/orders/orders.jsx | 7 ++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/ashes/src/components/orders/order-row.jsx b/ashes/src/components/orders/order-row.jsx index bf626b4d5a..073bf98073 100644 --- a/ashes/src/components/orders/order-row.jsx +++ b/ashes/src/components/orders/order-row.jsx @@ -1,7 +1,10 @@ +// @flow + import React, { PropTypes } from 'react'; import _ from 'lodash'; import MultiSelectRow from '../table/multi-select-row'; +import OrderParagon from 'paragons/order'; const compileShippingStatus = order => { if (order.state == 'canceled') { @@ -77,19 +80,29 @@ const setCellContents = (order, field) => { } }; +type Props = { + order: OrderParagon; + columns: Array<*>; + params: Object; +}; + +const OrderRow = (props: Props) => { + const { order, columns, params, hasAmazon = false } = props; -const OrderRow = (props, context) => { - const { order, columns, params } = props; - const key = `order-${order.referenceNumber}`; + // @todo verify isAmazon more strictly and convenient + const email = _.get(order, 'customer.email', ''); + const isAmazon = email.endsWith('@marketplace.amazon.com'); + const linkTo = isAmazon ? 'amazon-order' : 'order'; return ( + params={params} + /> ); }; diff --git a/ashes/src/components/orders/orders.jsx b/ashes/src/components/orders/orders.jsx index db16332ccb..58b06d7b4c 100644 --- a/ashes/src/components/orders/orders.jsx +++ b/ashes/src/components/orders/orders.jsx @@ -19,7 +19,7 @@ import { ChangeStateModal, CancelModal } from '../bulk-actions/modal'; import { Link } from '../link'; -const mapStateToProps = ({orders: {list}}) => { +const mapStateToProps = ({ orders: { list } }) => { return { list, }; @@ -99,14 +99,15 @@ export default class Orders extends React.Component { get renderRow() { return (row, index, columns, params) => { - const key = `order-${row.referenceNumber}`; + const key = `order-${row.id}`; return ( + params={params} + /> ); }; } From 0e49eaa36ac5387fadb52eb0dfe5dab1daabf323 Mon Sep 17 00:00:00 2001 From: Diokuz Date: Tue, 18 Apr 2017 13:44:32 +0300 Subject: [PATCH 26/93] back watchers endpoint --- ashes/src/components/orders/details.jsx | 4 +--- ashes/src/components/orders/order-row.jsx | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ashes/src/components/orders/details.jsx b/ashes/src/components/orders/details.jsx index 7a1eb5b423..b7b83f3ec0 100644 --- a/ashes/src/components/orders/details.jsx +++ b/ashes/src/components/orders/details.jsx @@ -51,9 +51,7 @@ export default class OrderDetails extends Component {
- {order.channel !== 'Amazon.com' && - - } +
diff --git a/ashes/src/components/orders/order-row.jsx b/ashes/src/components/orders/order-row.jsx index 073bf98073..32f133cf0a 100644 --- a/ashes/src/components/orders/order-row.jsx +++ b/ashes/src/components/orders/order-row.jsx @@ -87,7 +87,7 @@ type Props = { }; const OrderRow = (props: Props) => { - const { order, columns, params, hasAmazon = false } = props; + const { order, columns, params } = props; // @todo verify isAmazon more strictly and convenient const email = _.get(order, 'customer.email', ''); From 27d3f93cc1e921cef6fc396baccda6b6ed4b44f1 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 18 Apr 2017 17:47:33 +0700 Subject: [PATCH 27/93] Fix typo and trigger --- hyperion/lib/hyperion/phoenix_scala/client.ex | 4 ++-- .../hyperion/workers/amazon/customers_orders_worker.ex | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hyperion/lib/hyperion/phoenix_scala/client.ex b/hyperion/lib/hyperion/phoenix_scala/client.ex index 844f3ad92f..3856c1a428 100644 --- a/hyperion/lib/hyperion/phoenix_scala/client.ex +++ b/hyperion/lib/hyperion/phoenix_scala/client.ex @@ -94,13 +94,13 @@ defmodule Hyperion.PhoenixScala.Client do end def create_order(payload, token) do - params = Poison.encode!(%{amazonOrderId: payload["amazonOrderId"], + params = Poison.encode!(%{amazonOrderId: payload["AmazonOrderId"], orderTotal: String.to_float(payload["OrderTotal"]["Amount"]) * 100, paymentMethodDetail: payload["PaymentMethodDetails"]["PaymentMethodDetail"], orderType: payload["OrderType"], currency: payload["OrderTotal"]["Currency"], orderStatus: payload["OrderStatus"], - purchaseDate: "2017-03-08T19:38:36Z", + purchaseDate: payload["PurchaseDate"], scope: Hyperion.JwtAuth.get_scope(token), customerName: payload["BuyerName"], customerEmail: payload["BuyerEmail"]}) diff --git a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex index 301a546bf5..e647d50612 100644 --- a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex +++ b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex @@ -29,16 +29,19 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do end end - # TODO: Add order saving into phoenix defp fetch_amazon_orders do date = Timex.beginning_of_day(Timex.now) |> Timex.format!("%Y-%m-%dT%TZ", :strftime) list = [fulfillment_channel: ["MFN", "AFN"], created_after: [date]] + Logger.info("Fetching order with params: #{inspect(list)}") + case MWSClient.list_orders(list, Amazon.fetch_config()) do {:error, error} -> raise inspect(error) {:warn, warn} -> raise warn["ErrorResponse"]["Error"]["Message"] - {_, resp} -> resp["ListOrdersResponse"]["ListOrdersResult"]["Orders"] + {_, resp} -> + Logger.info("Orders fetched: #{inspect(resp)}") + resp["ListOrdersResponse"]["ListOrdersResult"] end end @@ -49,6 +52,7 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do end) map when is_map(map) -> Client.create_order_and_customer(map) empty when empty in [%{}, []] -> nil + _ -> Logger.error "Some error occured! #{inspect(orders)}" end end From d55e3b61557e0633e4a734429db470821dbf612c Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Tue, 18 Apr 2017 15:56:06 +0300 Subject: [PATCH 28/93] add amazon order assinments management --- ashes/src/components/orders/order.jsx | 3 +- phoenix-scala/app/models/Assignment.scala | 23 ++++++------ .../responses/cord/AmazonOrderResponse.scala | 1 + .../app/routes/admin/AssignmentsRoutes.scala | 37 +++++++++++++++++++ .../AmazonOrderAssignmentsManager.scala | 25 +++++++++++++ .../AmazonOrderWatchersManager.scala | 25 +++++++++++++ ...ter_assignment_domain_add_amazon_order.sql | 4 ++ 7 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala create mode 100644 phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala create mode 100644 phoenix-scala/sql/V4.118__alter_assignment_domain_add_amazon_order.sql diff --git a/ashes/src/components/orders/order.jsx b/ashes/src/components/orders/order.jsx index 0f1889be61..c66994e317 100644 --- a/ashes/src/components/orders/order.jsx +++ b/ashes/src/components/orders/order.jsx @@ -137,7 +137,8 @@ export default class Order extends React.Component { } get renderDetails(): Element<*> { - const details = React.cloneElement(this.props.children, { ...this.props, entity: this.order }); + const entityType = !this.props.route.amazon ? 'orders' : 'amazon-orders'; + const details = React.cloneElement(this.props.children, { ...this.props, entity: this.order, entityType }); return (
diff --git a/phoenix-scala/app/models/Assignment.scala b/phoenix-scala/app/models/Assignment.scala index c017b289d6..92a843dbb9 100644 --- a/phoenix-scala/app/models/Assignment.scala +++ b/phoenix-scala/app/models/Assignment.scala @@ -33,17 +33,18 @@ object Assignment { AssignmentType.slickColumn sealed trait ReferenceType - case object Cart extends ReferenceType - case object Order extends ReferenceType - case object GiftCard extends ReferenceType - case object Customer extends ReferenceType - case object Return extends ReferenceType - case object Sku extends ReferenceType - case object Product extends ReferenceType - case object Promotion extends ReferenceType - case object Coupon extends ReferenceType - case object Taxonomy extends ReferenceType - case object Taxon extends ReferenceType + case object Cart extends ReferenceType + case object AmazonOrder extends ReferenceType + case object Order extends ReferenceType + case object GiftCard extends ReferenceType + case object Customer extends ReferenceType + case object Return extends ReferenceType + case object Sku extends ReferenceType + case object Product extends ReferenceType + case object Promotion extends ReferenceType + case object Coupon extends ReferenceType + case object Taxonomy extends ReferenceType + case object Taxon extends ReferenceType object ReferenceType extends ADT[ReferenceType] { def types = sealerate.values[ReferenceType] diff --git a/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala index 934d6a7874..3238c7f6a6 100644 --- a/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala +++ b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala @@ -36,6 +36,7 @@ object AmazonOrderResponse { customerEmail: String = "", createdAt: Instant, updatedAt: Instant) + extends ResponseItem def build(amazonOrder: AmazonOrder): Root = Root(id = amazonOrder.id, diff --git a/phoenix-scala/app/routes/admin/AssignmentsRoutes.scala b/phoenix-scala/app/routes/admin/AssignmentsRoutes.scala index cbc3120098..b2ede87fcb 100644 --- a/phoenix-scala/app/routes/admin/AssignmentsRoutes.scala +++ b/phoenix-scala/app/routes/admin/AssignmentsRoutes.scala @@ -741,6 +741,43 @@ object AssignmentsRoutes { } } } + } ~ + // Amazon Order Single Assignments + pathPrefix("amazon-orders" / cordRefNumRegex) { refNum ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + AmazonOrderAssignmentsManager.list(refNum) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + AmazonOrderAssignmentsManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + AmazonOrderAssignmentsManager.unassign(refNum, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + AmazonOrderWatchersManager.list(refNum) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + AmazonOrderWatchersManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + AmazonOrderWatchersManager.unassign(refNum, assigneeId, auth.model) + } + } + } } } } diff --git a/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala b/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala new file mode 100644 index 0000000000..3f3ae16e0d --- /dev/null +++ b/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala @@ -0,0 +1,25 @@ +package services.assignments + +import models.cord._ +import models.{Assignment, NotificationSubscription} +import responses.cord.AmazonOrderResponse._ +import slick.driver.PostgresDriver.api._ +import utils.aliases._ +import utils.db._ + +object AmazonOrderAssignmentsManager extends AssignmentsManager[String, AmazonOrder] { + + val assignmentType = Assignment.Assignee + val referenceType = Assignment.AmazonOrder + val notifyDimension = models.activity.Dimension.order + val notifyReason = NotificationSubscription.Assigned + + def buildResponse(model: AmazonOrder): Root = build(model) + + def fetchEntity(refNum: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[AmazonOrder] = + AmazonOrders.mustFindByAmazonOrderId(refNum) + + def fetchSequence( + refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[AmazonOrder]] = + AmazonOrders.filter(_.amazonOrderId.inSetBind(refNums)).result.dbresult +} diff --git a/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala b/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala new file mode 100644 index 0000000000..28d51c330c --- /dev/null +++ b/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala @@ -0,0 +1,25 @@ +package services.assignments + +import models.cord._ +import models.{Assignment, NotificationSubscription} +import responses.cord.AmazonOrderResponse._ +import slick.driver.PostgresDriver.api._ +import utils.aliases._ +import utils.db._ + +object AmazonOrderWatchersManager extends AssignmentsManager[String, AmazonOrder] { + + val assignmentType = Assignment.Watcher + val referenceType = Assignment.AmazonOrder + val notifyDimension = models.activity.Dimension.order + val notifyReason = NotificationSubscription.Watching + + def buildResponse(model: AmazonOrder): Root = build(model) + + def fetchEntity(refNum: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[AmazonOrder] = + AmazonOrders.mustFindByAmazonOrderId(refNum) + + def fetchSequence( + refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[AmazonOrder]] = + AmazonOrders.filter(_.amazonOrderId.inSetBind(refNums)).result.dbresult +} diff --git a/phoenix-scala/sql/V4.118__alter_assignment_domain_add_amazon_order.sql b/phoenix-scala/sql/V4.118__alter_assignment_domain_add_amazon_order.sql new file mode 100644 index 0000000000..f7ac95c706 --- /dev/null +++ b/phoenix-scala/sql/V4.118__alter_assignment_domain_add_amazon_order.sql @@ -0,0 +1,4 @@ +alter domain assignment_ref_type drop constraint assignment_ref_type_check; + +alter domain assignment_ref_type add check (value in ('cart', 'order', 'giftCard', + 'customer', 'return', 'product', 'sku', 'promotion', 'coupon', 'returnsScope', 'taxonomy', 'taxon', 'amazonOrder')); From b8666b121aa1c323923bc67121157d143903e32c Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Tue, 18 Apr 2017 17:54:40 +0300 Subject: [PATCH 29/93] add amazonOrder dimension --- phoenix-scala/app/models/activity/Dimension.scala | 1 + .../services/assignments/AmazonOrderAssignmentsManager.scala | 2 +- .../app/services/assignments/AmazonOrderWatchersManager.scala | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/phoenix-scala/app/models/activity/Dimension.scala b/phoenix-scala/app/models/activity/Dimension.scala index f1b4615ebc..134892f244 100644 --- a/phoenix-scala/app/models/activity/Dimension.scala +++ b/phoenix-scala/app/models/activity/Dimension.scala @@ -34,6 +34,7 @@ object Dimension { val giftCard = "giftCard" val notification = "notification" val order = "order" + val amazonOrder = "amazonOrder" val product = "product" val promotion = "promotion" val rma = "return" diff --git a/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala b/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala index 3f3ae16e0d..d6a0adec14 100644 --- a/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala +++ b/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala @@ -11,7 +11,7 @@ object AmazonOrderAssignmentsManager extends AssignmentsManager[String, AmazonOr val assignmentType = Assignment.Assignee val referenceType = Assignment.AmazonOrder - val notifyDimension = models.activity.Dimension.order + val notifyDimension = models.activity.Dimension.amazonOrder val notifyReason = NotificationSubscription.Assigned def buildResponse(model: AmazonOrder): Root = build(model) diff --git a/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala b/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala index 28d51c330c..3ac1379a43 100644 --- a/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala +++ b/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala @@ -11,7 +11,7 @@ object AmazonOrderWatchersManager extends AssignmentsManager[String, AmazonOrder val assignmentType = Assignment.Watcher val referenceType = Assignment.AmazonOrder - val notifyDimension = models.activity.Dimension.order + val notifyDimension = models.activity.Dimension.amazonOrder val notifyReason = NotificationSubscription.Watching def buildResponse(model: AmazonOrder): Root = build(model) From 856543695b5f0cc948256453c39450e01ecf75a6 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 20 Apr 2017 15:54:30 +0700 Subject: [PATCH 30/93] Add customer to amazon orders --- .../app/models/cord/AmazonOrder.scala | 18 +- .../app/payloads/AmazonOrderPayloads.scala | 9 +- .../responses/cord/AmazonOrderResponse.scala | 9 +- .../services/orders/AmazonOrderManager.scala | 22 +- phoenix-scala/app/utils/db/package.scala | 2 +- ..._orders_to_orders_search_view_triggers.sql | 82 +++--- .../sql/R__orders_search_view_triggers.sql | 2 - ...serach_view_id_seq_and_change_triggers.sql | 239 ++++++++++++++++++ 8 files changed, 310 insertions(+), 73 deletions(-) create mode 100644 phoenix-scala/sql/V4.118__add_orders_serach_view_id_seq_and_change_triggers.sql diff --git a/phoenix-scala/app/models/cord/AmazonOrder.scala b/phoenix-scala/app/models/cord/AmazonOrder.scala index 1384a2bf70..1d6062dcb4 100644 --- a/phoenix-scala/app/models/cord/AmazonOrder.scala +++ b/phoenix-scala/app/models/cord/AmazonOrder.scala @@ -10,6 +10,7 @@ import utils.aliases._ import failures._ import payloads.AmazonOrderPayloads.CreateAmazonOrderPayload import com.github.tminglei.slickpg.LTree +import models.account._ case class AmazonOrder(id: Int = 0, amazonOrderId: String = "", @@ -20,14 +21,13 @@ case class AmazonOrder(id: Int = 0, orderStatus: String = "", purchaseDate: Instant, scope: LTree, - customerName: String, - customerEmail: String, + accountId: Int, createdAt: Instant = Instant.now, updatedAt: Instant = Instant.now) extends FoxModel[AmazonOrder] object AmazonOrder { - def build(payload: CreateAmazonOrderPayload): AmazonOrder = + def build(payload: CreateAmazonOrderPayload, accountId: Int)(implicit ec: EC): AmazonOrder = AmazonOrder(id = 0, amazonOrderId = payload.amazonOrderId, orderTotal = payload.orderTotal, @@ -37,8 +37,7 @@ object AmazonOrder { orderStatus = payload.orderStatus, purchaseDate = payload.purchaseDate, scope = payload.scope, - customerName = payload.customerName, - customerEmail = payload.customerEmail, + accountId = accountId, createdAt = Instant.now, updatedAt = Instant.now) @@ -52,8 +51,7 @@ object AmazonOrder { orderStatus = existingOrder.orderStatus, purchaseDate = existingOrder.purchaseDate, scope = existingOrder.scope, - customerName = existingOrder.customerName, - customerEmail = existingOrder.customerEmail, + accountId = existingOrder.accountId, createdAt = existingOrder.createdAt, updatedAt = existingOrder.updatedAt) } @@ -83,8 +81,7 @@ class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") def orderStatus = column[String]("order_status") def purchaseDate = column[Instant]("purchase_date") def scope = column[LTree]("scope") - def customerName = column[String]("customer_name") - def customerEmail = column[String]("customer_email") + def accountId = column[Int]("account_id") def createdAt = column[Instant]("created_at") def updatedAt = column[Instant]("updated_at") @@ -98,8 +95,7 @@ class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") orderStatus, purchaseDate, scope, - customerName, - customerEmail, + accountId, createdAt, updatedAt) <> ((AmazonOrder.apply _).tupled, AmazonOrder.unapply) } diff --git a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala index d007afe48c..0774d5a419 100644 --- a/phoenix-scala/app/payloads/AmazonOrderPayloads.scala +++ b/phoenix-scala/app/payloads/AmazonOrderPayloads.scala @@ -5,15 +5,14 @@ import java.time.Instant import com.github.tminglei.slickpg.LTree object AmazonOrderPayloads { - case class CreateAmazonOrderPayload(amazonOrderId: String = "", + case class CreateAmazonOrderPayload(amazonOrderId: String, orderTotal: Int, paymentMethodDetail: String, - orderType: String = "", + orderType: String, currency: Currency = Currency.USD, - orderStatus: String = "", + orderStatus: String, scope: LTree, - customerName: String = "", - customerEmail: String = "", + customerEmail: String, purchaseDate: Instant) case class UpdateAmazonOrderPayload(orderStatus: String) diff --git a/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala index 3238c7f6a6..9fcb79224b 100644 --- a/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala +++ b/phoenix-scala/app/responses/cord/AmazonOrderResponse.scala @@ -15,8 +15,7 @@ case class AmazonOrderResponse(id: Int, orderStatus: String = "", purchaseDate: Instant, scope: LTree, - customerName: String = "", - customerEmail: String = "", + accountId: Int, createdAt: Instant = Instant.now, updatedAt: Instant = Instant.now) extends ResponseItem @@ -32,8 +31,7 @@ object AmazonOrderResponse { orderStatus: String, purchaseDate: Instant, scope: LTree, - customerName: String = "", - customerEmail: String = "", + accountId: Int, createdAt: Instant, updatedAt: Instant) extends ResponseItem @@ -48,8 +46,7 @@ object AmazonOrderResponse { orderStatus = amazonOrder.orderStatus, purchaseDate = amazonOrder.purchaseDate, scope = amazonOrder.scope, - customerName = amazonOrder.customerName, - customerEmail = amazonOrder.customerEmail, + accountId = amazonOrder.accountId, createdAt = amazonOrder.createdAt, updatedAt = amazonOrder.updatedAt) } diff --git a/phoenix-scala/app/services/orders/AmazonOrderManager.scala b/phoenix-scala/app/services/orders/AmazonOrderManager.scala index 949dda7f8d..92dfdc1508 100644 --- a/phoenix-scala/app/services/orders/AmazonOrderManager.scala +++ b/phoenix-scala/app/services/orders/AmazonOrderManager.scala @@ -3,28 +3,38 @@ package services import cats.implicits._ import payloads.AmazonOrderPayloads._ import models.cord._ +import models.account._ import responses.cord.AmazonOrderResponse import utils.aliases._ import utils.db._ +import failures._ object AmazonOrderManager { + def createAmazonOrder(payload: CreateAmazonOrderPayload)( implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrderResponse.Root] = { - val amazonOrderT = for { - result ← * <~ AmazonOrders - .findOneByAmazonOrderId(payload.amazonOrderId) - .findOrCreateExtended(AmazonOrders.create(AmazonOrder.build(payload))) - (existingOrder, foundOrCreated) = result - } yield result + val amazonOrderT = AmazonOrders + .findOneByAmazonOrderId(payload.amazonOrderId) + .findOrCreateExtended(createInner(payload)) amazonOrderT.map { case (existingOrder, foundOrCreated) ⇒ AmazonOrderResponse.build(AmazonOrder.fromExistingAmazonOrder(existingOrder)) } } + + private def createInner( + payload: CreateAmazonOrderPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrder] = + for { + user ← * <~ Users + .findByEmail(payload.customerEmail) + .mustFindOneOr(NotFoundFailure404(User, payload.customerEmail)) + amazonOrder ← AmazonOrders.create(AmazonOrder.build(payload, user.accountId)) + } yield amazonOrder + def updateAmazonOrder(amazonOrderId: String, payload: UpdateAmazonOrderPayload)( implicit ec: EC, db: DB, diff --git a/phoenix-scala/app/utils/db/package.scala b/phoenix-scala/app/utils/db/package.scala index ccab248be4..c9bdef80d7 100644 --- a/phoenix-scala/app/utils/db/package.scala +++ b/phoenix-scala/app/utils/db/package.scala @@ -13,7 +13,7 @@ import slick.profile.SqlAction import utils.aliases._ import utils.time.JavaTimeSlickMapper -/*_*/ // <- this little guy will disable IJ lint for the code below +/*_*/ // <- this little guy will disable IJ lint for the code below package object db { // ————————————————————————————— Foxy ————————————————————————————— diff --git a/phoenix-scala/sql/R__amazon_orders_to_orders_search_view_triggers.sql b/phoenix-scala/sql/R__amazon_orders_to_orders_search_view_triggers.sql index 38c955bdff..e768162f46 100644 --- a/phoenix-scala/sql/R__amazon_orders_to_orders_search_view_triggers.sql +++ b/phoenix-scala/sql/R__amazon_orders_to_orders_search_view_triggers.sql @@ -1,46 +1,44 @@ create or replace function update_orders_search_view_from_amazon_orders_insert_fn() returns trigger as $$ - begin - insert into orders_search_view ( - id, - scope, - reference_number, - state, - placed_at, - currency, - sub_total, - shipping_total, - adjustments_total, - taxes_total, - grand_total, - customer) - select distinct on (new.id) - -- order - ((select max(id) from orders_search_view group by id order by id DESC limit 1) + 1) as id, - new.scope as scope, - new.amazon_order_id as reference_number, - new.order_status as state, - to_char(new.purchase_date, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as placed_at, - new.currency as currency, - -- totals - 0 as sub_total, - 0 as shipping_total, - 0 as adjustments_total, - 0 as taxes_total, - new.order_total as grand_total, - -- customer - json_build_object( - 'id', 0, - 'name', ao.customer_name, - 'email', ao.customer_email, - 'is_blacklisted', false, - 'joined_at', null, - 'rank', null, - 'revenue', null - )::jsonb as customer - from amazon_orders as ao - where (new.amazon_order_id = ao.amazon_order_id); - return null; - end; + begin + insert into orders_search_view ( + scope, + reference_number, + state, + placed_at, + currency, + sub_total, + shipping_total, + adjustments_total, + taxes_total, + grand_total, + customer) + select distinct on (new.id) + -- order + new.scope as scope, + new.amazon_order_id as reference_number, + new.order_status as state, + to_char(new.purchase_date, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') as placed_at, + new.currency as currency, + -- totals + 0 as sub_total, + 0 as shipping_total, + 0 as adjustments_total, + 0 as taxes_total, + new.order_total as grand_total, + -- customer + json_build_object( + 'id', c.id, + 'name', c.name, + 'email', c.email, + 'is_blacklisted', c.is_blacklisted, + 'joined_at', c.joined_at, + 'rank', c.rank, + 'revenue', c.revenue + )::jsonb as customer + from customers_search_view as c + where (new.account_id = c.id); + return null; + end; $$ language plpgsql; -- update customer group function diff --git a/phoenix-scala/sql/R__orders_search_view_triggers.sql b/phoenix-scala/sql/R__orders_search_view_triggers.sql index 36c9caaa1b..23f7d0b785 100644 --- a/phoenix-scala/sql/R__orders_search_view_triggers.sql +++ b/phoenix-scala/sql/R__orders_search_view_triggers.sql @@ -1,7 +1,6 @@ create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ begin insert into orders_search_view ( - id, scope, reference_number, state, @@ -15,7 +14,6 @@ create or replace function update_orders_view_from_orders_insert_fn() returns tr customer) select distinct on (new.id) -- order - new.id as id, new.scope as scope, new.reference_number as reference_number, new.state as state, diff --git a/phoenix-scala/sql/V4.118__add_orders_serach_view_id_seq_and_change_triggers.sql b/phoenix-scala/sql/V4.118__add_orders_serach_view_id_seq_and_change_triggers.sql new file mode 100644 index 0000000000..3ff7d19001 --- /dev/null +++ b/phoenix-scala/sql/V4.118__add_orders_serach_view_id_seq_and_change_triggers.sql @@ -0,0 +1,239 @@ +-- set sequence value as max id + 1 +create sequence if not exists orders_search_view_id_seq increment by 1; + +select setval ('orders_search_view_id_seq', + coalesce((select max (id) + 1 from orders_search_view), 1), false); + +alter table orders_search_view + alter column id set default nextval ('orders_search_view_id_seq'); + +-- from amazon orders +create or replace function update_orders_search_view_from_amazon_orders_insert_fn() returns trigger as $$ +begin + insert into orders_search_view ( + scope, + reference_number, + state, + placed_at, + currency, + sub_total, + shipping_total, + adjustments_total, + taxes_total, + grand_total, + customer) + select distinct on (new.id) + -- order + new.scope as scope, + new.amazon_order_id as reference_number, + new.order_status as state, + to_char(new.purchase_date, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, + new.currency as currency, + -- totals + 0 as sub_total, + 0 as shipping_total, + 0 as adjustments_total, + 0 as taxes_total, + new.order_total as grand_total, + -- customer + json_build_object( + 'id', c.id, + 'name', c.name, + 'email', c.email, + 'is_blacklisted', c.is_blacklisted, + 'joined_at', c.joined_at, + 'rank', c.rank, + 'revenue', c.revenue + )::jsonb as customer + from customers_search_view as c + where (new.account_id = c.id); + return null; +end; +$$ language plpgsql; + +-- from orders + +create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ +begin + insert into orders_search_view ( + scope, + reference_number, + state, + placed_at, + currency, + sub_total, + shipping_total, + adjustments_total, + taxes_total, + grand_total, + customer) + select distinct on (new.id) + -- order + new.scope as scope, + new.reference_number as reference_number, + new.state as state, + to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, + new.currency as currency, + -- totals + new.sub_total as sub_total, + new.shipping_total as shipping_total, + new.adjustments_total as adjustments_total, + new.taxes_total as taxes_total, + new.grand_total as grand_total, + -- customer + json_build_object( + 'id', c.id, + 'name', c.name, + 'email', c.email, + 'is_blacklisted', c.is_blacklisted, + 'joined_at', c.joined_at, + 'rank', c.rank, + 'revenue', c.revenue + )::jsonb as customer + from customers_search_view as c + where (new.account_id = c.id); + return null; +end; +$$ language plpgsql; + +-- + +create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ +begin + insert into orders_search_view select distinct on (new.id) + -- order + new.reference_number as reference_number, + new.state as state, + to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, + new.currency as currency, + -- totals + new.sub_total as sub_total, + new.shipping_total as shipping_total, + new.adjustments_total as adjustments_total, + new.taxes_total as taxes_total, + new.grand_total as grand_total, + -- customer + json_build_object( + 'id', c.id, + 'name', c.name, + 'email', c.email, + 'is_blacklisted', c.is_blacklisted, + 'joined_at', to_char(c.created_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"'), + 'rank', rank.rank, + 'revenue', coalesce(rank.revenue, 0) + )::jsonb as customer + from customers as c + left join customers_ranking as rank on (c.id = rank.id) + where (new.customer_id = c.id); + return null; +end; +$$ language plpgsql; + +-- + +create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ +begin + insert into orders_search_view select distinct on (new.id) + -- order + new.reference_number as reference_number, + new.state as state, + to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, + new.currency as currency, + -- totals + new.sub_total as sub_total, + new.shipping_total as shipping_total, + new.adjustments_total as adjustments_total, + new.taxes_total as taxes_total, + new.grand_total as grand_total, + -- customer + json_build_object( + 'id', c.id, + 'name', c.name, + 'email', c.email, + 'is_blacklisted', c.is_blacklisted, + 'joined_at', c.joined_at, + 'rank', c.rank, + 'revenue', c.revenue + )::jsonb as customer + from customers_search_view as c + where (new.customer_id = c.id); + return null; +end; +$$ language plpgsql; + +-- + +create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ +begin + insert into orders_search_view select distinct on (new.id) + -- order + new.reference_number as reference_number, + new.state as state, + to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, + new.currency as currency, + -- totals + new.sub_total as sub_total, + new.shipping_total as shipping_total, + new.adjustments_total as adjustments_total, + new.taxes_total as taxes_total, + new.grand_total as grand_total, + -- customer + json_build_object( + 'id', c.id, + 'name', c.name, + 'email', c.email, + 'is_blacklisted', c.is_blacklisted, + 'joined_at', c.joined_at, + 'rank', c.rank, + 'revenue', c.revenue + )::jsonb as customer + from customers_search_view as c + where (new.account_id = c.id); + return null; +end; +$$ language plpgsql; + +-- + +create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ +begin + insert into orders_search_view ( + scope, + reference_number, + state, + placed_at, + currency, + sub_total, + shipping_total, + adjustments_total, + taxes_total, + grand_total, + customer) + select distinct on (new.id) + -- order + new.scope as scope, + new.reference_number as reference_number, + new.state as state, + to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, + new.currency as currency, + -- totals + new.sub_total as sub_total, + new.shipping_total as shipping_total, + new.adjustments_total as adjustments_total, + new.taxes_total as taxes_total, + new.grand_total as grand_total, + -- customer + json_build_object( + 'id', c.id, + 'name', c.name, + 'email', c.email, + 'is_blacklisted', c.is_blacklisted, + 'joined_at', c.joined_at, + 'rank', c.rank, + 'revenue', c.revenue + )::jsonb as customer + from customers_search_view as c + where (new.account_id = c.id); + return null; +end; +$$ language plpgsql; \ No newline at end of file From 001607a5f3eddc9e2b384447f90453b4a1dd9566 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 20 Apr 2017 16:25:33 +0700 Subject: [PATCH 31/93] Rename migration file --- ...V4.119__add_orders_search_view_id_seq_and_change_triggers.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename phoenix-scala/sql/{V4.118__add_orders_serach_view_id_seq_and_change_triggers.sql => V4.119__add_orders_search_view_id_seq_and_change_triggers.sql} (100%) diff --git a/phoenix-scala/sql/V4.118__add_orders_serach_view_id_seq_and_change_triggers.sql b/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql similarity index 100% rename from phoenix-scala/sql/V4.118__add_orders_serach_view_id_seq_and_change_triggers.sql rename to phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql From c52cff7754b02c67bbbc028c861bf4e71afb5ac8 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 20 Apr 2017 17:26:58 +0700 Subject: [PATCH 32/93] Alter amazon_orders table --- phoenix-scala/sql/V4.120__cgange_amazon_orders_table.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 phoenix-scala/sql/V4.120__cgange_amazon_orders_table.sql diff --git a/phoenix-scala/sql/V4.120__cgange_amazon_orders_table.sql b/phoenix-scala/sql/V4.120__cgange_amazon_orders_table.sql new file mode 100644 index 0000000000..0ab0819d0f --- /dev/null +++ b/phoenix-scala/sql/V4.120__cgange_amazon_orders_table.sql @@ -0,0 +1 @@ +alter table amazon_orders add column account_id int; \ No newline at end of file From a2bd68b4204ae30c7981daa7f371415bc05d9289 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 20 Apr 2017 17:29:19 +0700 Subject: [PATCH 33/93] Fix migration --- ...search_view_id_seq_and_change_triggers.sql | 142 ------------------ 1 file changed, 142 deletions(-) diff --git a/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql b/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql index 3ff7d19001..b15afd75be 100644 --- a/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql +++ b/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql @@ -95,145 +95,3 @@ begin return null; end; $$ language plpgsql; - --- - -create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ -begin - insert into orders_search_view select distinct on (new.id) - -- order - new.reference_number as reference_number, - new.state as state, - to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, - new.currency as currency, - -- totals - new.sub_total as sub_total, - new.shipping_total as shipping_total, - new.adjustments_total as adjustments_total, - new.taxes_total as taxes_total, - new.grand_total as grand_total, - -- customer - json_build_object( - 'id', c.id, - 'name', c.name, - 'email', c.email, - 'is_blacklisted', c.is_blacklisted, - 'joined_at', to_char(c.created_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"'), - 'rank', rank.rank, - 'revenue', coalesce(rank.revenue, 0) - )::jsonb as customer - from customers as c - left join customers_ranking as rank on (c.id = rank.id) - where (new.customer_id = c.id); - return null; -end; -$$ language plpgsql; - --- - -create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ -begin - insert into orders_search_view select distinct on (new.id) - -- order - new.reference_number as reference_number, - new.state as state, - to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, - new.currency as currency, - -- totals - new.sub_total as sub_total, - new.shipping_total as shipping_total, - new.adjustments_total as adjustments_total, - new.taxes_total as taxes_total, - new.grand_total as grand_total, - -- customer - json_build_object( - 'id', c.id, - 'name', c.name, - 'email', c.email, - 'is_blacklisted', c.is_blacklisted, - 'joined_at', c.joined_at, - 'rank', c.rank, - 'revenue', c.revenue - )::jsonb as customer - from customers_search_view as c - where (new.customer_id = c.id); - return null; -end; -$$ language plpgsql; - --- - -create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ -begin - insert into orders_search_view select distinct on (new.id) - -- order - new.reference_number as reference_number, - new.state as state, - to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, - new.currency as currency, - -- totals - new.sub_total as sub_total, - new.shipping_total as shipping_total, - new.adjustments_total as adjustments_total, - new.taxes_total as taxes_total, - new.grand_total as grand_total, - -- customer - json_build_object( - 'id', c.id, - 'name', c.name, - 'email', c.email, - 'is_blacklisted', c.is_blacklisted, - 'joined_at', c.joined_at, - 'rank', c.rank, - 'revenue', c.revenue - )::jsonb as customer - from customers_search_view as c - where (new.account_id = c.id); - return null; -end; -$$ language plpgsql; - --- - -create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ -begin - insert into orders_search_view ( - scope, - reference_number, - state, - placed_at, - currency, - sub_total, - shipping_total, - adjustments_total, - taxes_total, - grand_total, - customer) - select distinct on (new.id) - -- order - new.scope as scope, - new.reference_number as reference_number, - new.state as state, - to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, - new.currency as currency, - -- totals - new.sub_total as sub_total, - new.shipping_total as shipping_total, - new.adjustments_total as adjustments_total, - new.taxes_total as taxes_total, - new.grand_total as grand_total, - -- customer - json_build_object( - 'id', c.id, - 'name', c.name, - 'email', c.email, - 'is_blacklisted', c.is_blacklisted, - 'joined_at', c.joined_at, - 'rank', c.rank, - 'revenue', c.revenue - )::jsonb as customer - from customers_search_view as c - where (new.account_id = c.id); - return null; -end; -$$ language plpgsql; \ No newline at end of file From 32343331455c91cec6d2ea3f991fe796f8c2390b Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 21 Apr 2017 15:35:48 +0700 Subject: [PATCH 34/93] CodeReview and rename mistyped migration --- .../app/services/orders/AmazonOrderManager.scala | 9 ++++----- ..._table.sql => V4.120__change_amazon_orders_table.sql} | 0 2 files changed, 4 insertions(+), 5 deletions(-) rename phoenix-scala/sql/{V4.120__cgange_amazon_orders_table.sql => V4.120__change_amazon_orders_table.sql} (100%) diff --git a/phoenix-scala/app/services/orders/AmazonOrderManager.scala b/phoenix-scala/app/services/orders/AmazonOrderManager.scala index 92dfdc1508..c4e964497f 100644 --- a/phoenix-scala/app/services/orders/AmazonOrderManager.scala +++ b/phoenix-scala/app/services/orders/AmazonOrderManager.scala @@ -16,12 +16,11 @@ object AmazonOrderManager { db: DB, au: AU): DbResultT[AmazonOrderResponse.Root] = { - val amazonOrderT = AmazonOrders - .findOneByAmazonOrderId(payload.amazonOrderId) - .findOrCreateExtended(createInner(payload)) + val amazonOrderT = + AmazonOrders.findOneByAmazonOrderId(payload.amazonOrderId).findOrCreate(createInner(payload)) amazonOrderT.map { - case (existingOrder, foundOrCreated) ⇒ + case (existingOrder) ⇒ AmazonOrderResponse.build(AmazonOrder.fromExistingAmazonOrder(existingOrder)) } } @@ -32,7 +31,7 @@ object AmazonOrderManager { user ← * <~ Users .findByEmail(payload.customerEmail) .mustFindOneOr(NotFoundFailure404(User, payload.customerEmail)) - amazonOrder ← AmazonOrders.create(AmazonOrder.build(payload, user.accountId)) + amazonOrder ← * <~ AmazonOrders.create(AmazonOrder.build(payload, user.accountId)) } yield amazonOrder def updateAmazonOrder(amazonOrderId: String, payload: UpdateAmazonOrderPayload)( diff --git a/phoenix-scala/sql/V4.120__cgange_amazon_orders_table.sql b/phoenix-scala/sql/V4.120__change_amazon_orders_table.sql similarity index 100% rename from phoenix-scala/sql/V4.120__cgange_amazon_orders_table.sql rename to phoenix-scala/sql/V4.120__change_amazon_orders_table.sql From 6864731ca5ed062b90f2c1eba1b66b019e1d82e9 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 21 Apr 2017 16:46:01 +0700 Subject: [PATCH 35/93] Fix tests. We do not need order_id in returns search view --- phoenix-scala/sql/R__returns_search_view_triggers.sql | 4 ++-- .../sql/V4.121__drop_order_id_from_returns_search_view.sql | 2 ++ phoenix-scala/test/integration/ReturnsSearchViewTest.scala | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 phoenix-scala/sql/V4.121__drop_order_id_from_returns_search_view.sql diff --git a/phoenix-scala/sql/R__returns_search_view_triggers.sql b/phoenix-scala/sql/R__returns_search_view_triggers.sql index 1c507ca24a..0d350c6db6 100644 --- a/phoenix-scala/sql/R__returns_search_view_triggers.sql +++ b/phoenix-scala/sql/R__returns_search_view_triggers.sql @@ -3,7 +3,7 @@ create or replace function update_returns_search_view_from_returns_insert_fn() r insert into returns_search_view ( id, reference_number, - order_id, + -- order_id, order_ref, created_at, state, @@ -16,7 +16,7 @@ create or replace function update_returns_search_view_from_returns_insert_fn() r -- return new.id as id, new.reference_number as reference_number, - new.order_id as order_id, + -- new.order_id as order_id, new.order_ref as order_ref, to_json_timestamp(new.created_at) as created_at, new.state as state, diff --git a/phoenix-scala/sql/V4.121__drop_order_id_from_returns_search_view.sql b/phoenix-scala/sql/V4.121__drop_order_id_from_returns_search_view.sql new file mode 100644 index 0000000000..fbc170fee2 --- /dev/null +++ b/phoenix-scala/sql/V4.121__drop_order_id_from_returns_search_view.sql @@ -0,0 +1,2 @@ +-- after discussion with @@aafa; -@retgoat +alter table returns_search_view drop order_id; \ No newline at end of file diff --git a/phoenix-scala/test/integration/ReturnsSearchViewTest.scala b/phoenix-scala/test/integration/ReturnsSearchViewTest.scala index 433e416b8f..511dffb177 100644 --- a/phoenix-scala/test/integration/ReturnsSearchViewTest.scala +++ b/phoenix-scala/test/integration/ReturnsSearchViewTest.scala @@ -10,7 +10,6 @@ import testutils.fixtures.{BakedFixtures, ReturnsFixtures} case class ReturnsSearchViewResult( id: Int, referenceNumber: String, - orderId: Int, orderRef: String, createdAt: String, state: Return.State, From fe20835ed74a80865fa9fb32323a1c7f065de0ff Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 21 Apr 2017 16:46:51 +0700 Subject: [PATCH 36/93] Remove comments --- phoenix-scala/sql/R__returns_search_view_triggers.sql | 2 -- 1 file changed, 2 deletions(-) diff --git a/phoenix-scala/sql/R__returns_search_view_triggers.sql b/phoenix-scala/sql/R__returns_search_view_triggers.sql index 0d350c6db6..310848cf2e 100644 --- a/phoenix-scala/sql/R__returns_search_view_triggers.sql +++ b/phoenix-scala/sql/R__returns_search_view_triggers.sql @@ -3,7 +3,6 @@ create or replace function update_returns_search_view_from_returns_insert_fn() r insert into returns_search_view ( id, reference_number, - -- order_id, order_ref, created_at, state, @@ -16,7 +15,6 @@ create or replace function update_returns_search_view_from_returns_insert_fn() r -- return new.id as id, new.reference_number as reference_number, - -- new.order_id as order_id, new.order_ref as order_ref, to_json_timestamp(new.created_at) as created_at, new.state as state, From c6768ee849eb9128e5a7d5deadbd527515dad962 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Mon, 24 Apr 2017 17:04:01 +0700 Subject: [PATCH 37/93] Add Integration tests --- .../services/orders/AmazonOrderManager.scala | 2 +- .../app/utils/seeds/AmazonOrdersSeeds.scala | 26 +++++++++ phoenix-scala/app/utils/seeds/Factories.scala | 7 ++- .../AmazonOrderIntegrationTest.scala | 54 +++++++++++++++++++ .../testutils/apis/PhoenixAdminApi.scala | 11 ++++ 5 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 phoenix-scala/app/utils/seeds/AmazonOrdersSeeds.scala create mode 100644 phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala diff --git a/phoenix-scala/app/services/orders/AmazonOrderManager.scala b/phoenix-scala/app/services/orders/AmazonOrderManager.scala index c4e964497f..2814cc92a1 100644 --- a/phoenix-scala/app/services/orders/AmazonOrderManager.scala +++ b/phoenix-scala/app/services/orders/AmazonOrderManager.scala @@ -30,7 +30,7 @@ object AmazonOrderManager { for { user ← * <~ Users .findByEmail(payload.customerEmail) - .mustFindOneOr(NotFoundFailure404(User, payload.customerEmail)) + .mustFindOneOr(NotFoundFailure404(User, "email", payload.customerEmail)) amazonOrder ← * <~ AmazonOrders.create(AmazonOrder.build(payload, user.accountId)) } yield amazonOrder diff --git a/phoenix-scala/app/utils/seeds/AmazonOrdersSeeds.scala b/phoenix-scala/app/utils/seeds/AmazonOrdersSeeds.scala new file mode 100644 index 0000000000..eddfdfbf0b --- /dev/null +++ b/phoenix-scala/app/utils/seeds/AmazonOrdersSeeds.scala @@ -0,0 +1,26 @@ +package utils.seeds + +import scala.concurrent.ExecutionContext.Implicits.global + +import models.cord.AmazonOrder +import com.github.tminglei.slickpg.LTree +import utils.aliases._ +import utils.db._ +import java.time.Instant +import utils.Money.Currency + +trait AmazonOrdersSeeds { + def amazonOrder = + AmazonOrder(id = 0, + amazonOrderId = "112233", + orderTotal = 4500, + paymentMethodDetail = "CreditCard", + orderType = "StandardOrder", + currency = Currency.USD, + orderStatus = "Shipped", + purchaseDate = Instant.now, + scope = LTree("1"), + accountId = 0, + createdAt = Instant.now, + updatedAt = Instant.now) +} diff --git a/phoenix-scala/app/utils/seeds/Factories.scala b/phoenix-scala/app/utils/seeds/Factories.scala index 0b8405d523..9b3aa00558 100644 --- a/phoenix-scala/app/utils/seeds/Factories.scala +++ b/phoenix-scala/app/utils/seeds/Factories.scala @@ -1,6 +1,10 @@ package utils.seeds import models.Reason +import models.cord.AmazonOrder +import java.time.Instant +import com.github.tminglei.slickpg.LTree +import utils.Money.Currency import models.Reason.{Cancellation, GiftCardCreation, StoreCreditCreation} import models.cord.{OrderPayment, OrderShippingAddress} import models.payment.creditcard.CreditCardCharge @@ -25,7 +29,8 @@ object Factories with PromotionSeeds with ObjectSchemaSeeds with CouponSeeds - with SharedSearchSeeds { + with SharedSearchSeeds + with AmazonOrdersSeeds { implicit val formats = JsonFormatters.phoenixFormats diff --git a/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala b/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala new file mode 100644 index 0000000000..98c5feabe9 --- /dev/null +++ b/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala @@ -0,0 +1,54 @@ +import testutils._ +import testutils.apis._ +import testutils.fixtures._ +import payloads.AmazonOrderPayloads._ +import responses.cord.AmazonOrderResponse +import models.cord._ +import failures._ +import utils.db._ +import utils.db.ExPostgresDriver.api._ +import cats.implicits._ +import utils.seeds.Factories +import utils.Money.Currency +import java.time.Instant +import com.github.tminglei.slickpg.LTree + +class AmazonOrderIntegrationTest + extends IntegrationTestBase + with PhoenixAdminApi + with AutomaticAuth + with BakedFixtures + with TestActivityContext.AdminAC { + + "POST /v1/amazon_orders" - { + "successfully creates amazonOrder from payload" in new Customer_Seed { + val payload = CreateAmazonOrderPayload(amazonOrderId = "111-5296499-9653859", + orderTotal = 4500, + paymentMethodDetail = "CreditCard", + orderType = "StandardOrder", + currency = Currency.USD, + orderStatus = "Shipped", + purchaseDate = Instant.now, + scope = LTree("1"), + customerEmail = customer.email.value) + + val root = amazonOrderApi.create(payload).as[AmazonOrderResponse.Root] + val created = AmazonOrders.findOneByAmazonOrderId(root.amazonOrderId).gimme.value + created.id must === (root.id) + } + } + + "PATCH /v1/amazon_orders/:amazonOrderId" - { + "update existing order" in new Fixture { + val updPayload = UpdateAmazonOrderPayload(orderStatus = "ChangedStatus") + val updated = + amazonOrderApi.update(amazonOrder.amazonOrderId, updPayload).as[AmazonOrderResponse.Root] + updated.orderStatus must === (updPayload.orderStatus) + } + } + + trait Fixture extends Customer_Seed { + val amazonOrder = + AmazonOrders.create(Factories.amazonOrder.copy(accountId = customer.accountId)).gimme + } +} diff --git a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala index e5670c71a4..f9ccc6a687 100644 --- a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -30,6 +30,7 @@ import payloads.TaxonomyPayloads._ import payloads.TaxonPayloads._ import payloads.UserPayloads._ import payloads.VariantPayloads._ +import payloads.AmazonOrderPayloads._ import payloads._ import testutils._ import utils.aliases.OC @@ -42,6 +43,16 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ private val rootPrefix = "v1" + object amazonOrderApi { + val amazonOrdersPrefix = s"$rootPrefix/amazon_orders" + + def create(payload: CreateAmazonOrderPayload): HttpResponse = + POST(amazonOrdersPrefix, payload) + + def update(amazonOrderId: String, payload: UpdateAmazonOrderPayload): HttpResponse = + PATCH(s"$amazonOrdersPrefix/$amazonOrderId", payload) + } + object customersApi { val customersPrefix = s"$rootPrefix/customers" From d6d172d4c4a005c224f919c6e6b687d5240c883d Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Wed, 26 Apr 2017 14:30:00 +0700 Subject: [PATCH 38/93] Fix orders_search_view triggers --- phoenix-scala/sql/R__orders_search_view_triggers.sql | 2 ++ ...119__add_orders_search_view_id_seq_and_change_triggers.sql | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/phoenix-scala/sql/R__orders_search_view_triggers.sql b/phoenix-scala/sql/R__orders_search_view_triggers.sql index 23f7d0b785..fb0c216b70 100644 --- a/phoenix-scala/sql/R__orders_search_view_triggers.sql +++ b/phoenix-scala/sql/R__orders_search_view_triggers.sql @@ -1,6 +1,7 @@ create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ begin insert into orders_search_view ( + id, scope, reference_number, state, @@ -13,6 +14,7 @@ create or replace function update_orders_view_from_orders_insert_fn() returns tr grand_total, customer) select distinct on (new.id) + nextval('orders_search_view_id_seq') as id, -- order new.scope as scope, new.reference_number as reference_number, diff --git a/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql b/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql index b15afd75be..4a983697d1 100644 --- a/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql +++ b/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql @@ -11,6 +11,7 @@ alter table orders_search_view create or replace function update_orders_search_view_from_amazon_orders_insert_fn() returns trigger as $$ begin insert into orders_search_view ( + id, scope, reference_number, state, @@ -23,6 +24,7 @@ begin grand_total, customer) select distinct on (new.id) + nextval('orders_search_view_id_seq') as id, -- order new.scope as scope, new.amazon_order_id as reference_number, @@ -56,6 +58,7 @@ $$ language plpgsql; create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ begin insert into orders_search_view ( + id, scope, reference_number, state, @@ -68,6 +71,7 @@ begin grand_total, customer) select distinct on (new.id) + nextval('orders_search_view_id_seq') as id, -- order new.scope as scope, new.reference_number as reference_number, From 91cda792c7a4138017a90cec0e000512db0ce51b Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 28 Apr 2017 17:28:25 +0700 Subject: [PATCH 39/93] Implemet first run --- .../hyperion/models/pull_worker_history.ex | 39 +++++++++++++++++++ .../workers/amazon/customers_orders_worker.ex | 25 ++++++++---- hyperion/mix.exs | 1 + hyperion/mix.lock | 1 + .../V2_002__create_pull_worker_history.sql | 7 ++++ 5 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 hyperion/lib/hyperion/models/pull_worker_history.ex create mode 100644 hyperion/sql/V2_002__create_pull_worker_history.sql diff --git a/hyperion/lib/hyperion/models/pull_worker_history.ex b/hyperion/lib/hyperion/models/pull_worker_history.ex new file mode 100644 index 0000000000..e70c241c2c --- /dev/null +++ b/hyperion/lib/hyperion/models/pull_worker_history.ex @@ -0,0 +1,39 @@ +defmodule PullWorkerHistory do + + use Ecto.Schema + use Timex.Ecto.Timestamps + import Ecto.Changeset + import Ecto.Query + + @derive {Poison.Encoder, only: [:id, :last_run, :seller_id]} + + schema "pull_worker_history" do + field :last_run, Timex.Ecto.DateTime + field :seller_id + + timestamps() + end + + def changeset(pull_worker_history, params \\ %{}) do + pull_worker_history + |> cast(params, [:last_run, :seller_id]) + |> validate_required([:last_run, :seller_id]) + end + + def last_run_for(seller_id) do + # We're using amazon founded at date for furst run + q = (from h in PullWorkerHistory, where: h.seller_id == ^seller_id, order_by: [desc: h.id], limit: 1) + case Hyperion.Repo.all(q) do + [] -> Timex.parse!("1994-07-05", "%Y-%m-%d", :strftime) + r -> hd(r).last_run + end + end + + def insert_run_mark(seller_id) do + res = %PullWorkerHistory{seller_id: seller_id, last_run: Timex.beginning_of_day(Timex.now)} + case Hyperion.Repo.insert(res) do + {:ok, record} -> record.last_run + {:error, _ } -> raise "Can not create run mark!" + end + end +end diff --git a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex index e647d50612..624038a0f6 100644 --- a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex +++ b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex @@ -20,27 +20,38 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do {:noreply, state} end - defp do_work() do + def do_work() do try do - fetch_amazon_orders() + get_credentials() + |> fetch_amazon_orders |> store_customers_and_orders() rescue e in RuntimeError -> Logger.error "Error while fetching orders from Amazon: #{e.message}" end end - defp fetch_amazon_orders do - date = Timex.beginning_of_day(Timex.now) - |> Timex.format!("%Y-%m-%dT%TZ", :strftime) + defp get_credentials() do + cfg = Amazon.fetch_config() + if String.strip(cfg.seller_id) != "" do + cfg + else + raise "Credentials not set. Exiting." + end + end + + defp fetch_amazon_orders(cfg) do + date = PullWorkerHistory.last_run_for(cfg.seller_id) + |>Timex.format!("%Y-%m-%dT%H:%M:%SZ", :strftime) list = [fulfillment_channel: ["MFN", "AFN"], created_after: [date]] Logger.info("Fetching order with params: #{inspect(list)}") - case MWSClient.list_orders(list, Amazon.fetch_config()) do + case MWSClient.list_orders(list, cfg) do {:error, error} -> raise inspect(error) {:warn, warn} -> raise warn["ErrorResponse"]["Error"]["Message"] {_, resp} -> Logger.info("Orders fetched: #{inspect(resp)}") + PullWorkerHistory.insert_run_mark(cfg.seller_id) resp["ListOrdersResponse"]["ListOrdersResult"] end end @@ -51,7 +62,7 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do Client.create_order_and_customer(order) end) map when is_map(map) -> Client.create_order_and_customer(map) - empty when empty in [%{}, []] -> nil + nil -> Logger.info "No orders present: #{inspect(orders)}" _ -> Logger.error "Some error occured! #{inspect(orders)}" end end diff --git a/hyperion/mix.exs b/hyperion/mix.exs index 3670a4a07f..bd9ef75562 100644 --- a/hyperion/mix.exs +++ b/hyperion/mix.exs @@ -44,6 +44,7 @@ defmodule Hyperion.Mixfile do {:mws_client, github: "FoxComm/elixir-amazon-mws-client"}, {:json_web_token, "~> 0.2"}, {:envy, "~> 1.0.0"}, + {:timex_ecto, "~> 3.0"}, {:exsync, "~> 0.1", only: :dev}, {:espec, "~> 1.3.2", only: :test}, {:ex_machina, "~> 2.0", only: :test}] diff --git a/hyperion/mix.lock b/hyperion/mix.lock index 303bd0106b..6625b9fbaa 100644 --- a/hyperion/mix.lock +++ b/hyperion/mix.lock @@ -39,4 +39,5 @@ "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, "timex": {:hex, :timex, "3.1.13", "48b33162e3ec33e9a08fb5f98e3f3c19c3e328dded3156096c1969b77d33eef0", [:mix], [{:combine, "~> 0.7", [hex: :combine, optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, optional: false]}]}, + "timex_ecto": {:hex, :timex_ecto, "3.1.1", "37d54f6879d96a6789bb497296531cfb853631de78e152969d95cff03c1368dd", [:mix], [{:ecto, "~> 2.1.0", [hex: :ecto, optional: false]}, {:timex, "~> 3.0", [hex: :timex, optional: false]}]}, "tzdata": {:hex, :tzdata, "0.5.11", "3d5469a9f46bdf4a8760333dbdabdcc4751325035c454b10521f71e7c611ae50", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, optional: false]}]}} diff --git a/hyperion/sql/V2_002__create_pull_worker_history.sql b/hyperion/sql/V2_002__create_pull_worker_history.sql new file mode 100644 index 0000000000..d63def9d6e --- /dev/null +++ b/hyperion/sql/V2_002__create_pull_worker_history.sql @@ -0,0 +1,7 @@ +create table pull_worker_history( + id bigserial primary key, + seller_id varchar(255) not null, + last_run timestamp not null, + inserted_at timestamp not null, + updated_at timestamp not null +) \ No newline at end of file From 71852b8afaeee4dc21001f90d1f0b0c9aa705892 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 28 Apr 2017 17:31:55 +0700 Subject: [PATCH 40/93] Make function private --- hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex index 624038a0f6..cbae25e0fa 100644 --- a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex +++ b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex @@ -20,7 +20,7 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do {:noreply, state} end - def do_work() do + defp do_work() do try do get_credentials() |> fetch_amazon_orders From b099a29aef860aad57d27ba11c630c7b1e432dc3 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 28 Apr 2017 17:32:23 +0700 Subject: [PATCH 41/93] Add newline --- hyperion/sql/V2_002__create_pull_worker_history.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyperion/sql/V2_002__create_pull_worker_history.sql b/hyperion/sql/V2_002__create_pull_worker_history.sql index d63def9d6e..f9a384bd5e 100644 --- a/hyperion/sql/V2_002__create_pull_worker_history.sql +++ b/hyperion/sql/V2_002__create_pull_worker_history.sql @@ -4,4 +4,4 @@ create table pull_worker_history( last_run timestamp not null, inserted_at timestamp not null, updated_at timestamp not null -) \ No newline at end of file +) From 00f42b6d43dc989c782f479c221159fd86d406f5 Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Fri, 28 Apr 2017 14:08:56 +0300 Subject: [PATCH 42/93] fix tests --- .../test/integration/AmazonOrderIntegrationTest.scala | 1 - .../test/integration/testutils/apis/PhoenixAdminApi.scala | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala b/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala index 98c5feabe9..60357b6c79 100644 --- a/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala +++ b/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala @@ -16,7 +16,6 @@ import com.github.tminglei.slickpg.LTree class AmazonOrderIntegrationTest extends IntegrationTestBase with PhoenixAdminApi - with AutomaticAuth with BakedFixtures with TestActivityContext.AdminAC { diff --git a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala index 9111a521c8..21c8bb0d12 100644 --- a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -46,11 +46,11 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ object amazonOrderApi { val amazonOrdersPrefix = s"$rootPrefix/amazon_orders" - def create(payload: CreateAmazonOrderPayload): HttpResponse = - POST(amazonOrdersPrefix, payload) + def create(payload: CreateAmazonOrderPayload)(implicit aa: TestAdminAuth): HttpResponse = + POST(amazonOrdersPrefix, payload, aa.jwtCookie.some) - def update(amazonOrderId: String, payload: UpdateAmazonOrderPayload): HttpResponse = - PATCH(s"$amazonOrdersPrefix/$amazonOrderId", payload) + def update(amazonOrderId: String, payload: UpdateAmazonOrderPayload)(implicit aa: TestAdminAuth): HttpResponse = + PATCH(s"$amazonOrdersPrefix/$amazonOrderId", payload, aa.jwtCookie.some) } object customersApi { From e1be943dffaf5242c97cc232be0158818c6a4c3d Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Fri, 28 Apr 2017 14:28:25 +0300 Subject: [PATCH 43/93] add missing trait --- .../test/integration/AmazonOrderIntegrationTest.scala | 1 + .../test/integration/testutils/apis/PhoenixAdminApi.scala | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala b/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala index 60357b6c79..d459131b6d 100644 --- a/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala +++ b/phoenix-scala/test/integration/AmazonOrderIntegrationTest.scala @@ -17,6 +17,7 @@ class AmazonOrderIntegrationTest extends IntegrationTestBase with PhoenixAdminApi with BakedFixtures + with DefaultJwtAdminAuth with TestActivityContext.AdminAC { "POST /v1/amazon_orders" - { diff --git a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala index 21c8bb0d12..62a4e5fa97 100644 --- a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -49,7 +49,8 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def create(payload: CreateAmazonOrderPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(amazonOrdersPrefix, payload, aa.jwtCookie.some) - def update(amazonOrderId: String, payload: UpdateAmazonOrderPayload)(implicit aa: TestAdminAuth): HttpResponse = + def update(amazonOrderId: String, payload: UpdateAmazonOrderPayload)( + implicit aa: TestAdminAuth): HttpResponse = PATCH(s"$amazonOrdersPrefix/$amazonOrderId", payload, aa.jwtCookie.some) } From 348275582c92632daae375ee2dc8f3610c867cce Mon Sep 17 00:00:00 2001 From: mbektimirov Date: Mon, 1 May 2017 17:19:40 +0500 Subject: [PATCH 44/93] Fixed flow error --- .../components/promotions/widgets/select-products.jsx | 2 +- ashes/yarn.lock | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/ashes/src/components/promotions/widgets/select-products.jsx b/ashes/src/components/promotions/widgets/select-products.jsx index 721d74314d..c3ca7c11e0 100644 --- a/ashes/src/components/promotions/widgets/select-products.jsx +++ b/ashes/src/components/promotions/widgets/select-products.jsx @@ -151,7 +151,7 @@ class ProductsQualifier extends Component { } } - render(): Element<*> { + render() { return (
{this.props.label} diff --git a/ashes/yarn.lock b/ashes/yarn.lock index 7ebb5fc8a6..2a0ee199c8 100644 --- a/ashes/yarn.lock +++ b/ashes/yarn.lock @@ -7698,15 +7698,7 @@ react-docgen@^2.13.0: node-dir "^0.1.10" recast "^0.11.5" -react-dom@^15.2.0: - version "15.4.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.4.2.tgz#015363f05b0a1fd52ae9efdd3a0060d90695208f" - dependencies: - fbjs "^0.8.1" - loose-envify "^1.1.0" - object-assign "^4.1.0" - -react-dom@^15.5.4: +react-dom@^15.2.0, react-dom@^15.5.4: version "15.5.4" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.5.4.tgz#ba0c28786fd52ed7e4f2135fe0288d462aef93da" dependencies: From 6cd1b21af1a19abc1cfe681f3e4df00f25246932 Mon Sep 17 00:00:00 2001 From: Sergey Rublev Date: Mon, 1 May 2017 15:52:04 +0300 Subject: [PATCH 45/93] Bump sql versions --- ..._create_amazon_orders.sql => V4.118__create_amazon_orders.sql} | 0 ...r.sql => V4.119__alter_assignment_domain_add_amazon_order.sql} | 0 ...V4.120__add_orders_search_view_id_seq_and_change_triggers.sql} | 0 ...on_orders_table.sql => V4.121__change_amazon_orders_table.sql} | 0 ...iew.sql => V4.122__drop_order_id_from_returns_search_view.sql} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename phoenix-scala/sql/{V4.117__create_amazon_orders.sql => V4.118__create_amazon_orders.sql} (100%) rename phoenix-scala/sql/{V4.118__alter_assignment_domain_add_amazon_order.sql => V4.119__alter_assignment_domain_add_amazon_order.sql} (100%) rename phoenix-scala/sql/{V4.119__add_orders_search_view_id_seq_and_change_triggers.sql => V4.120__add_orders_search_view_id_seq_and_change_triggers.sql} (100%) rename phoenix-scala/sql/{V4.120__change_amazon_orders_table.sql => V4.121__change_amazon_orders_table.sql} (100%) rename phoenix-scala/sql/{V4.121__drop_order_id_from_returns_search_view.sql => V4.122__drop_order_id_from_returns_search_view.sql} (100%) diff --git a/phoenix-scala/sql/V4.117__create_amazon_orders.sql b/phoenix-scala/sql/V4.118__create_amazon_orders.sql similarity index 100% rename from phoenix-scala/sql/V4.117__create_amazon_orders.sql rename to phoenix-scala/sql/V4.118__create_amazon_orders.sql diff --git a/phoenix-scala/sql/V4.118__alter_assignment_domain_add_amazon_order.sql b/phoenix-scala/sql/V4.119__alter_assignment_domain_add_amazon_order.sql similarity index 100% rename from phoenix-scala/sql/V4.118__alter_assignment_domain_add_amazon_order.sql rename to phoenix-scala/sql/V4.119__alter_assignment_domain_add_amazon_order.sql diff --git a/phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql b/phoenix-scala/sql/V4.120__add_orders_search_view_id_seq_and_change_triggers.sql similarity index 100% rename from phoenix-scala/sql/V4.119__add_orders_search_view_id_seq_and_change_triggers.sql rename to phoenix-scala/sql/V4.120__add_orders_search_view_id_seq_and_change_triggers.sql diff --git a/phoenix-scala/sql/V4.120__change_amazon_orders_table.sql b/phoenix-scala/sql/V4.121__change_amazon_orders_table.sql similarity index 100% rename from phoenix-scala/sql/V4.120__change_amazon_orders_table.sql rename to phoenix-scala/sql/V4.121__change_amazon_orders_table.sql diff --git a/phoenix-scala/sql/V4.121__drop_order_id_from_returns_search_view.sql b/phoenix-scala/sql/V4.122__drop_order_id_from_returns_search_view.sql similarity index 100% rename from phoenix-scala/sql/V4.121__drop_order_id_from_returns_search_view.sql rename to phoenix-scala/sql/V4.122__drop_order_id_from_returns_search_view.sql From 5a776c6d96cdee4564dcfda5e7e18a87e5179b83 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 2 May 2017 08:56:27 +0700 Subject: [PATCH 46/93] Update orders fetcher --- hyperion/config/config.exs | 1 + hyperion/lib/hyperion.ex | 12 +-- hyperion/lib/hyperion/amazon/amazon.ex | 23 ++++-- hyperion/lib/hyperion/amazon/credentials.ex | 12 +++ .../hyperion/models/pull_worker_history.ex | 20 +++-- hyperion/lib/hyperion/phoenix_scala/client.ex | 41 +++++++++- .../workers/amazon/customers_orders_worker.ex | 14 ++-- .../workers/amazon/push_checker_worker.ex | 2 + hyperion/mix.lock | 82 +++++++++---------- tabernacle/ansible/group_vars/all | 1 + .../dev/marathon/templates/hyperion.json | 3 +- 11 files changed, 141 insertions(+), 70 deletions(-) diff --git a/hyperion/config/config.exs b/hyperion/config/config.exs index 88886273d7..6a9205c155 100644 --- a/hyperion/config/config.exs +++ b/hyperion/config/config.exs @@ -21,6 +21,7 @@ config :hyperion, config :hyperion, public_key: System.get_env("PUBLIC_KEY"), push_check_interval: System.get_env("PUSH_CHECK_INTERVAL"), + orders_fetch_interval: System.get_env("ORDERS_FETCH_INTERVAL"), create_plugin: System.get_env("CREATE_ASHES_PLUGIN") # This configuration is loaded before any dependency and is restricted diff --git a/hyperion/lib/hyperion.ex b/hyperion/lib/hyperion.ex index a43580ded8..1917fbdbeb 100644 --- a/hyperion/lib/hyperion.ex +++ b/hyperion/lib/hyperion.ex @@ -9,6 +9,13 @@ defmodule Hyperion do Envy.reload_config end + # Create plugin on app start only if ENV var defined + # Pattern match against `True' because of marathon + case Application.fetch_env(:hyperion, :create_plugin) do + {:ok, "true"} -> Hyperion.PhoenixScala.Client.create_amazon_plugin_in_ashes() + _ -> nil + end + children = [ worker(Hyperion.Repo, []), worker(Hyperion.Amazon.Workers.CustomersOrdersWorker, []), @@ -16,11 +23,6 @@ defmodule Hyperion do worker(Hyperion.MWSAuth, []) ] - # Create plugin on app start only if ENV var defined - case Application.fetch_env(:hyperion, :create_plugin) do - {:ok, "true"} -> Hyperion.PhoenixScala.Client.create_amazon_plugin_in_ashes() - _ -> nil - end opts = [strategy: :one_for_one, name: Hyperion.Supervisor] Supervisor.start_link(children, opts) diff --git a/hyperion/lib/hyperion/amazon/amazon.ex b/hyperion/lib/hyperion/amazon/amazon.ex index 9f58399a41..a3ea88d85f 100644 --- a/hyperion/lib/hyperion/amazon/amazon.ex +++ b/hyperion/lib/hyperion/amazon/amazon.ex @@ -76,13 +76,19 @@ defmodule Hyperion.Amazon do def fetch_config do token = Client.login fetch_config(token) - # Credentials.mws_config(jwt.scope) end def fetch_config(token) do Credentials.mws_config(token) end + def safe_fetch_config() do + case Client.safe_login() do + token -> Credentials.safe_mws_config(token) + nil -> nil + end + end + def get_full_order(order_id, token) do try do cfg = fetch_config(token) @@ -222,13 +228,6 @@ defmodule Hyperion.Amazon do }] end - defp get_country_id(code, token) do - resp = Client.get_countries(token) - Enum.filter(resp.body, fn(cnt) -> cnt["alpha2"] == code end) - |> hd - |> get_in(["id"]) - end - defp get_sku_image(sku, token) do sku = Client.get_sku(sku, token) case sku.body["errors"] do @@ -239,6 +238,14 @@ defmodule Hyperion.Amazon do end end + defp get_country_id(code, token) do + resp = Client.get_countries(token) + Enum.filter(resp.body, fn(cnt) -> cnt["alpha2"] == code end) + |> hd + |> get_in(["id"]) + end + + # gets the albums and images for skus, # adds the SKU for matching # renders main, pt and swatch images diff --git a/hyperion/lib/hyperion/amazon/credentials.ex b/hyperion/lib/hyperion/amazon/credentials.ex index 82955f74bc..60dac09e3f 100644 --- a/hyperion/lib/hyperion/amazon/credentials.ex +++ b/hyperion/lib/hyperion/amazon/credentials.ex @@ -6,6 +6,18 @@ defmodule Hyperion.Amazon.Credentials do |> build_cfg end + def safe_mws_config(token) do + Client.safe_get_credentials(token) + |> build_cfg + end + + defp build_cfg(client) when is_nil(client) do + %MWSClient.Config{aws_access_key_id: mws_access_key_id(), + aws_secret_access_key: mws_secret_access_key(), + seller_id: "", + mws_auth_token: "" } + end + defp build_cfg(client) do %MWSClient.Config{aws_access_key_id: mws_access_key_id(), aws_secret_access_key: mws_secret_access_key(), diff --git a/hyperion/lib/hyperion/models/pull_worker_history.ex b/hyperion/lib/hyperion/models/pull_worker_history.ex index e70c241c2c..fdb26132cd 100644 --- a/hyperion/lib/hyperion/models/pull_worker_history.ex +++ b/hyperion/lib/hyperion/models/pull_worker_history.ex @@ -20,8 +20,12 @@ defmodule PullWorkerHistory do |> validate_required([:last_run, :seller_id]) end + @doc """ + Gets the last run mark from the DB. + If it's first run using amazon founded at date as the search start + """ def last_run_for(seller_id) do - # We're using amazon founded at date for furst run + q = (from h in PullWorkerHistory, where: h.seller_id == ^seller_id, order_by: [desc: h.id], limit: 1) case Hyperion.Repo.all(q) do [] -> Timex.parse!("1994-07-05", "%Y-%m-%d", :strftime) @@ -29,11 +33,15 @@ defmodule PullWorkerHistory do end end + @doc """ + Stores run mark in the DB. + If mark for `today' already exists — returns it, + if not — creates new + """ def insert_run_mark(seller_id) do - res = %PullWorkerHistory{seller_id: seller_id, last_run: Timex.beginning_of_day(Timex.now)} - case Hyperion.Repo.insert(res) do - {:ok, record} -> record.last_run - {:error, _ } -> raise "Can not create run mark!" - end + date = Timex.beginning_of_day(Timex.now) + q = from p in PullWorkerHistory, where: p.last_run == ^date + res = %PullWorkerHistory{seller_id: seller_id, last_run: date} + Hyperion.Repo.one(q) || Hyperion.Repo.insert!(res) end end diff --git a/hyperion/lib/hyperion/phoenix_scala/client.ex b/hyperion/lib/hyperion/phoenix_scala/client.ex index 3856c1a428..958eca10c2 100644 --- a/hyperion/lib/hyperion/phoenix_scala/client.ex +++ b/hyperion/lib/hyperion/phoenix_scala/client.ex @@ -11,20 +11,36 @@ defmodule Hyperion.PhoenixScala.Client do base_uri <> path end + def email, do: Application.fetch_env!(:hyperion, :phoenix_email) + def password, do: Application.fetch_env!(:hyperion, :phoenix_password) + def org, do: Application.fetch_env!(:hyperion, :phoenix_org) + def login_params, do: Poison.encode!(%{email: email(), password: password(), org: org()}) + + @doc """ Gets JWT from Phoenix. Try to not use it very often because it takes a lot of time """ def login do - email = Application.fetch_env!(:hyperion, :phoenix_email) - password = Application.fetch_env!(:hyperion, :phoenix_password) - org = Application.fetch_env!(:hyperion, :phoenix_org) - params = Poison.encode!(%{email: email, password: password, org: org}) + params = login_params() case post("/api/v1/public/login", params, make_request_headers()) do {_, %{body: _, headers: headers, status_code: 200}} -> Keyword.take(headers, ["Jwt"]) |> hd |> elem(1) {_, %{body: resp, headers: _, status_code: _}} -> raise %PhoenixError{message: hd(resp["errors"])} end end + def safe_login() do + params = login_params() + case post("/api/v1/public/login", params, make_request_headers()) do + {_, %{body: _, headers: headers, status_code: 200}} -> Keyword.take(headers, ["Jwt"]) |> hd |> elem(1) + {:ok, %{body: body, headers: headers, status_code: 502}} -> + Logger.error "Some error occured on login: #{body}" + nil + {:error, %HTTPoison.Error{id: _, reason: reason}} -> + Logger.error "Some error occured on login: #{reason}" + nil + end + end + @doc """ Returns product by id """ @@ -122,6 +138,8 @@ defmodule Hyperion.PhoenixScala.Client do @doc """ Returns MWS credentials stored in Phoenix plugins """ + def get_credentials(token) when token == nil, do: nil + def get_credentials(token) do {_, resp} = get("/api/v1/plugins/settings/AmazonMWS/detailed", make_request_headers(token)) case resp.status_code do @@ -132,6 +150,21 @@ defmodule Hyperion.PhoenixScala.Client do end end + @doc """ + Not raising an error if no credentials set + """ + def safe_get_credentials(token) do + {_, resp} = get("/api/v1/plugins/settings/AmazonMWS/detailed", make_request_headers(token)) + case resp.status_code do + code when code in [200, 201] -> + resp.body["settings"] + |> Enum.reduce(%{}, fn({k, v}, acc) -> Map.put(acc, String.to_atom(k), v) end) + _ -> + Logger.error "Error while getting credentials #{inspect(resp)}" + nil + end + end + @doc """ Creates Amazon MWS plugin in phoenix on Hyperion start """ diff --git a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex index cbae25e0fa..149269890e 100644 --- a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex +++ b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex @@ -30,11 +30,12 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do end end - defp get_credentials() do - cfg = Amazon.fetch_config() + def get_credentials() do + cfg = Amazon.safe_fetch_config() if String.strip(cfg.seller_id) != "" do cfg else + schedule_work() raise "Credentials not set. Exiting." end end @@ -67,7 +68,10 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do end end - defp schedule_work do - Process.send_after(self(), :work, 24 * 60 * 60 * 1000) # In 24 hours + defp schedule_work() do + mins = Application.fetch_env!(:hyperion, :orders_fetch_interval) |> String.to_integer + next_run = Timex.shift(Timex.now, minutes: mins) |> Timex.format!("{ISO:Extended}") + Logger.info "Scheduling #{__MODULE__} for next run at: #{next_run}. Run Interval is set to #{mins} minute(s)" + Process.send_after(self(), :work, mins * 60 * 1000) end -end \ No newline at end of file +end diff --git a/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex b/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex index d862694b8a..7397553b40 100644 --- a/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex +++ b/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex @@ -78,6 +78,8 @@ defmodule Hyperion.Amazon.Workers.PushCheckerWorker do defp schedule_work do mins = Application.fetch_env!(:hyperion, :push_check_interval) |> String.to_integer + next_run = Timex.shift(Timex.now, minutes: mins) |> Timex.format!("{ISO:Extended}") + Logger.info "Scheduling #{__MODULE__} for next run at: #{next_run}. Run Interval is set to #{mins} minute(s)" Process.send_after(self(), :work, mins * 60 * 1000) end end diff --git a/hyperion/mix.lock b/hyperion/mix.lock index 6625b9fbaa..4a8306b832 100644 --- a/hyperion/mix.lock +++ b/hyperion/mix.lock @@ -1,43 +1,43 @@ -%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []}, - "combine": {:hex, :combine, "0.9.6", "8d1034a127d4cbf6924c8a5010d3534d958085575fa4d9b878f200d79ac78335", [:mix], []}, - "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []}, - "cors_plug": {:hex, :cors_plug, "1.2.1", "bbe1381a52e4a16e609cf3c4cbfde6884726a58b9a1a205db104dbdfc542f447", [:mix], [{:plug, "> 0.8.0", [hex: :plug, optional: false]}]}, - "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, optional: false]}]}, - "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []}, - "csv": {:hex, :csv, "1.4.4", "992f2e1418849a326fd1d9287801fa2d86091db4f9611f60781da6d236f64cd4", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, optional: false]}]}, - "db_connection": {:hex, :db_connection, "1.1.1", "f9d246e8f65b9490945cf7360875eee18fcec9a0115207603215eb1fd94c39ef", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]}, - "decimal": {:hex, :decimal, "1.3.1", "157b3cedb2bfcb5359372a7766dd7a41091ad34578296e951f58a946fcab49c6", [:mix], []}, - "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]}, +%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], [], "hexpm"}, + "combine": {:hex, :combine, "0.9.6", "8d1034a127d4cbf6924c8a5010d3534d958085575fa4d9b878f200d79ac78335", [:mix], [], "hexpm"}, + "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, + "cors_plug": {:hex, :cors_plug, "1.2.1", "bbe1381a52e4a16e609cf3c4cbfde6884726a58b9a1a205db104dbdfc542f447", [:mix], [{:plug, "> 0.8.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, + "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"}, + "csv": {:hex, :csv, "1.4.4", "992f2e1418849a326fd1d9287801fa2d86091db4f9611f60781da6d236f64cd4", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"}, + "db_connection": {:hex, :db_connection, "1.1.1", "f9d246e8f65b9490945cf7360875eee18fcec9a0115207603215eb1fd94c39ef", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "decimal": {:hex, :decimal, "1.3.1", "157b3cedb2bfcb5359372a7766dd7a41091ad34578296e951f58a946fcab49c6", [:mix], [], "hexpm"}, + "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "elixir_xml_to_map": {:git, "https://github.com/retgoat/elixir-xml-to-map.git", "c5171c8173ec72fb35d306eb3b8fb6e03741a4e2", [tag: "0.1.2"]}, - "envy": {:hex, :envy, "1.0.0", "d8385715b908f3972f85cbffa0ffbd36fec017601258bcb6be9003c11ece3e75", [:mix], []}, - "erlsom": {:hex, :erlsom, "1.4.1", "53dbacf35adfea6f0714fd0e4a7b0720d495e88c5e24e12c5dc88c7b62bd3e49", [:rebar3], []}, - "espec": {:hex, :espec, "1.3.2", "20c96d580df671860bd8e7de1523be9ead34bbdca4912689a54f295add56d683", [:mix], [{:meck, "0.8.4", [hex: :meck, optional: false]}]}, - "ex_aws": {:hex, :ex_aws, "1.1.1", "58c46d9a0b395d7cbb065424c109feb6a7385907c12a91d3032a1e8baf3d6220", [:mix], [{:configparser_ex, "~> 0.2.1", [hex: :configparser_ex, optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1", [hex: :hackney, optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, optional: true]}, {:xml_builder, "~> 0.0.6", [hex: :xml_builder, optional: true]}]}, - "ex_machina": {:hex, :ex_machina, "2.0.0", "ec284c6f57233729cea9319e083f66e613e82549f78eccdb2059aeba5d0df9f3", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, optional: true]}]}, - "exfswatch": {:hex, :exfswatch, "0.2.1", "3f34190e2750ae6d924ce53729bb40e050dd8a08fee683847e6ddfa03ea5429f", [:mix], [{:fs, "~> 0.9", [hex: :fs, optional: false]}]}, - "exsync": {:hex, :exsync, "0.1.3", "84c66a4f60505d1baeb8a79cbf713ae98276f23b4bc7d676c6cb2d663fced5f3", [:mix], [{:exfswatch, "~> 0.2.1", [hex: :exfswatch, optional: false]}]}, - "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []}, - "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], []}, - "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, - "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.0.1", "2572e7122c78ab7e57b613e7c7f5e42bf9b3c25e430e32f23f1413d86db8a0af", [:mix], [{:mochiweb, "~> 2.12.2", [hex: :mochiweb, optional: false]}]}, - "httpoison": {:hex, :httpoison, "0.11.1", "d06c571274c0e77b6cc50e548db3fd7779f611fbed6681fd60a331f66c143a0b", [:mix], [{:hackney, "~> 1.7.0", [hex: :hackney, optional: false]}]}, - "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []}, - "inflex": {:hex, :inflex, "1.7.0", "4466a34b7d8e871d8164619ba0f3b8410ec782e900f0ae1d3d27a5875a29532e", [:mix], []}, - "json_web_token": {:hex, :json_web_token, "0.2.8", "c79d4c36cfd6f205be7099713e67d6057bde64ee9c64363f9001e3de86de703c", [:mix], [{:poison, "~> 3.1", [hex: :poison, optional: false]}]}, - "maru": {:hex, :maru, "0.11.3", "0bf2f26955430c4878dab91fe44aeb8b3aaed338b4f6ffd0729ea119284c374d", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: false]}, {:plug, "~> 1.0", [hex: :plug, optional: false]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}]}, - "meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], []}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, - "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, - "mochiweb": {:hex, :mochiweb, "2.12.2", "80804ad342afa3d7f3524040d4eed66ce74b17a555de454ac85b07c479928e46", [:make, :rebar], []}, + "envy": {:hex, :envy, "1.0.0", "d8385715b908f3972f85cbffa0ffbd36fec017601258bcb6be9003c11ece3e75", [:mix], [], "hexpm"}, + "erlsom": {:hex, :erlsom, "1.4.1", "53dbacf35adfea6f0714fd0e4a7b0720d495e88c5e24e12c5dc88c7b62bd3e49", [:rebar3], [], "hexpm"}, + "espec": {:hex, :espec, "1.3.2", "20c96d580df671860bd8e7de1523be9ead34bbdca4912689a54f295add56d683", [:mix], [{:meck, "0.8.4", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"}, + "ex_aws": {:hex, :ex_aws, "1.1.1", "58c46d9a0b395d7cbb065424c109feb6a7385907c12a91d3032a1e8baf3d6220", [:mix], [{:configparser_ex, "~> 0.2.1", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.0.6", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"}, + "ex_machina": {:hex, :ex_machina, "2.0.0", "ec284c6f57233729cea9319e083f66e613e82549f78eccdb2059aeba5d0df9f3", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, + "exfswatch": {:hex, :exfswatch, "0.2.1", "3f34190e2750ae6d924ce53729bb40e050dd8a08fee683847e6ddfa03ea5429f", [:mix], [{:fs, "~> 0.9", [hex: :fs, repo: "hexpm", optional: false]}], "hexpm"}, + "exsync": {:hex, :exsync, "0.1.3", "84c66a4f60505d1baeb8a79cbf713ae98276f23b4bc7d676c6cb2d663fced5f3", [:mix], [{:exfswatch, "~> 0.2.1", [hex: :exfswatch, repo: "hexpm", optional: false]}], "hexpm"}, + "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], [], "hexpm"}, + "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "4.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.0.1", "2572e7122c78ab7e57b613e7c7f5e42bf9b3c25e430e32f23f1413d86db8a0af", [:mix], [{:mochiweb, "~> 2.12.2", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, + "httpoison": {:hex, :httpoison, "0.11.1", "d06c571274c0e77b6cc50e548db3fd7779f611fbed6681fd60a331f66c143a0b", [:mix], [{:hackney, "~> 1.7.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], [], "hexpm"}, + "inflex": {:hex, :inflex, "1.7.0", "4466a34b7d8e871d8164619ba0f3b8410ec782e900f0ae1d3d27a5875a29532e", [:mix], [], "hexpm"}, + "json_web_token": {:hex, :json_web_token, "0.2.8", "c79d4c36cfd6f205be7099713e67d6057bde64ee9c64363f9001e3de86de703c", [:mix], [{:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, + "maru": {:hex, :maru, "0.11.3", "0bf2f26955430c4878dab91fe44aeb8b3aaed338b4f6ffd0729ea119284c374d", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, + "meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], [], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, + "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, + "mochiweb": {:hex, :mochiweb, "2.12.2", "80804ad342afa3d7f3524040d4eed66ce74b17a555de454ac85b07c479928e46", [:make, :rebar], [], "hexpm"}, "mws_client": {:git, "https://github.com/FoxComm/elixir-amazon-mws-client.git", "145210296b12d0aaa5ee6cabb21c6a79fea6e96d", []}, - "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [:mix], []}, - "plug": {:hex, :plug, "1.3.3", "d9be189924379b4e9d470caef87380d09549aea1ceafe6a0d41292c8c317c923", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []}, - "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], []}, - "postgrex": {:hex, :postgrex, "0.13.2", "2b88168fc6a5456a27bfb54ccf0ba4025d274841a7a3af5e5deb1b755d95154e", [:mix], [{:connection, "~> 1.0", [hex: :connection, optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}]}, - "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, - "timex": {:hex, :timex, "3.1.13", "48b33162e3ec33e9a08fb5f98e3f3c19c3e328dded3156096c1969b77d33eef0", [:mix], [{:combine, "~> 0.7", [hex: :combine, optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, optional: false]}]}, - "timex_ecto": {:hex, :timex_ecto, "3.1.1", "37d54f6879d96a6789bb497296531cfb853631de78e152969d95cff03c1368dd", [:mix], [{:ecto, "~> 2.1.0", [hex: :ecto, optional: false]}, {:timex, "~> 3.0", [hex: :timex, optional: false]}]}, - "tzdata": {:hex, :tzdata, "0.5.11", "3d5469a9f46bdf4a8760333dbdabdcc4751325035c454b10521f71e7c611ae50", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, optional: false]}]}} + "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [:mix], [], "hexpm"}, + "plug": {:hex, :plug, "1.3.3", "d9be189924379b4e9d470caef87380d09549aea1ceafe6a0d41292c8c317c923", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, + "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, + "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, + "postgrex": {:hex, :postgrex, "0.13.2", "2b88168fc6a5456a27bfb54ccf0ba4025d274841a7a3af5e5deb1b755d95154e", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, + "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, + "timex": {:hex, :timex, "3.1.13", "48b33162e3ec33e9a08fb5f98e3f3c19c3e328dded3156096c1969b77d33eef0", [:mix], [{:combine, "~> 0.7", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, + "timex_ecto": {:hex, :timex_ecto, "3.1.1", "37d54f6879d96a6789bb497296531cfb853631de78e152969d95cff03c1368dd", [:mix], [{:ecto, "~> 2.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:timex, "~> 3.0", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm"}, + "tzdata": {:hex, :tzdata, "0.5.11", "3d5469a9f46bdf4a8760333dbdabdcc4751325035c454b10521f71e7c611ae50", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}} diff --git a/tabernacle/ansible/group_vars/all b/tabernacle/ansible/group_vars/all index 4507dc708b..04c5432f48 100644 --- a/tabernacle/ansible/group_vars/all +++ b/tabernacle/ansible/group_vars/all @@ -271,6 +271,7 @@ hyperion_db_host: "{{db_host}}" hyperion_db_connection_string: "postgresql://{{hyperion_db_user}}@{{hyperion_db_host}}/{{hyperion_db_name}}" hyperion_test_db_name: hyperion_test hyperion_push_check_interval: 5 +hyperion_orders_fetch_interval: 24 hyperion_create_plugin_in_ashes_on_start: true # Eggcreate diff --git a/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json b/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json index 983fc4005d..521d1730b4 100644 --- a/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json +++ b/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json @@ -27,7 +27,8 @@ "PHOENIX_URL": "https://{{storefront_server_name}}", "PUBLIC_KEY": "{{public_keys_dest_dir}}/public_key.pem", "PUSH_CHECK_INTERVAL": "{{hyperion_push_check_interval}}", - "CREATE_ASHES_PLUGIN": "{{hyperion_create_plugin_in_ashes_on_start}}" + "ORDERS_FETCH_INTERVAL" : "{{hyperion_orders_fetch_interval}}", + "CREATE_ASHES_PLUGIN": "{{hyperion_create_plugin_in_ashes_on_start | bool}}" }, "constraints": [["hostname", "UNIQUE"]], "container": { From bb275bf7532d6903d513314b2727df343993705f Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 2 May 2017 16:59:11 +0700 Subject: [PATCH 47/93] Fix seeder image --- hyperion/Dockerfile.seed | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hyperion/Dockerfile.seed b/hyperion/Dockerfile.seed index d1d83618b8..341ac59761 100644 --- a/hyperion/Dockerfile.seed +++ b/hyperion/Dockerfile.seed @@ -11,6 +11,7 @@ ARG db_name="hyperion_development" ARG db_user="hyperion" ARG db_password="" ARG push_check_interval=5 +ARG orders_fetch_interval=1440 ARG hyperion_env=prod ENV HYPERION_DB_NAME $db_name @@ -18,6 +19,7 @@ ENV HYPERION_DB_USER $db_user ENV HYPERION_DB_PASSWORD $db_password ENV HYPERION_DB_HOST $db_host ENV PUSH_CHECK_INTERVAL $push_check_interval +ENV ORDERS_FETCH_INTERVAL $orders_fetch_interval ENV MIX_ENV $hyperion_env RUN mix local.hex --force From 8f4638c727a2b978d3b9b7f5e47b510af883865e Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 2 May 2017 17:00:48 +0700 Subject: [PATCH 48/93] Prevent fail if no SKU in phoenix --- hyperion/lib/hyperion/amazon/amazon.ex | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/hyperion/lib/hyperion/amazon/amazon.ex b/hyperion/lib/hyperion/amazon/amazon.ex index a3ea88d85f..23a65eaf02 100644 --- a/hyperion/lib/hyperion/amazon/amazon.ex +++ b/hyperion/lib/hyperion/amazon/amazon.ex @@ -1,6 +1,5 @@ defmodule Hyperion.Amazon do alias Hyperion.PhoenixScala.Client, warn: true - alias Hyperion.JwtAuth, warn: true alias Hyperion.Amazon.Credentials, warn: true require Logger @@ -228,13 +227,17 @@ defmodule Hyperion.Amazon do }] end - defp get_sku_image(sku, token) do - sku = Client.get_sku(sku, token) - case sku.body["errors"] do - nil -> - first_image = hd(sku.body["albums"])["images"] |> hd - first_image["src"] - err -> raise %AmazonError{message: "#{err}"} + def get_sku_image(sku, token) do + try do + sku = Client.get_sku(sku, token) + case sku.body["errors"] do + nil -> + first_image = hd(sku.body["albums"])["images"] |> hd + first_image["src"] + err -> raise %AmazonError{message: "#{err}"} + end + rescue _e in PhoenixError -> + nil end end From 0235eec080ee71a73ea5e2a0fcfa0e1ae638a2ea Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 2 May 2017 17:13:30 +0700 Subject: [PATCH 49/93] Fix tabernacle ENV var --- tabernacle/ansible/roles/dev/marathon/templates/hyperion.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json b/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json index 521d1730b4..db853839b8 100644 --- a/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json +++ b/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json @@ -28,7 +28,7 @@ "PUBLIC_KEY": "{{public_keys_dest_dir}}/public_key.pem", "PUSH_CHECK_INTERVAL": "{{hyperion_push_check_interval}}", "ORDERS_FETCH_INTERVAL" : "{{hyperion_orders_fetch_interval}}", - "CREATE_ASHES_PLUGIN": "{{hyperion_create_plugin_in_ashes_on_start | bool}}" + "CREATE_ASHES_PLUGIN": "{{hyperion_create_plugin_in_ashes_on_start | bool | lower}}" }, "constraints": [["hostname", "UNIQUE"]], "container": { From dfb3e963fb06a1fb2775e1fbcd7c966df5ec3e80 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 2 May 2017 17:53:16 +0700 Subject: [PATCH 50/93] Fix customer creation --- hyperion/lib/hyperion/phoenix_scala/client.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyperion/lib/hyperion/phoenix_scala/client.ex b/hyperion/lib/hyperion/phoenix_scala/client.ex index 958eca10c2..150fd20ed6 100644 --- a/hyperion/lib/hyperion/phoenix_scala/client.ex +++ b/hyperion/lib/hyperion/phoenix_scala/client.ex @@ -98,7 +98,7 @@ defmodule Hyperion.PhoenixScala.Client do Creates new customer in Phoenix from Amazon order """ def create_customer(payload, token) do - params = Poison.encode!(%{name: payload["BuyerName"], email: payload["BuyerName"]}) + params = Poison.encode!(%{name: payload["BuyerName"], email: payload["BuyerEmail"]}) {_, resp} = post("/api/v1/customers", params, make_request_headers(token)) case resp.status_code do # status_code = 400 means customer already exists From 4ab972c898246eaea2aa5ac1d6b33f50bd59d3f7 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 2 May 2017 18:09:11 +0700 Subject: [PATCH 51/93] Fix hyperion tests --- hyperion/.env.test | 1 + 1 file changed, 1 insertion(+) diff --git a/hyperion/.env.test b/hyperion/.env.test index 8c93eabd88..6c4bc33857 100644 --- a/hyperion/.env.test +++ b/hyperion/.env.test @@ -6,6 +6,7 @@ HYPERION_DB_HOST=localhost # misc PUSH_CHECK_INTERVAL=5 +ORDERS_FETCH_INTERVAL=1440 # AWS AWS_ACCESS_KEY_ID=AWK_KEY From 8dad0d5594a5319069be5930a8e65691b225005a Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 2 May 2017 18:18:36 +0700 Subject: [PATCH 52/93] Workers are only available in test --- hyperion/.env.test | 4 ---- .../hyperion/workers/amazon/customers_orders_worker.ex | 8 ++++++-- .../lib/hyperion/workers/amazon/push_checker_worker.ex | 8 ++++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/hyperion/.env.test b/hyperion/.env.test index 6c4bc33857..532c899671 100644 --- a/hyperion/.env.test +++ b/hyperion/.env.test @@ -4,10 +4,6 @@ HYPERION_DB_PASSWORD='' HYPERION_DB_NAME=hyperion_test HYPERION_DB_HOST=localhost -# misc -PUSH_CHECK_INTERVAL=5 -ORDERS_FETCH_INTERVAL=1440 - # AWS AWS_ACCESS_KEY_ID=AWK_KEY AWS_SECRET_ACCESS_KEY=AWS_SECRET diff --git a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex index 149269890e..690a85c589 100644 --- a/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex +++ b/hyperion/lib/hyperion/workers/amazon/customers_orders_worker.ex @@ -10,8 +10,12 @@ defmodule Hyperion.Amazon.Workers.CustomersOrdersWorker do end def init(state) do - schedule_work() - {:ok, state} + case Mix.env do + :test -> {:ok, state} + _ -> + schedule_work() + {:ok, state} + end end def handle_info(:work, state) do diff --git a/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex b/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex index 7397553b40..19af103c91 100644 --- a/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex +++ b/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex @@ -8,8 +8,12 @@ defmodule Hyperion.Amazon.Workers.PushCheckerWorker do end def init(state) do - schedule_work() - {:ok, state} + case Mix.env do + :test -> {:ok, state} + _ -> + schedule_work() + {:ok, state} + end end def handle_info(:work, state) do From 49aaf1e35330efe278c5d0a726d391670b53c3c1 Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Tue, 2 May 2017 15:04:15 +0300 Subject: [PATCH 53/93] remove primarySearchTerm for amazon order --- .../starfish/src/main/scala/utils/db/SearchTerms.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/phoenix-scala/starfish/src/main/scala/utils/db/SearchTerms.scala b/phoenix-scala/starfish/src/main/scala/utils/db/SearchTerms.scala index 0d2a818398..099e76c715 100644 --- a/phoenix-scala/starfish/src/main/scala/utils/db/SearchTerms.scala +++ b/phoenix-scala/starfish/src/main/scala/utils/db/SearchTerms.scala @@ -48,8 +48,6 @@ trait SearchByRefNum[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T trait SearchByAmazonOrderId[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T] { - override def primarySearchTerm = "amazonOrderId" - def findOneByAmazonOrderId(amazonOrderId: String): DBIO[Option[M]] def mustFindByAmazonOrderId( From b98b80ffabb56b7a334c29c708e7532fe40ea9de Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 2 May 2017 20:55:26 +0700 Subject: [PATCH 54/93] Fix tests --- hyperion/.env.test | 3 + .../workers/amazon/push_checker_worker.ex | 8 +- hyperion/mix.lock | 82 +++++++++---------- 3 files changed, 46 insertions(+), 47 deletions(-) diff --git a/hyperion/.env.test b/hyperion/.env.test index 532c899671..bb9ecae0dc 100644 --- a/hyperion/.env.test +++ b/hyperion/.env.test @@ -11,3 +11,6 @@ AWS_SECRET_ACCESS_KEY=AWS_SECRET # MWS MWS_ACCESS_KEY_ID=MWS_KEY MWS_SECRET_ACCESS_KEY=MWS_SECRET + +# misc +PUSH_CHECK_INTERVAL=5 diff --git a/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex b/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex index 19af103c91..7397553b40 100644 --- a/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex +++ b/hyperion/lib/hyperion/workers/amazon/push_checker_worker.ex @@ -8,12 +8,8 @@ defmodule Hyperion.Amazon.Workers.PushCheckerWorker do end def init(state) do - case Mix.env do - :test -> {:ok, state} - _ -> - schedule_work() - {:ok, state} - end + schedule_work() + {:ok, state} end def handle_info(:work, state) do diff --git a/hyperion/mix.lock b/hyperion/mix.lock index 4a8306b832..6625b9fbaa 100644 --- a/hyperion/mix.lock +++ b/hyperion/mix.lock @@ -1,43 +1,43 @@ -%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], [], "hexpm"}, - "combine": {:hex, :combine, "0.9.6", "8d1034a127d4cbf6924c8a5010d3534d958085575fa4d9b878f200d79ac78335", [:mix], [], "hexpm"}, - "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, - "cors_plug": {:hex, :cors_plug, "1.2.1", "bbe1381a52e4a16e609cf3c4cbfde6884726a58b9a1a205db104dbdfc542f447", [:mix], [{:plug, "> 0.8.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, - "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"}, - "csv": {:hex, :csv, "1.4.4", "992f2e1418849a326fd1d9287801fa2d86091db4f9611f60781da6d236f64cd4", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"}, - "db_connection": {:hex, :db_connection, "1.1.1", "f9d246e8f65b9490945cf7360875eee18fcec9a0115207603215eb1fd94c39ef", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, - "decimal": {:hex, :decimal, "1.3.1", "157b3cedb2bfcb5359372a7766dd7a41091ad34578296e951f58a946fcab49c6", [:mix], [], "hexpm"}, - "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, +%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []}, + "combine": {:hex, :combine, "0.9.6", "8d1034a127d4cbf6924c8a5010d3534d958085575fa4d9b878f200d79ac78335", [:mix], []}, + "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []}, + "cors_plug": {:hex, :cors_plug, "1.2.1", "bbe1381a52e4a16e609cf3c4cbfde6884726a58b9a1a205db104dbdfc542f447", [:mix], [{:plug, "> 0.8.0", [hex: :plug, optional: false]}]}, + "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, optional: false]}]}, + "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []}, + "csv": {:hex, :csv, "1.4.4", "992f2e1418849a326fd1d9287801fa2d86091db4f9611f60781da6d236f64cd4", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, optional: false]}]}, + "db_connection": {:hex, :db_connection, "1.1.1", "f9d246e8f65b9490945cf7360875eee18fcec9a0115207603215eb1fd94c39ef", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]}, + "decimal": {:hex, :decimal, "1.3.1", "157b3cedb2bfcb5359372a7766dd7a41091ad34578296e951f58a946fcab49c6", [:mix], []}, + "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]}, "elixir_xml_to_map": {:git, "https://github.com/retgoat/elixir-xml-to-map.git", "c5171c8173ec72fb35d306eb3b8fb6e03741a4e2", [tag: "0.1.2"]}, - "envy": {:hex, :envy, "1.0.0", "d8385715b908f3972f85cbffa0ffbd36fec017601258bcb6be9003c11ece3e75", [:mix], [], "hexpm"}, - "erlsom": {:hex, :erlsom, "1.4.1", "53dbacf35adfea6f0714fd0e4a7b0720d495e88c5e24e12c5dc88c7b62bd3e49", [:rebar3], [], "hexpm"}, - "espec": {:hex, :espec, "1.3.2", "20c96d580df671860bd8e7de1523be9ead34bbdca4912689a54f295add56d683", [:mix], [{:meck, "0.8.4", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"}, - "ex_aws": {:hex, :ex_aws, "1.1.1", "58c46d9a0b395d7cbb065424c109feb6a7385907c12a91d3032a1e8baf3d6220", [:mix], [{:configparser_ex, "~> 0.2.1", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.0.6", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"}, - "ex_machina": {:hex, :ex_machina, "2.0.0", "ec284c6f57233729cea9319e083f66e613e82549f78eccdb2059aeba5d0df9f3", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, - "exfswatch": {:hex, :exfswatch, "0.2.1", "3f34190e2750ae6d924ce53729bb40e050dd8a08fee683847e6ddfa03ea5429f", [:mix], [{:fs, "~> 0.9", [hex: :fs, repo: "hexpm", optional: false]}], "hexpm"}, - "exsync": {:hex, :exsync, "0.1.3", "84c66a4f60505d1baeb8a79cbf713ae98276f23b4bc7d676c6cb2d663fced5f3", [:mix], [{:exfswatch, "~> 0.2.1", [hex: :exfswatch, repo: "hexpm", optional: false]}], "hexpm"}, - "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], [], "hexpm"}, - "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], [], "hexpm"}, - "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "4.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.0.1", "2572e7122c78ab7e57b613e7c7f5e42bf9b3c25e430e32f23f1413d86db8a0af", [:mix], [{:mochiweb, "~> 2.12.2", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, - "httpoison": {:hex, :httpoison, "0.11.1", "d06c571274c0e77b6cc50e548db3fd7779f611fbed6681fd60a331f66c143a0b", [:mix], [{:hackney, "~> 1.7.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, - "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], [], "hexpm"}, - "inflex": {:hex, :inflex, "1.7.0", "4466a34b7d8e871d8164619ba0f3b8410ec782e900f0ae1d3d27a5875a29532e", [:mix], [], "hexpm"}, - "json_web_token": {:hex, :json_web_token, "0.2.8", "c79d4c36cfd6f205be7099713e67d6057bde64ee9c64363f9001e3de86de703c", [:mix], [{:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, - "maru": {:hex, :maru, "0.11.3", "0bf2f26955430c4878dab91fe44aeb8b3aaed338b4f6ffd0729ea119284c374d", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, - "meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], [], "hexpm"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, - "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], [], "hexpm"}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, - "mochiweb": {:hex, :mochiweb, "2.12.2", "80804ad342afa3d7f3524040d4eed66ce74b17a555de454ac85b07c479928e46", [:make, :rebar], [], "hexpm"}, + "envy": {:hex, :envy, "1.0.0", "d8385715b908f3972f85cbffa0ffbd36fec017601258bcb6be9003c11ece3e75", [:mix], []}, + "erlsom": {:hex, :erlsom, "1.4.1", "53dbacf35adfea6f0714fd0e4a7b0720d495e88c5e24e12c5dc88c7b62bd3e49", [:rebar3], []}, + "espec": {:hex, :espec, "1.3.2", "20c96d580df671860bd8e7de1523be9ead34bbdca4912689a54f295add56d683", [:mix], [{:meck, "0.8.4", [hex: :meck, optional: false]}]}, + "ex_aws": {:hex, :ex_aws, "1.1.1", "58c46d9a0b395d7cbb065424c109feb6a7385907c12a91d3032a1e8baf3d6220", [:mix], [{:configparser_ex, "~> 0.2.1", [hex: :configparser_ex, optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1", [hex: :hackney, optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, optional: true]}, {:xml_builder, "~> 0.0.6", [hex: :xml_builder, optional: true]}]}, + "ex_machina": {:hex, :ex_machina, "2.0.0", "ec284c6f57233729cea9319e083f66e613e82549f78eccdb2059aeba5d0df9f3", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, optional: true]}]}, + "exfswatch": {:hex, :exfswatch, "0.2.1", "3f34190e2750ae6d924ce53729bb40e050dd8a08fee683847e6ddfa03ea5429f", [:mix], [{:fs, "~> 0.9", [hex: :fs, optional: false]}]}, + "exsync": {:hex, :exsync, "0.1.3", "84c66a4f60505d1baeb8a79cbf713ae98276f23b4bc7d676c6cb2d663fced5f3", [:mix], [{:exfswatch, "~> 0.2.1", [hex: :exfswatch, optional: false]}]}, + "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []}, + "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], []}, + "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, + "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.0.1", "2572e7122c78ab7e57b613e7c7f5e42bf9b3c25e430e32f23f1413d86db8a0af", [:mix], [{:mochiweb, "~> 2.12.2", [hex: :mochiweb, optional: false]}]}, + "httpoison": {:hex, :httpoison, "0.11.1", "d06c571274c0e77b6cc50e548db3fd7779f611fbed6681fd60a331f66c143a0b", [:mix], [{:hackney, "~> 1.7.0", [hex: :hackney, optional: false]}]}, + "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []}, + "inflex": {:hex, :inflex, "1.7.0", "4466a34b7d8e871d8164619ba0f3b8410ec782e900f0ae1d3d27a5875a29532e", [:mix], []}, + "json_web_token": {:hex, :json_web_token, "0.2.8", "c79d4c36cfd6f205be7099713e67d6057bde64ee9c64363f9001e3de86de703c", [:mix], [{:poison, "~> 3.1", [hex: :poison, optional: false]}]}, + "maru": {:hex, :maru, "0.11.3", "0bf2f26955430c4878dab91fe44aeb8b3aaed338b4f6ffd0729ea119284c374d", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: false]}, {:plug, "~> 1.0", [hex: :plug, optional: false]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}]}, + "meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], []}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, + "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, + "mochiweb": {:hex, :mochiweb, "2.12.2", "80804ad342afa3d7f3524040d4eed66ce74b17a555de454ac85b07c479928e46", [:make, :rebar], []}, "mws_client": {:git, "https://github.com/FoxComm/elixir-amazon-mws-client.git", "145210296b12d0aaa5ee6cabb21c6a79fea6e96d", []}, - "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [:mix], [], "hexpm"}, - "plug": {:hex, :plug, "1.3.3", "d9be189924379b4e9d470caef87380d09549aea1ceafe6a0d41292c8c317c923", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, - "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, - "postgrex": {:hex, :postgrex, "0.13.2", "2b88168fc6a5456a27bfb54ccf0ba4025d274841a7a3af5e5deb1b755d95154e", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, - "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, - "timex": {:hex, :timex, "3.1.13", "48b33162e3ec33e9a08fb5f98e3f3c19c3e328dded3156096c1969b77d33eef0", [:mix], [{:combine, "~> 0.7", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, - "timex_ecto": {:hex, :timex_ecto, "3.1.1", "37d54f6879d96a6789bb497296531cfb853631de78e152969d95cff03c1368dd", [:mix], [{:ecto, "~> 2.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:timex, "~> 3.0", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm"}, - "tzdata": {:hex, :tzdata, "0.5.11", "3d5469a9f46bdf4a8760333dbdabdcc4751325035c454b10521f71e7c611ae50", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}} + "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [:mix], []}, + "plug": {:hex, :plug, "1.3.3", "d9be189924379b4e9d470caef87380d09549aea1ceafe6a0d41292c8c317c923", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]}, + "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []}, + "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], []}, + "postgrex": {:hex, :postgrex, "0.13.2", "2b88168fc6a5456a27bfb54ccf0ba4025d274841a7a3af5e5deb1b755d95154e", [:mix], [{:connection, "~> 1.0", [hex: :connection, optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}]}, + "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, + "timex": {:hex, :timex, "3.1.13", "48b33162e3ec33e9a08fb5f98e3f3c19c3e328dded3156096c1969b77d33eef0", [:mix], [{:combine, "~> 0.7", [hex: :combine, optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, optional: false]}]}, + "timex_ecto": {:hex, :timex_ecto, "3.1.1", "37d54f6879d96a6789bb497296531cfb853631de78e152969d95cff03c1368dd", [:mix], [{:ecto, "~> 2.1.0", [hex: :ecto, optional: false]}, {:timex, "~> 3.0", [hex: :timex, optional: false]}]}, + "tzdata": {:hex, :tzdata, "0.5.11", "3d5469a9f46bdf4a8760333dbdabdcc4751325035c454b10521f71e7c611ae50", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, optional: false]}]}} From a6e0b6a9397378c4a278dd6a7f372877cb41b7ef Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Tue, 2 May 2017 17:58:22 +0300 Subject: [PATCH 55/93] bump sql versions --- ...search_view_rules.sql => V4.118__coupon_search_view_rules.sql} | 0 ..._create_amazon_orders.sql => V4.119__create_amazon_orders.sql} | 0 ...r.sql => V4.120__alter_assignment_domain_add_amazon_order.sql} | 0 ...V4.121__add_orders_search_view_id_seq_and_change_triggers.sql} | 0 ...on_orders_table.sql => V4.122__change_amazon_orders_table.sql} | 0 ...iew.sql => V4.123__drop_order_id_from_returns_search_view.sql} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename phoenix-scala/sql/{V4.117__coupon_search_view_rules.sql => V4.118__coupon_search_view_rules.sql} (100%) rename phoenix-scala/sql/{V4.118__create_amazon_orders.sql => V4.119__create_amazon_orders.sql} (100%) rename phoenix-scala/sql/{V4.119__alter_assignment_domain_add_amazon_order.sql => V4.120__alter_assignment_domain_add_amazon_order.sql} (100%) rename phoenix-scala/sql/{V4.120__add_orders_search_view_id_seq_and_change_triggers.sql => V4.121__add_orders_search_view_id_seq_and_change_triggers.sql} (100%) rename phoenix-scala/sql/{V4.121__change_amazon_orders_table.sql => V4.122__change_amazon_orders_table.sql} (100%) rename phoenix-scala/sql/{V4.122__drop_order_id_from_returns_search_view.sql => V4.123__drop_order_id_from_returns_search_view.sql} (100%) diff --git a/phoenix-scala/sql/V4.117__coupon_search_view_rules.sql b/phoenix-scala/sql/V4.118__coupon_search_view_rules.sql similarity index 100% rename from phoenix-scala/sql/V4.117__coupon_search_view_rules.sql rename to phoenix-scala/sql/V4.118__coupon_search_view_rules.sql diff --git a/phoenix-scala/sql/V4.118__create_amazon_orders.sql b/phoenix-scala/sql/V4.119__create_amazon_orders.sql similarity index 100% rename from phoenix-scala/sql/V4.118__create_amazon_orders.sql rename to phoenix-scala/sql/V4.119__create_amazon_orders.sql diff --git a/phoenix-scala/sql/V4.119__alter_assignment_domain_add_amazon_order.sql b/phoenix-scala/sql/V4.120__alter_assignment_domain_add_amazon_order.sql similarity index 100% rename from phoenix-scala/sql/V4.119__alter_assignment_domain_add_amazon_order.sql rename to phoenix-scala/sql/V4.120__alter_assignment_domain_add_amazon_order.sql diff --git a/phoenix-scala/sql/V4.120__add_orders_search_view_id_seq_and_change_triggers.sql b/phoenix-scala/sql/V4.121__add_orders_search_view_id_seq_and_change_triggers.sql similarity index 100% rename from phoenix-scala/sql/V4.120__add_orders_search_view_id_seq_and_change_triggers.sql rename to phoenix-scala/sql/V4.121__add_orders_search_view_id_seq_and_change_triggers.sql diff --git a/phoenix-scala/sql/V4.121__change_amazon_orders_table.sql b/phoenix-scala/sql/V4.122__change_amazon_orders_table.sql similarity index 100% rename from phoenix-scala/sql/V4.121__change_amazon_orders_table.sql rename to phoenix-scala/sql/V4.122__change_amazon_orders_table.sql diff --git a/phoenix-scala/sql/V4.122__drop_order_id_from_returns_search_view.sql b/phoenix-scala/sql/V4.123__drop_order_id_from_returns_search_view.sql similarity index 100% rename from phoenix-scala/sql/V4.122__drop_order_id_from_returns_search_view.sql rename to phoenix-scala/sql/V4.123__drop_order_id_from_returns_search_view.sql From 2316bc8c1990fe82d38567f482db77ebaa6c801c Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 2 May 2017 23:57:33 +0700 Subject: [PATCH 56/93] Change phoenix url --- hyperion/lib/hyperion/phoenix_scala/client.ex | 36 +++++++++---------- .../dev/marathon/templates/hyperion.json | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/hyperion/lib/hyperion/phoenix_scala/client.ex b/hyperion/lib/hyperion/phoenix_scala/client.ex index 150fd20ed6..b888bd07d9 100644 --- a/hyperion/lib/hyperion/phoenix_scala/client.ex +++ b/hyperion/lib/hyperion/phoenix_scala/client.ex @@ -5,7 +5,6 @@ defmodule Hyperion.PhoenixScala.Client do @moduledoc """ Provides simple access to Phoenix-scala API """ - def process_url(path) do {:ok, base_uri} = Application.fetch_env(:hyperion, :phoenix_url) base_uri <> path @@ -22,17 +21,17 @@ defmodule Hyperion.PhoenixScala.Client do """ def login do params = login_params() - case post("/api/v1/public/login", params, make_request_headers()) do - {_, %{body: _, headers: headers, status_code: 200}} -> Keyword.take(headers, ["Jwt"]) |> hd |> elem(1) + case post("/v1/public/login", params, make_request_headers()) do + {_, %{body: _, headers: headers, status_code: 200}} -> Keyword.take(headers, ["JWT"]) |> hd |> elem(1) {_, %{body: resp, headers: _, status_code: _}} -> raise %PhoenixError{message: hd(resp["errors"])} end end def safe_login() do params = login_params() - case post("/api/v1/public/login", params, make_request_headers()) do - {_, %{body: _, headers: headers, status_code: 200}} -> Keyword.take(headers, ["Jwt"]) |> hd |> elem(1) - {:ok, %{body: body, headers: headers, status_code: 502}} -> + case post("/v1/public/login", params, make_request_headers()) do + {_, %{body: _, headers: headers, status_code: 200}} -> Keyword.take(headers, ["JWT"]) |> hd |> elem(1) + {:ok, %{body: body, headers: _, status_code: 502}} -> Logger.error "Some error occured on login: #{body}" nil {:error, %HTTPoison.Error{id: _, reason: reason}} -> @@ -45,7 +44,7 @@ defmodule Hyperion.PhoenixScala.Client do Returns product by id """ def get_product(product_id, token, ctx \\ "default") do - get("/api/v1/products/#{ctx}/#{product_id}", make_request_headers(token)) + get("/v1/products/#{ctx}/#{product_id}", make_request_headers(token)) |> parse_response(token) end @@ -53,16 +52,17 @@ defmodule Hyperion.PhoenixScala.Client do Returns sku by SKU-CODE """ def get_sku(sku_code, token, ctx \\ "default") do - get("/api/v1/skus/#{ctx}/#{sku_code}", make_request_headers(token)) + get("/v1/skus/#{ctx}/#{sku_code}", make_request_headers(token)) |> parse_response(token) end @doc """ Returns all non archived skus + FIXME!!! """ def get_all_skus(token, size \\ 50) do q = %{query: %{bool: %{filter: [%{missing: %{field: "archivedAt"}}]}}} - post("/api/search/admin/sku_search_view/_search?size=#{size}", Poison.encode!(q), make_request_headers(token)) + post("/admin_1/sku_search_view/_search?size=#{size}", Poison.encode!(q), make_request_headers(token)) |> parse_response(token) end @@ -70,7 +70,7 @@ defmodule Hyperion.PhoenixScala.Client do Return all countries from Phoenix """ def get_countries(token) do - get("/api/v1/public/countries", make_request_headers(token)) + get("/v1/public/countries", make_request_headers(token)) |> parse_response(token) end @@ -79,18 +79,18 @@ defmodule Hyperion.PhoenixScala.Client do """ def get_countries do token = login() - get("/api/v1/public/countries", make_request_headers(token)) + get("/v1/public/countries", make_request_headers(token)) |> parse_response(token) end def get_regions(country_id) do token = login() - get("/api/v1/public/countries/#{country_id}", make_request_headers(token)) + get("/v1/public/countries/#{country_id}", make_request_headers(token)) |> parse_response(token) end def get_regions(country_id, token) do - get("/api/v1/public/countries/#{country_id}", make_request_headers(token)) + get("/v1/public/countries/#{country_id}", make_request_headers(token)) |> parse_response(token) end @@ -99,7 +99,7 @@ defmodule Hyperion.PhoenixScala.Client do """ def create_customer(payload, token) do params = Poison.encode!(%{name: payload["BuyerName"], email: payload["BuyerEmail"]}) - {_, resp} = post("/api/v1/customers", params, make_request_headers(token)) + {_, resp} = post("/v1/customers", params, make_request_headers(token)) case resp.status_code do # status_code = 400 means customer already exists code when code in [200, 400] -> payload @@ -120,7 +120,7 @@ defmodule Hyperion.PhoenixScala.Client do scope: Hyperion.JwtAuth.get_scope(token), customerName: payload["BuyerName"], customerEmail: payload["BuyerEmail"]}) - {st, resp} = post("/api/v1/amazon_orders", params, make_request_headers(token)) + {st, resp} = post("/v1/amazon_orders", params, make_request_headers(token)) case resp.status_code do code when code in [200, 201] -> parse_response({st, resp}, token) _ -> @@ -141,7 +141,7 @@ defmodule Hyperion.PhoenixScala.Client do def get_credentials(token) when token == nil, do: nil def get_credentials(token) do - {_, resp} = get("/api/v1/plugins/settings/AmazonMWS/detailed", make_request_headers(token)) + {_, resp} = get("/v1/plugins/settings/AmazonMWS/detailed", make_request_headers(token)) case resp.status_code do code when code in [200, 201] -> resp.body["settings"] @@ -154,7 +154,7 @@ defmodule Hyperion.PhoenixScala.Client do Not raising an error if no credentials set """ def safe_get_credentials(token) do - {_, resp} = get("/api/v1/plugins/settings/AmazonMWS/detailed", make_request_headers(token)) + {_, resp} = get("/v1/plugins/settings/AmazonMWS/detailed", make_request_headers(token)) case resp.status_code do code when code in [200, 201] -> resp.body["settings"] @@ -179,7 +179,7 @@ defmodule Hyperion.PhoenixScala.Client do %{"default" => "", "name" => "mws_auth_token", "title" => "Amazon MWS Auth Token", "type" => "string"}] } - post("/api/v1/plugins/register", Poison.encode!(params), make_request_headers(token)) + post("/v1/plugins/register", Poison.encode!(params), make_request_headers(token)) |> parse_response(token) end diff --git a/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json b/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json index db853839b8..5a74652760 100644 --- a/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json +++ b/tabernacle/ansible/roles/dev/marathon/templates/hyperion.json @@ -24,7 +24,7 @@ "PHOENIX_USER": "{{phoenix_api_user}}", "PHOENIX_PASSWORD": "{{phoenix_api_password}}", "PHOENIX_ORG": "{{phoenix_api_user_org}}", - "PHOENIX_URL": "https://{{storefront_server_name}}", + "PHOENIX_URL": "http://{{phoenix_server}}", "PUBLIC_KEY": "{{public_keys_dest_dir}}/public_key.pem", "PUSH_CHECK_INTERVAL": "{{hyperion_push_check_interval}}", "ORDERS_FETCH_INTERVAL" : "{{hyperion_orders_fetch_interval}}", From bbc2c2cc71adcd6007050aad2aee2fe155b8ca76 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Wed, 3 May 2017 00:11:16 +0700 Subject: [PATCH 57/93] Remove unused func --- hyperion/lib/hyperion/phoenix_scala/client.ex | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/hyperion/lib/hyperion/phoenix_scala/client.ex b/hyperion/lib/hyperion/phoenix_scala/client.ex index b888bd07d9..d6f2b17d82 100644 --- a/hyperion/lib/hyperion/phoenix_scala/client.ex +++ b/hyperion/lib/hyperion/phoenix_scala/client.ex @@ -56,16 +56,6 @@ defmodule Hyperion.PhoenixScala.Client do |> parse_response(token) end - @doc """ - Returns all non archived skus - FIXME!!! - """ - def get_all_skus(token, size \\ 50) do - q = %{query: %{bool: %{filter: [%{missing: %{field: "archivedAt"}}]}}} - post("/admin_1/sku_search_view/_search?size=#{size}", Poison.encode!(q), make_request_headers(token)) - |> parse_response(token) - end - @doc """ Return all countries from Phoenix """ From 2103073f67b40b04993bfa7de7f7b8727cd008a9 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Wed, 3 May 2017 17:34:31 +0700 Subject: [PATCH 58/93] Update categories csv --- .../categories/clothes_accessories_categories.csv | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/hyperion/priv/seeds/categories/clothes_accessories_categories.csv b/hyperion/priv/seeds/categories/clothes_accessories_categories.csv index 6a6c6f9354..b44e379e23 100644 --- a/hyperion/priv/seeds/categories/clothes_accessories_categories.csv +++ b/hyperion/priv/seeds/categories/clothes_accessories_categories.csv @@ -1222,7 +1222,6 @@ 6796859011,"Clothing, Shoes & Jewelry/Men/Shoes/Work & Safety/Fire & Safety",department_name:mens AND item_type_keyword:fire-and-safety-shoes,See Available Refinements 6796861011,"Clothing, Shoes & Jewelry/Men/Shoes/Work & Safety/Health Care & Food Service",department_name:mens AND item_type_keyword:health-care-and-food-service-shoes,See Available Refinements 6796860011,"Clothing, Shoes & Jewelry/Men/Shoes/Work & Safety/Industrial & Construction",department_name:mens AND item_type_keyword:industrial-and-construction-shoes,See Available Refinements -11312338011,"Clothing, Shoes & Jewelry/Men/Shoes/Work & Safety/Medical",department_name:mens AND item_type_keyword:medical-professional-shoes,See Available Refinements 6796862011,"Clothing, Shoes & Jewelry/Men/Shoes/Work & Safety/Military & Tactical",department_name:mens AND item_type_keyword:military-and-tactical-boots,See Available Refinements 6796863011,"Clothing, Shoes & Jewelry/Men/Shoes/Work & Safety/Uniform Dress Shoes",department_name:mens AND item_type_keyword:uniform-dress-shoes,See Available Refinements 7581669011,"Clothing, Shoes & Jewelry/Men/Shops",, @@ -1322,7 +1321,6 @@ 6567202011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Clothing/Medical/Scrub Jackets",department_name:mens AND item_type_keyword:medical-scrubs-jackets,See Available Refinements 6567203011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Clothing/Medical/Scrub Sets",department_name:mens AND item_type_keyword:medical-scrubs-apparel-sets,See Available Refinements 6567204011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Clothing/Medical/Scrub Tops",department_name:mens AND item_type_keyword:medical-scrubs-shirts,See Available Refinements -11316162011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Clothing/Medical/Shoes",department_name:mens AND item_type_keyword:medical-shoes, 6567205011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Clothing/Medical/T-Shirts",department_name:mens AND item_type_keyword:medical-apparel-t-shirts,See Available Refinements 2492606011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Clothing/Military",department_name:mens AND item_type_keyword:military-apparel, 2492612011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Clothing/Military/Accessories",department_name:mens AND item_type_keyword:military-apparel-accessories, @@ -1345,7 +1343,6 @@ 6796859011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Shoes/Fire & Safety",department_name:mens AND item_type_keyword:fire-and-safety-shoes,See Available Refinements 6796861011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Shoes/Health Care & Food Service",department_name:mens AND item_type_keyword:health-care-and-food-service-shoes,See Available Refinements 6796860011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Shoes/Industrial & Construction",department_name:mens AND item_type_keyword:industrial-and-construction-shoes,See Available Refinements -11312338011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Shoes/Medical",department_name:mens AND item_type_keyword:medical-professional-shoes,See Available Refinements 6796862011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Shoes/Military & Tactical",department_name:mens AND item_type_keyword:military-and-tactical-boots,See Available Refinements 6796863011,"Clothing, Shoes & Jewelry/Men/Shops/Uniforms, Work & Safety/Shoes/Uniform Dress Shoes",department_name:mens AND item_type_keyword:uniform-dress-shoes,See Available Refinements 6358539011,"Clothing, Shoes & Jewelry/Men/Watches",, @@ -1954,7 +1951,6 @@ 6567202011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Men/Scrub Jackets",department_name:mens AND item_type_keyword:medical-scrubs-jackets,See Available Refinements 6567203011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Men/Scrub Sets",department_name:mens AND item_type_keyword:medical-scrubs-apparel-sets,See Available Refinements 6567204011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Men/Scrub Tops",department_name:mens AND item_type_keyword:medical-scrubs-shirts,See Available Refinements -11316162011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Men/Shoes",department_name:mens AND item_type_keyword:medical-shoes, 6567205011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Men/T-Shirts",department_name:mens AND item_type_keyword:medical-apparel-t-shirts,See Available Refinements 6567206011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Women",, 6567208011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Women/Lab Coats",department_name:womens AND item_type_keyword:medical-lab-coats,See Available Refinements @@ -1963,7 +1959,6 @@ 6567211011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Women/Scrub Jackets",department_name:womens AND item_type_keyword:medical-scrubs-jackets,See Available Refinements 6567212011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Women/Scrub Sets",department_name:womens AND item_type_keyword:medical-scrubs-apparel-sets,See Available Refinements 6567213011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Women/Scrub Tops",department_name:womens AND item_type_keyword:medical-scrubs-shirts,See Available Refinements -11316163011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Women/Shoes",department_name:womens AND item_type_keyword:medical-shoes, 6567214011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Medical/Women/T-Shirts",department_name:womens AND item_type_keyword:medical-apparel-t-shirts,See Available Refinements 1283420011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Military",, 2492606011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Clothing/Military/Men",department_name:mens AND item_type_keyword:military-apparel, @@ -2092,14 +2087,12 @@ 6796859011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Men/Fire & Safety",department_name:mens AND item_type_keyword:fire-and-safety-shoes,See Available Refinements 6796861011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Men/Health Care & Food Service",department_name:mens AND item_type_keyword:health-care-and-food-service-shoes,See Available Refinements 6796860011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Men/Industrial & Construction",department_name:mens AND item_type_keyword:industrial-and-construction-shoes,See Available Refinements -11312338011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Men/Medical",department_name:mens AND item_type_keyword:medical-professional-shoes,See Available Refinements 6796862011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Men/Military & Tactical",department_name:mens AND item_type_keyword:military-and-tactical-boots,See Available Refinements 6796863011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Men/Uniform Dress Shoes",department_name:mens AND item_type_keyword:uniform-dress-shoes,See Available Refinements 679442011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Women",,See Available Refinements 6796864011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Women/Fire & Safety",department_name:womens AND item_type_keyword:fire-and-safety-shoes,See Available Refinements 6796865011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Women/Health Care & Food Service",department_name:womens AND item_type_keyword:health-care-and-food-service-shoes,See Available Refinements 6796866011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Women/Industrial & Construction",department_name:womens AND item_type_keyword:industrial-and-construction-shoes,See Available Refinements -11312339011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Women/Medical",department_name:womens AND item_type_keyword:medical-professional-shoes,See Available Refinements 6796867011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Women/Military & Tactical",department_name:womens AND item_type_keyword:military-and-tactical-boots,See Available Refinements 6796868011,"Clothing, Shoes & Jewelry/Uniforms, Work & Safety/Shoes/Women/Uniform Dress Shoes",department_name:womens AND item_type_keyword:uniform-dress-shoes,See Available Refinements 7147440011,"Clothing, Shoes & Jewelry/Women",, @@ -2599,7 +2592,6 @@ 6796864011,"Clothing, Shoes & Jewelry/Women/Shoes/Work & Safety/Fire & Safety",department_name:womens AND item_type_keyword:fire-and-safety-shoes,See Available Refinements 6796865011,"Clothing, Shoes & Jewelry/Women/Shoes/Work & Safety/Health Care & Food Service",department_name:womens AND item_type_keyword:health-care-and-food-service-shoes,See Available Refinements 6796866011,"Clothing, Shoes & Jewelry/Women/Shoes/Work & Safety/Industrial & Construction",department_name:womens AND item_type_keyword:industrial-and-construction-shoes,See Available Refinements -11312339011,"Clothing, Shoes & Jewelry/Women/Shoes/Work & Safety/Medical",department_name:womens AND item_type_keyword:medical-professional-shoes,See Available Refinements 6796867011,"Clothing, Shoes & Jewelry/Women/Shoes/Work & Safety/Military & Tactical",department_name:womens AND item_type_keyword:military-and-tactical-boots,See Available Refinements 6796868011,"Clothing, Shoes & Jewelry/Women/Shoes/Work & Safety/Uniform Dress Shoes",department_name:womens AND item_type_keyword:uniform-dress-shoes,See Available Refinements 7581668011,"Clothing, Shoes & Jewelry/Women/Shops",, @@ -2965,7 +2957,6 @@ 6567211011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Clothing/Medical/Scrub Jackets",department_name:womens AND item_type_keyword:medical-scrubs-jackets,See Available Refinements 6567212011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Clothing/Medical/Scrub Sets",department_name:womens AND item_type_keyword:medical-scrubs-apparel-sets,See Available Refinements 6567213011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Clothing/Medical/Scrub Tops",department_name:womens AND item_type_keyword:medical-scrubs-shirts,See Available Refinements -11316163011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Clothing/Medical/Shoes",department_name:womens AND item_type_keyword:medical-shoes, 6567214011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Clothing/Medical/T-Shirts",department_name:womens AND item_type_keyword:medical-apparel-t-shirts,See Available Refinements 2492613011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Clothing/Military",department_name:womens AND item_type_keyword:military-apparel, 2492619011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Clothing/Military/Accessories",department_name:womens AND item_type_keyword:military-apparel-accessories, @@ -2988,7 +2979,6 @@ 6796864011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Shoes/Fire & Safety",department_name:womens AND item_type_keyword:fire-and-safety-shoes,See Available Refinements 6796865011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Shoes/Health Care & Food Service",department_name:womens AND item_type_keyword:health-care-and-food-service-shoes,See Available Refinements 6796866011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Shoes/Industrial & Construction",department_name:womens AND item_type_keyword:industrial-and-construction-shoes,See Available Refinements -11312339011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Shoes/Medical",department_name:womens AND item_type_keyword:medical-professional-shoes,See Available Refinements 6796867011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Shoes/Military & Tactical",department_name:womens AND item_type_keyword:military-and-tactical-boots,See Available Refinements 6796868011,"Clothing, Shoes & Jewelry/Women/Shops/Uniforms, Work & Safety/Shoes/Uniform Dress Shoes",department_name:womens AND item_type_keyword:uniform-dress-shoes,See Available Refinements 6358543011,"Clothing, Shoes & Jewelry/Women/Watches",, From d5d70f53870eea15bc4aa3efcabfdcdb5f90e857 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 4 May 2017 15:34:57 +0700 Subject: [PATCH 59/93] Workaround for images --- hyperion/lib/hyperion/amazon/amazon.ex | 79 +++++++++++++------ .../amazon/templates/submit_images.ex | 48 ++++------- .../seeds/clothes_accessories_categories.exs | 2 + hyperion/spec/factories/product_factory.ex | 71 ++++++++++++----- hyperion/spec/lib/amazon/amazon_spec.exs | 2 +- .../templates/template_builder_spec.exs | 25 ++++-- 6 files changed, 144 insertions(+), 83 deletions(-) diff --git a/hyperion/lib/hyperion/amazon/amazon.ex b/hyperion/lib/hyperion/amazon/amazon.ex index 23a65eaf02..b8d5ea9ace 100644 --- a/hyperion/lib/hyperion/amazon/amazon.ex +++ b/hyperion/lib/hyperion/amazon/amazon.ex @@ -249,25 +249,53 @@ defmodule Hyperion.Amazon do end - # gets the albums and images for skus, - # adds the SKU for matching - # renders main, pt and swatch images + @doc """ + Gets the albums and images for amazon enabled skus, + adds the SKU for matching + renders main, pt and swatch images + """ + # defp process_images(response) do + # r = response.body + # amazon_skus = Enum.filter(r["skus"], fn (sku) -> + # sku["attributes"]["amazon"]["v"] == true + # end) + + # case amazon_skus do + # [] -> raise "No images for product #{r["id"]}" + # _ -> amazon_skus + # end + # |> Enum.flat_map(fn(sku)-> + # images = Enum.flat_map(sku["albums"], fn(album) -> + # Enum.map(album["images"], fn(image) -> + # [code: sku["attributes"]["code"]["v"], src: image["src"], type: album["name"]] + # end) + # end) + # end) + # |> Enum.with_index(1) + + # end + defp process_images(response) do r = response.body - albums = Enum.map(r["skus"], fn(sku)-> - Enum.map(sku["albums"], fn(album) -> - {String.to_atom(album["name"]), album["images"]} - end) - end) |> Enum.reject(fn(list) -> list == [] end) + amazon_skus = Enum.filter(r["skus"], fn (sku) -> + sku["attributes"]["amazon"]["v"] == true + end) - case albums do + case amazon_skus do [] -> raise "No images for product #{r["id"]}" - _ -> Enum.map(r["skus"], fn(x)-> [albums: hd(albums), code: x["attributes"]["code"]["v"]] end) + _ -> amazon_skus end - |> Enum.flat_map(fn(product) -> - main = render_main_section(hd(product[:albums]), product[:code]) - [main, render_swatch_section(product[:albums][:swatches], product[:code], Enum.count(main))] - end) |> Enum.reject(fn el -> el == nil end) + |> Enum.map(fn(sku)-> + images = Enum.map(sku["albums"], fn(album) -> + {String.to_atom(album["name"]), album["images"]} + end) + [albums: images, code: sku["attributes"]["code"]["v"]] + end) + |> Enum.map(fn(sku) -> + main = render_main_section(hd(sku[:albums]), sku[:code], 1) + [main, render_swatch_section(sku[:albums][:swatches], sku[:code], Enum.count(main))] + end) + |> List.flatten |> Enum.reject(fn el -> el == nil end) |> Enum.with_index(1) end # renders main images section as: @@ -276,19 +304,23 @@ defmodule Hyperion.Amazon do # {[type: "PT", # location: "http:", id: 1], # 2}], - defp render_main_section({_, [h|[]]}, sku) do - [{[sku: sku, type: "Main", location: String.replace(h["src"], "https", "http")], 1}] + defp render_main_section({_, [h|t]}, sku, idx) when t == [] do + IO.puts("t is []") + # [{[sku: sku, type: "Main", location: String.replace(h["src"], "https", "http")], idx}] + [{sku, "Main", String.replace(h["src"], "https", "http")}] end - defp render_main_section({_, [h|t]}, sku) do - main = [sku: sku, type: "Main", location: String.replace(h["src"], "https", "http")] + defp render_main_section({_, [h|t]}, sku, idx) do + # main = [sku: sku, type: "Main", location: String.replace(h["src"], "https", "http")] + main = {sku, "Main", String.replace(h["src"], "https", "http")} pt = Enum.with_index(t, 1) - |> Enum.flat_map(fn({img, idx}) -> - [sku: sku, type: "PT", location: String.replace(img["src"], "https", "http"), id: idx] + |> Enum.map(fn({img, idx}) -> + # [sku: sku, type: "PT", location: String.replace(img["src"], "https", "http"), id: idx] + {sku, "PT", String.replace(img["src"], "https", "http"), idx} end) [main, pt] - |> Enum.with_index(1) + # |> Enum.with_index(idx) end def render_swatch_section(nil, _, _), do: nil @@ -298,7 +330,8 @@ defmodule Hyperion.Amazon do def render_swatch_section(list, sku, initial) do Enum.with_index(list, initial + 1) |> Enum.map(fn {image, idx} -> - [sku: sku, type: "Swatch", location: String.replace(image["src"], "https", "http"), idx: idx] + # [sku: sku, type: "Swatch", location: String.replace(image["src"], "https", "http")] + {sku, "Swatch", String.replace(image["src"], "https", "http")} end) end @@ -357,7 +390,7 @@ defmodule Hyperion.Amazon do # assign variants options to associated sku defp process_variants(variants) do func = fn var -> - {String.to_atom(var["attributes"]["name"]["v"]), atomize_keys(var["values"])} + {format_string(var["attributes"]["name"]["v"]), atomize_keys(var["values"])} end props = Enum.map(variants, func) diff --git a/hyperion/lib/hyperion/amazon/templates/submit_images.ex b/hyperion/lib/hyperion/amazon/templates/submit_images.ex index 72a72fc069..3ddad42d61 100644 --- a/hyperion/lib/hyperion/amazon/templates/submit_images.ex +++ b/hyperion/lib/hyperion/amazon/templates/submit_images.ex @@ -3,7 +3,6 @@ defmodule Hyperion.Amazon.Templates.SubmitImages do Renders whole images feed based on albums More info here https://sellercentral.amazon.com/gp/help/200386840?ie=UTF8&*Version*=1&*entries*=0& """ - def template_string do """ @@ -14,59 +13,40 @@ defmodule Hyperion.Amazon.Templates.SubmitImages do <%= seller_id %> ProductImage - <%= Hyperion.Amazon.Templates.SubmitImages.render_main_image(hd(images)) %> - <%= Hyperion.Amazon.Templates.SubmitImages.render_pt_images(hd(images)) %> - <%= Hyperion.Amazon.Templates.SubmitImages.render_swatches(tl(images)) %> + <%= for image <- images do %> + <%= Hyperion.Amazon.Templates.SubmitImages.render_any_image(image) %> + <% end %> """ end - def render_main_image([{main, message_id}|_]) do + def render_any_image({n, idx}) when n == nil, do: "" + + def render_any_image({{sku, type, src}, message_id}) do """ #{message_id} Update - #{main[:sku]} - Main - #{main[:location]} + #{sku} + #{type} + #{src} """ end - - def render_pt_images([_|pt_images]) do - for {item, idx} <- pt_images do - """ - - #{idx} - Update - - #{item[:sku]} - #{item[:type]}#{item[:id]} - #{item[:location]} - - - """ - end - end - - def render_swatches([]), do: "" - - def render_swatches([swatches|_]) do - for swatch <- swatches do + def render_any_image({{sku, type, src, index}, message_id}) do """ - #{swatch[:idx]} + #{message_id} Update - #{swatch[:sku]} - #{swatch[:type]} - #{swatch[:location]} + #{sku} + #{type}#{index} + #{src} """ - end end end diff --git a/hyperion/priv/seeds/clothes_accessories_categories.exs b/hyperion/priv/seeds/clothes_accessories_categories.exs index 29e1a44a2c..f725519a03 100644 --- a/hyperion/priv/seeds/clothes_accessories_categories.exs +++ b/hyperion/priv/seeds/clothes_accessories_categories.exs @@ -20,3 +20,5 @@ end Enum.map(data, fn row -> parse_and_store.(row) end) from(c in Category, where: c.department == "NULL" and not is_nil(c.item_type)) |> Hyperion.Repo.update_all(set: [department: nil]) + +from(c in Category, where: like(c.node_path, "%Clothing%")) |> Hyperion.Repo.update_all(set: [category_name: "clothing"]) diff --git a/hyperion/spec/factories/product_factory.ex b/hyperion/spec/factories/product_factory.ex index 104e362d38..5fdbc1804a 100644 --- a/hyperion/spec/factories/product_factory.ex +++ b/hyperion/spec/factories/product_factory.ex @@ -204,25 +204,58 @@ defmodule Hyperion.ProductFactory do saleprice: %{"currency" => "USD", "value" => 0}], 2}] end - def submit_images_feed_data do - [[{[sku: "SKU-ABC", type: "Main", - location: "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/487/DeathStar_400x390.jpg"], - 1}, - {[sku: "SKU-ABC", type: "PT", - location: "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/487/CuCeQ0IXEAAnpVx.jpg", - id: 1], 2}], - [[sku: "SKU-ABC", type: "Swatch", - location: "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/490/DeathStar2-1-1.jpg", - idx: 3], - [sku: "SKU-ABC", type: "Swatch", - location: "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/490/DeathStar2-2-0.jpg", - idx: 4], - [sku: "SKU-ABC", type: "Swatch", - location: "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/490/DeathStar2-2-2.jpg", - idx: 5], - [sku: "SKU-ABC", type: "Swatch", - location: "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/490/DeathStar2-0-1.jpg", - idx: 6]]] + def one_image_per_sku_data do + [{{"SKU-TRL1", "Main", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/232/81B6PnROB1L._UX522_.jpg"}, + 1}, + {{"SKU-TRL3", "Main", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/237/DeathStar2.jpg"}, + 2}, + {{"SKU-TRL2", "Main", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/235/DeathStar2.jpg"}, + 3}, + {{"SKU-TRL", "Main", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/221/DeathStar2.jpg"}, + 4}] + end + + def many_images_per_sku_data do + [{{"SKU-ABC", "Main", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/243/20170321_234255.jpg"}, + 1}, + {{"SKU-ABC", "PT", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/243/DeathStar2.jpg", + 1}, 2}, + {{"SKU-ABC", "Swatch", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/256/DeathStar2-0-1.jpg"}, + 3}, + {{"SKU-ABC", "Swatch", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/256/DeathStar2-1-0.jpg"}, + 4}, + {{"SKU-ABC", "Swatch", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/256/DeathStar2-1-1.jpg"}, + 5}, + {{"SKU-ABC", "Swatch", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/256/DeathStar2-2-0.jpg"}, + 6}, + {{"SKU-CBA", "Main", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/248/4620266368976559_big.jpg"}, + 7}, + {{"SKU-CBA", "PT", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/248/2krWC11Pfko.jpg", + 1}, 8}, + {{"SKU-CBA", "Swatch", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/261/DeathStar2-0-1.jpg"}, + 9}, + {{"SKU-CBA", "Swatch", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/261/DeathStar2-1-0.jpg"}, + 10}, + {{"SKU-CBA", "Swatch", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/261/DeathStar2-1-1.jpg"}, + 11}, + {{"SKU-CBA", "Swatch", + "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/261/DeathStar2-2-0.jpg"}, + 12}] end end end diff --git a/hyperion/spec/lib/amazon/amazon_spec.exs b/hyperion/spec/lib/amazon/amazon_spec.exs index 90e2cb36c2..c0c416c1a6 100644 --- a/hyperion/spec/lib/amazon/amazon_spec.exs +++ b/hyperion/spec/lib/amazon/amazon_spec.exs @@ -50,7 +50,7 @@ defmodule AmazonSpec do describe "images_feed" do context "when product have images" do let resp: build(:sku_with_images) - let images: [[{[sku: "XMENTEEX1", type: "Main", location: "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/245/81B6PnROB1L._UX522_.jpg"], 1}]] + let images: [{{"XMENTEEX1", "Main", "http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/245/81B6PnROB1L._UX522_.jpg"}, 1}] before do: allow(Hyperion.PhoenixScala.Client).to accept(:get_product, fn(_, _) -> resp() end) diff --git a/hyperion/spec/lib/amazon/templates/template_builder_spec.exs b/hyperion/spec/lib/amazon/templates/template_builder_spec.exs index 04c83e1bc8..4689a90773 100644 --- a/hyperion/spec/lib/amazon/templates/template_builder_spec.exs +++ b/hyperion/spec/lib/amazon/templates/template_builder_spec.exs @@ -48,13 +48,26 @@ defmodule TemplateBuilderSpec do describe "submit_images_feed" do - let list: submit_images_feed_data() - let opts: %{seller_id: 123} - let template: "\n\n
\n 1.01\n 123\n
\n ProductImage\n \n 1\n Update\n \n SKU-ABC\n Main\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/487/DeathStar_400x390.jpg\n \n\n\n \n 2\n Update\n \n SKU-ABC\n PT1\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/487/CuCeQ0IXEAAnpVx.jpg\n \n\n\n \n 3\n Update\n \n SKU-ABC\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/490/DeathStar2-1-1.jpg\n \n\n\n 4\n Update\n \n SKU-ABC\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/490/DeathStar2-2-0.jpg\n \n\n\n 5\n Update\n \n SKU-ABC\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/490/DeathStar2-2-2.jpg\n \n\n\n 6\n Update\n \n SKU-ABC\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/490/DeathStar2-0-1.jpg\n \n\n\n
\n" + context "when there is only one image per SKU" do + let list: one_image_per_sku_data() + let opts: %{seller_id: 123} + let template: "\n\n
\n 1.01\n 123\n
\n ProductImage\n \n \n 1\n Update\n \n SKU-TRL1\n Main\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/232/81B6PnROB1L._UX522_.jpg\n \n\n\n \n \n 2\n Update\n \n SKU-TRL3\n Main\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/237/DeathStar2.jpg\n \n\n\n \n \n 3\n Update\n \n SKU-TRL2\n Main\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/235/DeathStar2.jpg\n \n\n\n \n \n 4\n Update\n \n SKU-TRL\n Main\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/221/DeathStar2.jpg\n \n\n\n \n
\n" - it "should render images template" do - expect Hyperion.Amazon.TemplateBuilder.submit_images_feed(list(), opts()) - |> to(eq(template())) + it "should render images template" do + expect Hyperion.Amazon.TemplateBuilder.submit_images_feed(list(), opts()) + |> to(eq(template())) + end + end + + context "when there are many images per SKU" do + let list: many_images_per_sku_data() + let opts: %{seller_id: 123} + let template: "\n\n
\n 1.01\n 123\n
\n ProductImage\n \n \n 1\n Update\n \n SKU-ABC\n Main\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/243/20170321_234255.jpg\n \n\n\n \n \n 2\n Update\n \n SKU-ABC\n PT1\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/243/DeathStar2.jpg\n \n\n\n \n \n 3\n Update\n \n SKU-ABC\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/256/DeathStar2-0-1.jpg\n \n\n\n \n \n 4\n Update\n \n SKU-ABC\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/256/DeathStar2-1-0.jpg\n \n\n\n \n \n 5\n Update\n \n SKU-ABC\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/256/DeathStar2-1-1.jpg\n \n\n\n \n \n 6\n Update\n \n SKU-ABC\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/256/DeathStar2-2-0.jpg\n \n\n\n \n \n 7\n Update\n \n SKU-CBA\n Main\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/248/4620266368976559_big.jpg\n \n\n\n \n \n 8\n Update\n \n SKU-CBA\n PT1\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/248/2krWC11Pfko.jpg\n \n\n\n \n \n 9\n Update\n \n SKU-CBA\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/261/DeathStar2-0-1.jpg\n \n\n\n \n \n 10\n Update\n \n SKU-CBA\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/261/DeathStar2-1-0.jpg\n \n\n\n \n \n 11\n Update\n \n SKU-CBA\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/261/DeathStar2-1-1.jpg\n \n\n\n \n \n 12\n Update\n \n SKU-CBA\n Swatch\n http://s3-us-west-1.amazonaws.com/foxcomm-images/albums/1/261/DeathStar2-2-0.jpg\n \n\n\n \n
\n" + + it "should render images template" do + expect Hyperion.Amazon.TemplateBuilder.submit_images_feed(list(), opts()) + |> to(eq(template())) + end end end From 29fa2511f55836cd8ff10ad400fffc9c90e347cb Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 4 May 2017 16:32:27 +0700 Subject: [PATCH 60/93] Remove unused stuff --- hyperion/lib/hyperion/amazon/amazon.ex | 38 +++---------------- .../amazon/templates/submit_images.ex | 2 +- 2 files changed, 7 insertions(+), 33 deletions(-) diff --git a/hyperion/lib/hyperion/amazon/amazon.ex b/hyperion/lib/hyperion/amazon/amazon.ex index b8d5ea9ace..dcf131a3de 100644 --- a/hyperion/lib/hyperion/amazon/amazon.ex +++ b/hyperion/lib/hyperion/amazon/amazon.ex @@ -249,32 +249,10 @@ defmodule Hyperion.Amazon do end - @doc """ - Gets the albums and images for amazon enabled skus, - adds the SKU for matching - renders main, pt and swatch images - """ - # defp process_images(response) do - # r = response.body - # amazon_skus = Enum.filter(r["skus"], fn (sku) -> - # sku["attributes"]["amazon"]["v"] == true - # end) - - # case amazon_skus do - # [] -> raise "No images for product #{r["id"]}" - # _ -> amazon_skus - # end - # |> Enum.flat_map(fn(sku)-> - # images = Enum.flat_map(sku["albums"], fn(album) -> - # Enum.map(album["images"], fn(image) -> - # [code: sku["attributes"]["code"]["v"], src: image["src"], type: album["name"]] - # end) - # end) - # end) - # |> Enum.with_index(1) - - # end + # Gets the albums and images for amazon enabled skus, + # adds the SKU for matching + # renders main, pt and swatch images defp process_images(response) do r = response.body amazon_skus = Enum.filter(r["skus"], fn (sku) -> @@ -304,19 +282,16 @@ defmodule Hyperion.Amazon do # {[type: "PT", # location: "http:", id: 1], # 2}], - defp render_main_section({_, [h|t]}, sku, idx) when t == [] do + defp render_main_section({_, [h|t]}, sku, _idx) when t == [] do IO.puts("t is []") - # [{[sku: sku, type: "Main", location: String.replace(h["src"], "https", "http")], idx}] [{sku, "Main", String.replace(h["src"], "https", "http")}] end - defp render_main_section({_, [h|t]}, sku, idx) do - # main = [sku: sku, type: "Main", location: String.replace(h["src"], "https", "http")] + defp render_main_section({_, [h|t]}, sku, _idx) do main = {sku, "Main", String.replace(h["src"], "https", "http")} pt = Enum.with_index(t, 1) |> Enum.map(fn({img, idx}) -> - # [sku: sku, type: "PT", location: String.replace(img["src"], "https", "http"), id: idx] {sku, "PT", String.replace(img["src"], "https", "http"), idx} end) [main, pt] @@ -329,8 +304,7 @@ defmodule Hyperion.Amazon do # [[type: Swatch, lication: http://, id: id]] def render_swatch_section(list, sku, initial) do Enum.with_index(list, initial + 1) - |> Enum.map(fn {image, idx} -> - # [sku: sku, type: "Swatch", location: String.replace(image["src"], "https", "http")] + |> Enum.map(fn {image, _idx} -> {sku, "Swatch", String.replace(image["src"], "https", "http")} end) end diff --git a/hyperion/lib/hyperion/amazon/templates/submit_images.ex b/hyperion/lib/hyperion/amazon/templates/submit_images.ex index 3ddad42d61..a48c20efb4 100644 --- a/hyperion/lib/hyperion/amazon/templates/submit_images.ex +++ b/hyperion/lib/hyperion/amazon/templates/submit_images.ex @@ -20,7 +20,7 @@ defmodule Hyperion.Amazon.Templates.SubmitImages do """ end - def render_any_image({n, idx}) when n == nil, do: "" + def render_any_image({n, _idx}) when n == nil, do: "" def render_any_image({{sku, type, src}, message_id}) do """ From 2ad5c961c9974a2c266b39b0a4a58410bdd71351 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 4 May 2017 18:23:20 +0700 Subject: [PATCH 61/93] Fetch customer by email --- phoenix-scala/app/failures/UserFailures.scala | 4 +++ phoenix-scala/app/models/account/User.scala | 4 +++ .../app/routes/admin/CustomerRoutes.scala | 7 +++++ .../services/customers/CustomerManager.scala | 31 +++++++++++++++++++ .../integration/CustomerIntegrationTest.scala | 9 ++++++ .../testutils/apis/PhoenixAdminApi.scala | 7 ++++- 6 files changed, 61 insertions(+), 1 deletion(-) diff --git a/phoenix-scala/app/failures/UserFailures.scala b/phoenix-scala/app/failures/UserFailures.scala index 678ec5b40e..3a855ca588 100644 --- a/phoenix-scala/app/failures/UserFailures.scala +++ b/phoenix-scala/app/failures/UserFailures.scala @@ -17,6 +17,10 @@ object UserFailures { def apply(accountId: Int) = NotFoundFailure404(User, accountId) } + object UserWithEmailNotFound { + def apply(email: String) = NotFoundFailure404(User, email) + } + case class UserIsBlacklisted(accountId: Int) extends Failure { override def description = s"User with id = $accountId is blacklisted" } diff --git a/phoenix-scala/app/models/account/User.scala b/phoenix-scala/app/models/account/User.scala index a43485bd0f..d9f17ad779 100644 --- a/phoenix-scala/app/models/account/User.scala +++ b/phoenix-scala/app/models/account/User.scala @@ -129,6 +129,10 @@ object Users extends FoxTableQuery[User, Users](new Users(_)) with ReturningId[U def activeUserByEmail(email: Option[String]): QuerySeq = filter(c ⇒ c.email === email && !c.isBlacklisted && !c.isDisabled) + def mustfindOneByEmail(email: String)(implicit ec: EC): DbResultT[User] = { + findByEmail(email).mustFindOneOr(UserWithEmailNotFound(email)) + } + def otherUserByEmail(email: String, accountId: Int): QuerySeq = { filter(c ⇒ c.email === email && c.accountId =!= accountId && !c.isBlacklisted && !c.isDisabled) } diff --git a/phoenix-scala/app/routes/admin/CustomerRoutes.scala b/phoenix-scala/app/routes/admin/CustomerRoutes.scala index 0cfcdfac9c..c809f6a207 100644 --- a/phoenix-scala/app/routes/admin/CustomerRoutes.scala +++ b/phoenix-scala/app/routes/admin/CustomerRoutes.scala @@ -39,6 +39,13 @@ object CustomerRoutes { val context = AccountCreateContext(List(roleName), orgName, scopeId) CustomerManager.createFromAdmin(payload, Some(auth.model), context) } + } ~ + pathPrefix(Segment) { customerEmail ⇒ + (get & pathEnd) { + getOrFailures { + CustomerManager.getByEmail(customerEmail) + } + } } } ~ pathPrefix("customers" / IntNumber) { accountId ⇒ diff --git a/phoenix-scala/app/services/customers/CustomerManager.scala b/phoenix-scala/app/services/customers/CustomerManager.scala index 5b0779004d..8641966b2f 100644 --- a/phoenix-scala/app/services/customers/CustomerManager.scala +++ b/phoenix-scala/app/services/customers/CustomerManager.scala @@ -81,6 +81,37 @@ object CustomerManager { groups = groups.map(CustomerGroupResponse.build)) } + def getByEmail(email: String)(implicit ec: EC, db: DB): DbResultT[Root] = { + for { + customer ← * <~ Users.mustfindOneByEmail(email) + customerDatas ← * <~ CustomersData + .filter(_.accountId === customer.accountId) + .withRegionsAndRank + .mustFindOneOr(NotFoundFailure404(CustomerData, customer.accountId)) + (customerData, shipRegion, billRegion, rank) = customerDatas + maxOrdersDate ← * <~ Orders + .filter(_.accountId === customer.accountId) + .map(_.placedAt) + .max + .result + totals ← * <~ StoreCreditService.fetchTotalsForCustomer(customer.accountId) + phoneOverride ← * <~ doOrGood(customer.phoneNumber.isEmpty, + resolvePhoneNumber(customer.accountId), + None) + groupMembership ← * <~ CustomerGroupMembers.findByCustomerDataId(customerData.id).result + groupIds = groupMembership.map(_.groupId).toSet + groups ← * <~ CustomerGroups.findAllByIds(groupIds).result + } yield + build(customer.copy(phoneNumber = customer.phoneNumber.orElse(phoneOverride)), + customerData, + shipRegion, + billRegion, + rank = rank, + scTotals = totals, + lastOrderDays = maxOrdersDate.map(DAYS.between(_, Instant.now)), + groups = groups.map(CustomerGroupResponse.build)) + } + def create(payload: CreateCustomerPayload, admin: Option[User] = None, context: AccountCreateContext)(implicit ec: EC, diff --git a/phoenix-scala/test/integration/CustomerIntegrationTest.scala b/phoenix-scala/test/integration/CustomerIntegrationTest.scala index fdb9189ccb..218116b79b 100644 --- a/phoenix-scala/test/integration/CustomerIntegrationTest.scala +++ b/phoenix-scala/test/integration/CustomerIntegrationTest.scala @@ -81,7 +81,16 @@ class CustomerIntegrationTest } + "GET /v1/customers/:email" - { + "fetches customer info by email" in new Fixture { + val customerRoot = + CustomerResponse.build(customer, customerData, shippingRegion = region.some) + customersApi.get(customer.email).as[Root] must === (customerRoot) + } + } + "GET /v1/customers/:accountId" - { + "fetches customer info" in new Fixture { val customerRoot = CustomerResponse.build(customer, customerData, shippingRegion = region.some) diff --git a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala index 62a4e5fa97..9c2e382026 100644 --- a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -57,8 +57,13 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ object customersApi { val customersPrefix = s"$rootPrefix/customers" - def create(payload: CreateCustomerPayload)(implicit aa: TestAdminAuth): HttpResponse = + def create(payload: CreateCustomerPayload)(implicit aa: TestAdminAuth): HttpResponse = { POST(customersPrefix, payload, aa.jwtCookie.some) + } + + def get(customerEmail: Option[String])(implicit aa: TestAdminAuth): HttpResponse = { + GET(s"$customersPrefix/$customerEmail", aa.jwtCookie.some) + } } case class customersApi(id: Int) { From 7165765b59e3b9a91eac32da4db5f2fe708dd883 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 4 May 2017 19:18:19 +0700 Subject: [PATCH 62/93] Use another failure --- phoenix-scala/app/failures/UserFailures.scala | 4 ---- phoenix-scala/app/models/account/User.scala | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/phoenix-scala/app/failures/UserFailures.scala b/phoenix-scala/app/failures/UserFailures.scala index 3a855ca588..678ec5b40e 100644 --- a/phoenix-scala/app/failures/UserFailures.scala +++ b/phoenix-scala/app/failures/UserFailures.scala @@ -17,10 +17,6 @@ object UserFailures { def apply(accountId: Int) = NotFoundFailure404(User, accountId) } - object UserWithEmailNotFound { - def apply(email: String) = NotFoundFailure404(User, email) - } - case class UserIsBlacklisted(accountId: Int) extends Failure { override def description = s"User with id = $accountId is blacklisted" } diff --git a/phoenix-scala/app/models/account/User.scala b/phoenix-scala/app/models/account/User.scala index d9f17ad779..073afb97be 100644 --- a/phoenix-scala/app/models/account/User.scala +++ b/phoenix-scala/app/models/account/User.scala @@ -130,7 +130,7 @@ object Users extends FoxTableQuery[User, Users](new Users(_)) with ReturningId[U filter(c ⇒ c.email === email && !c.isBlacklisted && !c.isDisabled) def mustfindOneByEmail(email: String)(implicit ec: EC): DbResultT[User] = { - findByEmail(email).mustFindOneOr(UserWithEmailNotFound(email)) + findByEmail(email).mustFindOneOr(NotFoundFailure404(s"Customer with email=$email not found")) } def otherUserByEmail(email: String, accountId: Int): QuerySeq = { From ee945d83cd28194ad20ad1003dda1042aed4d1c5 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 4 May 2017 20:14:56 +0700 Subject: [PATCH 63/93] Fix routes and reuse code --- .../app/routes/admin/CustomerRoutes.scala | 2 +- .../services/customers/CustomerManager.scala | 42 ++++++------------- .../integration/CustomerIntegrationTest.scala | 4 +- .../testutils/apis/PhoenixAdminApi.scala | 4 +- 4 files changed, 18 insertions(+), 34 deletions(-) diff --git a/phoenix-scala/app/routes/admin/CustomerRoutes.scala b/phoenix-scala/app/routes/admin/CustomerRoutes.scala index c809f6a207..3705efcf3c 100644 --- a/phoenix-scala/app/routes/admin/CustomerRoutes.scala +++ b/phoenix-scala/app/routes/admin/CustomerRoutes.scala @@ -40,7 +40,7 @@ object CustomerRoutes { CustomerManager.createFromAdmin(payload, Some(auth.model), context) } } ~ - pathPrefix(Segment) { customerEmail ⇒ + pathPrefix("email" / Segment) { customerEmail ⇒ (get & pathEnd) { getOrFailures { CustomerManager.getByEmail(customerEmail) diff --git a/phoenix-scala/app/services/customers/CustomerManager.scala b/phoenix-scala/app/services/customers/CustomerManager.scala index 8641966b2f..ac564f2a4f 100644 --- a/phoenix-scala/app/services/customers/CustomerManager.scala +++ b/phoenix-scala/app/services/customers/CustomerManager.scala @@ -54,36 +54,10 @@ object CustomerManager { } yield shipment } - def getByAccountId(accountId: Int)(implicit ec: EC, db: DB): DbResultT[Root] = { + private def getCustomerInfo(user: DbResultT[models.account.User])(implicit ec: EC, + db: DB): DbResultT[Root] = { for { - customer ← * <~ Users.mustFindByAccountId(accountId) - customerDatas ← * <~ CustomersData - .filter(_.accountId === accountId) - .withRegionsAndRank - .mustFindOneOr(NotFoundFailure404(CustomerData, accountId)) - (customerData, shipRegion, billRegion, rank) = customerDatas - maxOrdersDate ← * <~ Orders.filter(_.accountId === accountId).map(_.placedAt).max.result - totals ← * <~ StoreCreditService.fetchTotalsForCustomer(accountId) - phoneOverride ← * <~ doOrGood(customer.phoneNumber.isEmpty, - resolvePhoneNumber(accountId), - None) - groupMembership ← * <~ CustomerGroupMembers.findByCustomerDataId(customerData.id).result - groupIds = groupMembership.map(_.groupId).toSet - groups ← * <~ CustomerGroups.findAllByIds(groupIds).result - } yield - build(customer.copy(phoneNumber = customer.phoneNumber.orElse(phoneOverride)), - customerData, - shipRegion, - billRegion, - rank = rank, - scTotals = totals, - lastOrderDays = maxOrdersDate.map(DAYS.between(_, Instant.now)), - groups = groups.map(CustomerGroupResponse.build)) - } - - def getByEmail(email: String)(implicit ec: EC, db: DB): DbResultT[Root] = { - for { - customer ← * <~ Users.mustfindOneByEmail(email) + customer ← * <~ user customerDatas ← * <~ CustomersData .filter(_.accountId === customer.accountId) .withRegionsAndRank @@ -112,6 +86,16 @@ object CustomerManager { groups = groups.map(CustomerGroupResponse.build)) } + def getByAccountId(accountId: Int)(implicit ec: EC, db: DB): DbResultT[Root] = { + val userByAccountId = Users.mustFindByAccountId(accountId) + getCustomerInfo(userByAccountId) + } + + def getByEmail(email: String)(implicit ec: EC, db: DB): DbResultT[Root] = { + val userByEmail = Users.mustfindOneByEmail(email) + getCustomerInfo(userByEmail) + } + def create(payload: CreateCustomerPayload, admin: Option[User] = None, context: AccountCreateContext)(implicit ec: EC, diff --git a/phoenix-scala/test/integration/CustomerIntegrationTest.scala b/phoenix-scala/test/integration/CustomerIntegrationTest.scala index 218116b79b..5a0544e2fc 100644 --- a/phoenix-scala/test/integration/CustomerIntegrationTest.scala +++ b/phoenix-scala/test/integration/CustomerIntegrationTest.scala @@ -81,11 +81,11 @@ class CustomerIntegrationTest } - "GET /v1/customers/:email" - { + "GET /v1/customers/email/:email" - { "fetches customer info by email" in new Fixture { val customerRoot = CustomerResponse.build(customer, customerData, shippingRegion = region.some) - customersApi.get(customer.email).as[Root] must === (customerRoot) + customersApi.get_by_email(customer.email.value).as[Root] must === (customerRoot) } } diff --git a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala index 9c2e382026..7bc1b3df9c 100644 --- a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -61,8 +61,8 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ POST(customersPrefix, payload, aa.jwtCookie.some) } - def get(customerEmail: Option[String])(implicit aa: TestAdminAuth): HttpResponse = { - GET(s"$customersPrefix/$customerEmail", aa.jwtCookie.some) + def get_by_email(customerEmail: String)(implicit aa: TestAdminAuth): HttpResponse = { + GET(s"$customersPrefix/email/$customerEmail", aa.jwtCookie.some) } } From bf6f5aac14c8056e3f8b14e856c6301d4201e5d9 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 4 May 2017 22:00:06 +0700 Subject: [PATCH 64/93] Apply CR comments --- phoenix-scala/app/models/account/User.scala | 11 ++++------- .../app/services/customers/CustomerManager.scala | 14 +++++++------- .../test/integration/CustomerIntegrationTest.scala | 12 ++++++++---- .../testutils/apis/PhoenixAdminApi.scala | 6 ++---- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/phoenix-scala/app/models/account/User.scala b/phoenix-scala/app/models/account/User.scala index 073afb97be..e86cf2c27a 100644 --- a/phoenix-scala/app/models/account/User.scala +++ b/phoenix-scala/app/models/account/User.scala @@ -114,9 +114,8 @@ object Users extends FoxTableQuery[User, Users](new Users(_)) with ReturningId[U val returningLens: Lens[User, Int] = lens[User].id - def findByEmail(email: String): QuerySeq = { + def findByEmail(email: String): QuerySeq = filter(_.email === email) - } def findNonGuestByEmail(email: String): QuerySeq = { findByEmail(email) @@ -129,13 +128,11 @@ object Users extends FoxTableQuery[User, Users](new Users(_)) with ReturningId[U def activeUserByEmail(email: Option[String]): QuerySeq = filter(c ⇒ c.email === email && !c.isBlacklisted && !c.isDisabled) - def mustfindOneByEmail(email: String)(implicit ec: EC): DbResultT[User] = { - findByEmail(email).mustFindOneOr(NotFoundFailure404(s"Customer with email=$email not found")) - } + def mustfindOneByEmail(email: String)(implicit ec: EC): DbResultT[User] = + findByEmail(email).mustFindOneOr(NotFoundFailure404(User, email)) - def otherUserByEmail(email: String, accountId: Int): QuerySeq = { + def otherUserByEmail(email: String, accountId: Int): QuerySeq = filter(c ⇒ c.email === email && c.accountId =!= accountId && !c.isBlacklisted && !c.isDisabled) - } def findOneByAccountId(accountId: Int): DBIO[Option[User]] = filter(_.accountId === accountId).result.headOption diff --git a/phoenix-scala/app/services/customers/CustomerManager.scala b/phoenix-scala/app/services/customers/CustomerManager.scala index ac564f2a4f..3e4175cf63 100644 --- a/phoenix-scala/app/services/customers/CustomerManager.scala +++ b/phoenix-scala/app/services/customers/CustomerManager.scala @@ -54,10 +54,10 @@ object CustomerManager { } yield shipment } - private def getCustomerInfo(user: DbResultT[models.account.User])(implicit ec: EC, - db: DB): DbResultT[Root] = { + private def getCustomerInfo(userDbT: DbResultT[models.account.User])(implicit ec: EC, + db: DB): DbResultT[Root] = { for { - customer ← * <~ user + customer ← * <~ userDbT customerDatas ← * <~ CustomersData .filter(_.accountId === customer.accountId) .withRegionsAndRank @@ -87,13 +87,13 @@ object CustomerManager { } def getByAccountId(accountId: Int)(implicit ec: EC, db: DB): DbResultT[Root] = { - val userByAccountId = Users.mustFindByAccountId(accountId) - getCustomerInfo(userByAccountId) + val userDbByAccountId = Users.mustFindByAccountId(accountId) + getCustomerInfo(userDbByAccountId) } def getByEmail(email: String)(implicit ec: EC, db: DB): DbResultT[Root] = { - val userByEmail = Users.mustfindOneByEmail(email) - getCustomerInfo(userByEmail) + val userDbByEmail = Users.mustfindOneByEmail(email) + getCustomerInfo(userDbByEmail) } def create(payload: CreateCustomerPayload, diff --git a/phoenix-scala/test/integration/CustomerIntegrationTest.scala b/phoenix-scala/test/integration/CustomerIntegrationTest.scala index 5a0544e2fc..71c151a7ab 100644 --- a/phoenix-scala/test/integration/CustomerIntegrationTest.scala +++ b/phoenix-scala/test/integration/CustomerIntegrationTest.scala @@ -82,10 +82,14 @@ class CustomerIntegrationTest } "GET /v1/customers/email/:email" - { - "fetches customer info by email" in new Fixture { - val customerRoot = - CustomerResponse.build(customer, customerData, shippingRegion = region.some) - customersApi.get_by_email(customer.email.value).as[Root] must === (customerRoot) + "fetches customer info by email" in new Customer_Seed { + customersApi.get_by_email(customer.email.value).as[Root].id must === (customer.id) + } + + "fails if customer not found" in { + customersApi + .get_by_email("foo@bar.baz") + .mustFailWith404(NotFoundFailure404(User, "foo@bar.baz")) } } diff --git a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala index 7bc1b3df9c..cf3af124ee 100644 --- a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -57,13 +57,11 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ object customersApi { val customersPrefix = s"$rootPrefix/customers" - def create(payload: CreateCustomerPayload)(implicit aa: TestAdminAuth): HttpResponse = { + def create(payload: CreateCustomerPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(customersPrefix, payload, aa.jwtCookie.some) - } - def get_by_email(customerEmail: String)(implicit aa: TestAdminAuth): HttpResponse = { + def get_by_email(customerEmail: String)(implicit aa: TestAdminAuth): HttpResponse = GET(s"$customersPrefix/email/$customerEmail", aa.jwtCookie.some) - } } case class customersApi(id: Int) { From 972a14381a8bd6790f77725f4444e260e08c9a39 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 4 May 2017 22:34:54 +0700 Subject: [PATCH 65/93] camelCase method --- phoenix-scala/test/integration/CustomerIntegrationTest.scala | 4 ++-- .../test/integration/testutils/apis/PhoenixAdminApi.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phoenix-scala/test/integration/CustomerIntegrationTest.scala b/phoenix-scala/test/integration/CustomerIntegrationTest.scala index 71c151a7ab..6b9b2000cc 100644 --- a/phoenix-scala/test/integration/CustomerIntegrationTest.scala +++ b/phoenix-scala/test/integration/CustomerIntegrationTest.scala @@ -83,12 +83,12 @@ class CustomerIntegrationTest "GET /v1/customers/email/:email" - { "fetches customer info by email" in new Customer_Seed { - customersApi.get_by_email(customer.email.value).as[Root].id must === (customer.id) + customersApi.getByEmail(customer.email.value).as[Root].id must === (customer.id) } "fails if customer not found" in { customersApi - .get_by_email("foo@bar.baz") + .getByEmail("foo@bar.baz") .mustFailWith404(NotFoundFailure404(User, "foo@bar.baz")) } } diff --git a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala index cf3af124ee..5c9e83dc0e 100644 --- a/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -60,7 +60,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def create(payload: CreateCustomerPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(customersPrefix, payload, aa.jwtCookie.some) - def get_by_email(customerEmail: String)(implicit aa: TestAdminAuth): HttpResponse = + def getByEmail(customerEmail: String)(implicit aa: TestAdminAuth): HttpResponse = GET(s"$customersPrefix/email/$customerEmail", aa.jwtCookie.some) } From 60c238c61a11883594ec5cd031c21e049dd4ca59 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 5 May 2017 09:00:41 +0700 Subject: [PATCH 66/93] Add customer from phoenix to full order --- hyperion/lib/hyperion/amazon/amazon.ex | 5 +---- hyperion/lib/hyperion/phoenix_scala/client.ex | 11 +++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/hyperion/lib/hyperion/amazon/amazon.ex b/hyperion/lib/hyperion/amazon/amazon.ex index dcf131a3de..87e2b241ca 100644 --- a/hyperion/lib/hyperion/amazon/amazon.ex +++ b/hyperion/lib/hyperion/amazon/amazon.ex @@ -126,10 +126,7 @@ defmodule Hyperion.Amazon do adjustments: 0, total: String.to_float(order["OrderTotal"]["Amount"]) * 100 |> round }, - customer: %{ - email: order["BuyerEmail"], - name: order["BuyerName"] - }, + customer: Client.get_customer_by_email(order["BuyerEmail"], token).body, shippingMethod: %{ id: 0, name: order["ShipmentServiceLevelCategory"], diff --git a/hyperion/lib/hyperion/phoenix_scala/client.ex b/hyperion/lib/hyperion/phoenix_scala/client.ex index d6f2b17d82..b555e95e7c 100644 --- a/hyperion/lib/hyperion/phoenix_scala/client.ex +++ b/hyperion/lib/hyperion/phoenix_scala/client.ex @@ -84,6 +84,17 @@ defmodule Hyperion.PhoenixScala.Client do |> parse_response(token) end + def get_customer_by_email(email, token) do + get("/v1/customers/email/#{email}", make_request_headers(token)) + |> parse_response(token) + end + + def get_customer_by_email(email) do + token = login() + get("/v1/customers/email/#{email}", make_request_headers(token)) + |> parse_response(token) + end + @doc """ Creates new customer in Phoenix from Amazon order """ From 72fff47fdbc720c1164e9cb9e2d36d5a2e59cb23 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Fri, 5 May 2017 14:23:04 +0700 Subject: [PATCH 67/93] Add images for amazon wiki --- documents/wiki_images/amazon/button-ashes.png | Bin 0 -> 48889 bytes documents/wiki_images/amazon/mws-ashes.png | Bin 0 -> 93277 bytes .../wiki_images/amazon/pics-amazon-pdp.png | Bin 0 -> 397309 bytes documents/wiki_images/amazon/pics-ashes.png | Bin 0 -> 410889 bytes documents/wiki_images/amazon/plugins-ashes.png | Bin 0 -> 98651 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 documents/wiki_images/amazon/button-ashes.png create mode 100644 documents/wiki_images/amazon/mws-ashes.png create mode 100644 documents/wiki_images/amazon/pics-amazon-pdp.png create mode 100644 documents/wiki_images/amazon/pics-ashes.png create mode 100644 documents/wiki_images/amazon/plugins-ashes.png diff --git a/documents/wiki_images/amazon/button-ashes.png b/documents/wiki_images/amazon/button-ashes.png new file mode 100644 index 0000000000000000000000000000000000000000..41b80686b9861510e69f6232101449149ef06335 GIT binary patch literal 48889 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 literal 0 HcmV?d00001 diff --git a/documents/wiki_images/amazon/mws-ashes.png b/documents/wiki_images/amazon/mws-ashes.png new file mode 100644 index 0000000000000000000000000000000000000000..92bbeab4805ec8ea5be10928465f6c1cb7080dd4 GIT binary patch literal 93277 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%0A7(6}p*ffoZ^FB`-yDauJ($DP)$SzYH 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 z]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 literal 0 HcmV?d00001 diff --git a/documents/wiki_images/amazon/pics-amazon-pdp.png b/documents/wiki_images/amazon/pics-amazon-pdp.png new file mode 100644 index 0000000000000000000000000000000000000000..7f47bc32c05a20ea9e4e9ee875e8e8c8ae1662e5 GIT binary patch literal 397309 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

_oIZtel}; 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�HkWIU0W@ApGcCN`uIHhsfY5Ca-KcmRPO2Xu6d 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 QBZ^he6snzWx{$uo+jA!4@f4|_vVsmzy5 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 z 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 *c`_jNBRr-)VpyF6M~WQ#ua!6FZm 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⪚+;qasyE(;p!a&ElqRd`X_Q8cx`+h8fp8 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

(zh2UBzpQ6etiY*5`ManZ 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 literal 0 HcmV?d00001 diff --git a/documents/wiki_images/amazon/pics-ashes.png b/documents/wiki_images/amazon/pics-ashes.png new file mode 100644 index 0000000000000000000000000000000000000000..0cf0aa1de0e9d7ad5798023e03c574255a096ec8 GIT binary patch literal 410889 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%0A**e=Yx0767LJlLx=J>zxZhKUA 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°Avk|L))ZU(fyg+5erqEn5En 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

p^%iX|OTyy= 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

t$x?O#f>~`q{ye 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

nD5V_vMb+B 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 Date: Fri, 5 May 2017 14:24:05 +0700 Subject: [PATCH 68/93] Revert "Add images for amazon wiki" This reverts commit 72fff47fdbc720c1164e9cb9e2d36d5a2e59cb23. --- documents/wiki_images/amazon/button-ashes.png | Bin 48889 -> 0 bytes documents/wiki_images/amazon/mws-ashes.png | Bin 93277 -> 0 bytes .../wiki_images/amazon/pics-amazon-pdp.png | Bin 397309 -> 0 bytes documents/wiki_images/amazon/pics-ashes.png | Bin 410889 -> 0 bytes documents/wiki_images/amazon/plugins-ashes.png | Bin 98651 -> 0 bytes 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 documents/wiki_images/amazon/button-ashes.png delete mode 100644 documents/wiki_images/amazon/mws-ashes.png delete mode 100644 documents/wiki_images/amazon/pics-amazon-pdp.png delete mode 100644 documents/wiki_images/amazon/pics-ashes.png delete mode 100644 documents/wiki_images/amazon/plugins-ashes.png diff --git a/documents/wiki_images/amazon/button-ashes.png b/documents/wiki_images/amazon/button-ashes.png deleted file mode 100644 index 41b80686b9861510e69f6232101449149ef06335..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48889 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 diff --git a/documents/wiki_images/amazon/mws-ashes.png b/documents/wiki_images/amazon/mws-ashes.png deleted file mode 100644 index 92bbeab4805ec8ea5be10928465f6c1cb7080dd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93277 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%0A7(6}p*ffoZ^FB`-yDauJ($DP)$SzYH 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 z]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 diff --git a/documents/wiki_images/amazon/pics-amazon-pdp.png b/documents/wiki_images/amazon/pics-amazon-pdp.png deleted file mode 100644 index 7f47bc32c05a20ea9e4e9ee875e8e8c8ae1662e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 397309 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

_oIZtel}; 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�HkWIU0W@ApGcCN`uIHhsfY5Ca-KcmRPO2Xu6d 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 QBZ^he6snzWx{$uo+jA!4@f4|_vVsmzy5 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 z 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 *c`_jNBRr-)VpyF6M~WQ#ua!6FZm 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⪚+;qasyE(;p!a&ElqRd`X_Q8cx`+h8fp8 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

(zh2UBzpQ6etiY*5`ManZ z9Fv^c^IN4!(x2mhuEr=ltF?m!Epp`6rRvT8trGDTNRi~dZ62~d?caaLKT(Mfd;?MJ ze^r7+mHTn(Kgq0@lJ{wlKf-CWA70lGZfz?T!sk4neAdco=>2tS+HRj{_QQ-#dq_W) z81)0;dTrz*yWSLsl^{x<(=Bb^XzWv_0W#yBWt}CrTXH*L-SW$g+w%k#^Dj42W^W|V zC&<3?!2CWLSX@st^DEH7Y)#Nz@~l1Uj!PTtlu<_|yKf2C5Z4yoate7T?#UGIJNUe~ zsP-5Ns%jJ*dYtCMElBul558fhxtja?m_<0+SiP^}p19Tau3*iz+jIR%IhPwjrM=(d zd3;zj|Hb=7OIBUKH)1}NvWS3Hm9x4txXa{U*1mJUzDZpCN3rnbVd)KKQ@?`hUa9;W z*WeUIwYamNWSpW#<^-H8*CkTK9g98J`F-s*xu2&pS6q%@;V@~5Sko;;KGy;_RRNp} z=)w-Q8#AvihpcP4zBg=poE`{|D-Sk&|L2zVE$~&32WBIgi5HqK+-uVQt#ZzibFM!} z+wsg|pP?b?uY_t@!}~?omwCj80`BGXq`#J!;D@dPkTFLy9{@+#=|t9}%U~9AdVc)l z+8FE$^ZYYCz#tBiviN2_W$SIUEUY?Ul8tBq-)myOj%1pPjt|0q`Rgj#!Fcix;H57m&Vp_2xhIxtJ6#;wb&Yqe ztB}5W#NH85*WX=r3CQ`b4)0R{{&lL32@v?diIBfLTmL`)Ot@NB@N>>)^Xaxw0A3*U zL&ooSa*}RQBTveiJMmY6oV)wUJLyH^?J{98uA>JAQtfEVxGY!BdHlY4x&A5 zm7>z^ixQsN>FV2+0sd-DRn!^~`|6R>51?)5oXT+=~=~-~x@(IRXlGS#?LX zQR8W$s}owN(?wJm8q|fGuvMbzjZqP%IVV_A$^l>ZKAD@m7)f25RAQ-u@(fTiHx8W(=yzU%9Ek5 z+gxdWt6fG*dk2G@J-;Hpn_-?d6c1&-X}oADeAbGdO+lxxUo)Lz*5&kSi+x7zh1B$;n%!`o<3mRpC28;l1FX8u(Bx#>T3(wD#^ z%VF*fGi+Or=@Qy7<2HJA3yGTtsrU=wucCH>~WnvPcGxmm9AMJIyskj{u3+2#W=N@AX|f=yRa*JL-Vd``l& z9dy@7g2DYxtPFt;9zRzAZrsb(ls8EH5%QBw&OUzk)to!*TFagUiLlezg0ONc6Z~!J z4FAFg)1ix{iUcyK^kiLQZUs^&zpnLxtd?^PE|nPP9WY>DRdKp@{FErTChTgj!D$|m z!{H0fgEUO3&^15v=nz_Z8_x5PDEy`X);9ZD{E7ZRlwgcOv@33XPzyEe|m1jZcKXh zEK033{tNh%Wl+j9hF{<0xR-$DEmQy`1C(BemXiJw9}3FmuYJugzYbDh@iO;CWZjU= zV+$8h&`=a5DO9z)AN-a5kd^4m25B{Sj$^kkeJ4GBm+RR^ONkdUOVugq zan<_Q9};&1^)`P1SVkvPsVivDbrnqzsMf)VF-?rmWKnA1^!oEh!>^a->a2+~Twz~d z{CS^!D8)gXswT6W=8wRV+eMn<3%jARr}KDRtT4shLvw!`I+YW8_)Dh!>ic|SP`V%f1!+FwOBJZN+LmPk;r_hM z2fwi{xHThj*}u29#HO29(uZ?wWi=V+UR`24^1!GoR0@I*Agn+nqAb&yjdqi+ju?q@U>yO;|sAZ48)=Nz%{D$VvBj zpPI5VyaGkT6~~@qI~-1!*A}i+SU(&+n+#QD;hK(&l>8pYKxg1mR&TktXG(rKn$eJa z-R*;hO52w-vk5Ev`N}%ZrepFC{9ZDn(Z z?X*L&dFs&BA3a!kUzEd;%N~2SrPAV(?NZ$sqx<8QkYwbv!cm^b`3MDpQm16m7We7U z>w-CLm#tNee7RG=?MD^rj%+d7x4x&pqAT`WcI~{IBUJzsVq1Ctxf3v^b8kODp1V4~ znI;@A=@!dVl(lZSH|P!anZ1+lmlSWlqH@V@Uj5oFtMNpFy*x9_?q)=iQUz~q<<{rP z%_!cehD{*bK9hezuzk1Oye73W*nKo2v-G)tpbxQg9h_k9Yg+k4@U0@FTd%d7kFfj& zreHZfh6M}%ziMw^oKbL*>ZGJd)bgP9(=Kn#CV2Mx&)>}ceS!5T!NTHs(o1!wIfHs2 zX>>0_E~pUbadE{AnsENpn(sY{sv9?tp653xaNlZJ76;u1CiQ(5h%hhoy>GFx`Vp>i zT}A#4!SCy3*ClJ%4$xo#XROL){p0DY^kse*Pp2L?D5%W$)w&LAfyDF!hAVm>GXP`8 zaO25`*Y}|cvq8K~M?oDY+H+ODOkh2AOMuajntZem-M%hcE#=`!=i_y%in?K81JgvU{t?^l=i1Y`_j|KEdg~*gzVRMAB~Grm-%Qj z61h}TJ@lv%P2J#D#?OdCNJpu*$0eDlpojm2xf7TtoOzeiLOhQ)n8M={kc-T-z^8_Jf z-}`7_a@vHg^8QlDTfxrSCW zJ-WVe*1KT}AwuNf57-@&;uNY0D2MbA>dqQA=&UQgdb5z|KA-8L^vXloU|Zq!exv+q z!9joW1`kWzHHAfqlcv0rz|TTmzM<<&WsSDka#VK-J}886oAHo4ct}1M=%uDiq@qq& zxWg!!(36u`Ez!$nh(^z|TRg9#ZrO!Nhe^J@cHuG)1EW^W&6OA{6oY2e9hF3pGi0kT7E1LZCC@Z>pZbu<)mNHpzG|d`3T-@=0~L1YmU(=-tJn* z$Ae6Hrq%XJ@D0y(iH+W@MvwlR?2iI;+4Fx2 znGFKQE&#H4X&t1!#cp~MskOwf^LF%(ZCy&WT)A%0_Ln%92UVLIK@&4?2T@VOZS4Wm zcewS*EW1qZNVx{(d#ZP@m*5frSjFHS6;_CpVk-i6jZsiu7$K%^G;nBWi@+^G;L(|dXhXFEKuhF zWW2;g023L~=(0^eV!BHiF(d+Ni~fRkfZ=iSH|}1b&kx`K=3s%h|o@`ycOp6Kwv@q58B6R03M;Xsr!i9YhFLcSZP}G|p68w+>2dBX(x0K#Q}z zq>{Q?ON&(0z$UEf>l;aVW;AM zzw*Inyjt#`7Cv0+Z>o9RVzbb4G1s~)>~!5U!K*7w7^se5&WKQgVk2j|sFg#hUDUx; zQOIg__kOb8Y2Q_DFu@m!8@7cWmnnl+0+o+{%5$45)V^(j3!BfZT*J$)dh$MdT6xcM zDX9o)`o?QA2nZuO_@Kw_!9WmDYj0b`|FZZAYuMt~A27*6T%Ip^7`EpZ*>-S8meNuSABW;fN_uH`#oi{i`VhX zGz4FtvX&$kAqfN?Toy@pG7>|~R=3ZHpKCLE!)+Wy7sH|QP~=h)VCkB28uNAHUBnAZ z7?B|l9OJ+j4*1KRvSAoGMpttmlh~`-mjM*pK|a-Bre;vaH7dWbc{V(0LVcscsYNP( z-{2!GXfnT%?(BBzIQo4?s7tf0omQYG~4 zqGbDPeusPFLGmaV<+D_}_zM7QAO$_$dNUOLicx$gJc0>?Q8cC-?G0FA-u|oHrR}Ep z2Mbi8R787e({8y+ojF7ZLn zb8)e&sWaH$ef6*(KLfH-nb$ydBp_e3h5256`LX%<)>c0u-dZBR$ZBEn z>B);?$gOh=!yO@lr=oX8O)jl45HnlweM>FLC-*%-$cQe_t9qWRF`Xd}f)dDK537Z? zgPxggS}cgRno8Y+<(@3sQl_~>4`*^HoAO9vUL*>CJV%F;1Fv*N7txiNK*`i*C@vdI zgVQVF5z1tEYA%gDqJ`3gqJ2olXQSIbi7jc<%t*KHe!8LxPn!$FY)`{Yzg(z8^b;zL zzfH2IBM;fhqS{TFmbADcC@xvmfAoB}pG=h%vct#eXx{j&(8A~|q`2_XV#~dE@0#n^ znxttm;J|a-YQe`)3Ic^Sh2Om?lJJ&yF>vitpW9T3!;>TlAI+Ps_XQ&6LwczmldCQv z>C@A=8MoUy^ph4V)zIGe&!7Cb75DZd&);`1{Po4XUOj*|w(G&0II`!=C@oKRRL0I6 z&CfWC%gY}P@9rs}W+cWQG4|EIW`b{9c)A3Ya&Xy0r;HZ1;~2%-f4Q}plug&y#p&kf z^obR4DBJh-g&XM`8`?1x)fF}zAD2-S$+Tp`KsV*s6jVt@644^o5E`y8aW7NCexe~v z%n*FNz1zKeme9H9IkS@&H$K^ZJ!cX;m8kEK;>TY5b?D0pCtbf_kI{A8Tfqy5UOcIO zM*RdpZ`XC4{$b*bsMwYaU8*dQ!DSr#;F20YB<)c{>!P#(7C(M|`*Mtf39NKTVKl&vM)yXp^ae02_+5I<-6+YKvzWLoaa%+vFqZ z{`?9!MK?xU%-VhRxjL%*VFSg1@4c?5dP^_GkE??+eM_({-r^Q(eG@jQQEO^2rvNc( zC3>x66;Vsy@px^t&pLAS*d$&Slb^E}ydcpzAhatU6da$H4C$}hlnT*Lz3022KDP5) zPut38=&@9l#gyxp`BXRa=4E?VH<>C~Pg1E$pyFH}?YaIv3|UrGZCC0jQ?Z!lLUg5h z!ym1jWJyDEcfVc}C_(N##V`{6h-oe%pKa!RKbJnm+vHwuj=L>&m15&iOJ6ooEYhhFuT#p0(bI3?rX>H&i|O-m5PCIf{w> z{>CkdD0Q*17#lHoLDI8>+*oFWk`3!s=M*T#!VW_Op z{8s11GiT0d#0SBG1Rs>PYcH9*{hj|pjTf$VTdLHcP9W2~K}{!)O=^rmEqyXwFuJK+ zBE_fA(rw(}foF`|hk<-7X1yt^?f$fW2h7YIjfk_*=PRFFI#<-@_^ValEymEfIa%IK zfP-)atP>oolOzz?IUn3u)Y@-T>G!b?UhVTFi$9~RU*F3+z|q&H%+%F5CM~GdD*a8s zqoVmL1r`ipBE~J!dg|{|cnlltkz0|mAZxC>O{09~%VB7#5efhX|@LTOg($#f>0dKH*}z;htOUL)r=KUf~>BH#FQhUQ*AST$GtieIxCpDy^?) zD!{>_DX5ntjLZ()wOwd(q2MQNi@J%Y+@0w)BCgvV4;lB;*%S|vmZT-9;o1k87fKUN zGsC0jb9TiJ%eowx1GvRXR^OF?V}rL-mIu$!0G@!TRDbd$3u6^L{D})Dgv?`Y+(%=8 zGjN#=O{hYE0QeqtW?h2KF*kA7G$e}u>3pOY$lAs0gPY$gVDaOsu<3cCZ2vCkwwkv2 zqW|n-lfLgfE*6BcZ5?nz=fUn@65f(@3~o-)^XHVKZIrUof_HGVP3av=MRX&EUDReG zk5=c^lN%6WwW80-q{WGX{1Wa-31Fu>mW1myYzb?I4xG&&c3W^UCngMmdrPxhH~cqc zRxK5Kp=fnnE`fV#YPoHywyl@3QDzRHcIPk&1IkV<$Pa>J&+hX*K+TQjtxU0-#4s`I zseURY##v3eQ0m7MQv$gkNQO!}!&!1br=sm9ZOOFoVyn5k>-}QW8jp( zu20{6`}{|4O8Gduy4DyK%pT$o1Tiz+xyWi%cGMQreBKC>-t-jxtduKg-n%-&o^;V9 z&C}SVeNOgOav$*5`Xac&EV)aEgkadQ;^EB@9(01(CzcBj`l6rM4l<(I;4GK6$!=Tq z3I~Pr8@my_H=vouw-Y5C4Pb0n%WtJk_>Slo5c~{n?Q2_=nybpErUz{-6Wi3=E1PsV z@#tFlhOq)m&g~D%kSC=#me+?L?&JtA;j#qtjpGSkP9_gY6?ObCOU*EDE;$dW50$W* zx#C5%)L9P~s0eK0WXQhEq^-)>v{f$2Je#N3_z4|byTw+AbN!-CXzTXRtrbyX&hZQj z6wHIi^kTc7_y>dzW4yq5a_`(x6!kft2y-yK zmeEkNu-~_&E)vbrC?xLe+I;J3(w9de)3Kds8+5 zN4f_S^+m5`-QTdC0oAdEm36jF)3+H4Ew`U9?vUIc#a<^h1=T6JP546kVTaFA(eU-Pe?<#uys)Wi6Kdm;7_F5p<}1<&64C3VGx(;);Ux8wKE$+{zcM;-cx|VUo+KZ68L7ibkz&d!X!lxPo++k z5S%Cao0@0hj*8+sZ7>}1HVXle@^vvIxL1FjyQ21+|L|A8NZ{%OUn=eB?B>f&18q{4BpB>P}nnPN^)0PMcF2c&R^N>Xw8;!RkfBcl8{!yIyTXGjx*wQju_rCNDRx@z z*MjRH-NByZn7X_6--MhR$TnJS*YvSBT3=Q4jOe=+;x}d5lyI@S`K8}Y04Z)yS|p6S zbx2jKbkE5UnGCteV_ruKYA|ttuBG}7h8k#_#fxtyWcS)b7J3^Y1AsXafNsAQQrC0l zpv8){%6%6wNu~+eHC3p!WW|AsEeYz@o){pmUy(ie3$_Be>Kb+)i&-m-c9o62j|vB_ zg-LYrG0scuLr@;UM}JCHh(F{oBCNSv?g2r)SrPZ)7AjZ_pzY57=m9LDTSc4234)5Y zj|sXxX1gh|+z#ol#)^e_&LjxRUDJ)a)6q1rd7a1Jw$ou77z-=iMd2Cf^YOl8WMrJd z5eL6P{?tZ=z2RR`C;Uv{c~Sk3bz>p1BD_-h<&UQjpL~{3Tyb)-57~_LyW@0XVjw;j zp6B_Add0B$Sg&&v;n5hCUlfjz8sxmB-Q=cUF3ej5R2JS(ag@#+9I6U~RBg^KtH^g# zR%|n=C&X^5lfz&&GDPfT{i2|WvV!|~HocD z#zxA~ry(K770BihtdjkU-gjG=e3u3+Q8n`Hfpvs%oBvv3cBBYK+Rbj@9!#Dd%$La(<`ivT%--S;44h$jjaai#nyVUQ4e-4(^ zE4LJ-Yl%;a1P$ZIVeQu~e>?3jMuq7uF1k2p+SD(o3%B|oZ-+6a;O{)lQJ4$|#vJ5}U49?0-PusIMZnp!0dF3`y_% zgm$02)h~Gl4~Y%7`Kln9CJ35OXU~ltamB^BjkqUW8ow*J7${+~q2h>QhQ{i)Yl!p`oE zea~v>F-CH~0qp z0_x09C)Yb#pRt#$G`ZS@=p2aQ69mUGtF@lB$5`J+H}8}X2r+;-B0Iv@swIPq<_8xqDSBD{%cEthYe7K%YMDXzM*sX~uZE zWuYBZL*t7cPPaZxVSPlMa_QW5-m{gy#RM!fECBz7@Q3$%RMyV!PP3u2IjvPz z;VcpJ6*u5T{Z_)x6=jcQ%ZCRy@f&RG=ccaIixq&B zhLcbE0-#^;)y-7mhZ!gVmb}v~@B4k5T>NnHN5whH$CuKTiN5;2;`FF%ct!|h1m~w=$>~$E~0BeYPzS+#4XPd z#c?G!uYt3ZpgqL`>)dnl+SGF6_PSMiwg5nI6_>vXdJOVD92G=S2%!@DRWlentpF5Q*WCht4h z*Ta{rrPJ3{Gi6q;jWFho^re}|)1|p@ts36{^yw1-ixhbDXy0W+%6-~nuFh#ZU+td` z3_m_y?b9ofI|U>MFo27hu|y}c$#s&~UsF>vCa5mxUeZlcB0}FaAWFH~C~9jZx@5%8iJH6AyYh_Aqqh%#7Iy~)_hZ-6N)--UTn@ND%RV=W~iaba!PV}BK_h4LZNB{EcANzQrsU9DDxjun?L zTEbz^LX1@9Bo-*d6->^0R(2$_om2;Yw%FC0iLonyap=FB^jsDBAcvQftH>q>lzjqcYJ z)Z5Y^R8bkF8uR;ebBDKl7F*ob27vKfT8ev$*GA*ot<&l2waXb3vzk zGkA3dyvoGb$gF(FYqxYEt9;N$-@~N7&LguCIa*PskInqLxU8>WV!9w8khO|3l@&>u zAG5AwNj1~U7910Oq#Sy)wjDA1usliz8R-u6E6NuQa#C&|=U;)Z&i3Cs^@!6>)0xv?P$7VwQTA zz6tAVo0*fp=<86J#x>*rr@``);(S?dka+vd&x@zLz5c8eGxW3g0FIkrl{FPiL2eWW zfAR2^|3Zh7gER4S`ncz81y=zxA-BcxH^zP=xOu7T_2QBis2gJw>(C|awE5OK%!--eD^_N{!S)jtr z_OiCYLL_9;#M5N2(6w^8KRN?-x)<0zb!(s-dlE^{EfOZysEi)XwtV$!f3F?eb+VB; z-wRCptFUO)gf;hS^;XxAs&{vHXKcVD`pQT^8Zjuh&yzZE6I$U5N`RM; zvV*B~olZbRET%L1VtE93F;JnTOOt#~AMN*qY-g@`F{%-?Y6HaUG}U!l3yKHrWMr|& zu0FGZ947TDty;N#cGXRQ<>M7xwpcjfWhe*X@7pUCTM$M_Im3F~>WmkXr6g~wlvM31Q4lV& z14?r~f5tKcoG6}TZi#LRDxMH_Os`LX;G)ygh^Zd>y@{vkw8f)mDQPa2r2bvouEdj` zT-pIynX&|{J|%oIMOvNw5S@MyJwUVRI7~hnQVn(`te{smlze9j1hF}78%S4oY^Dg8 zDTeNi)}1}ZLsg0uW}mEZ^GdK zmD_r(e$^!U5bp9f(gJUNP)(Euz#d5`4=B0kJZmn;d>X`gVK1MPJc?Be<;R+BzU@tni__Vdv9g-|}RxSYI_wlKd*6p|(X7RknrsaM+(+W+Oh$3cv6%+Ku9AjpuM1|fv~G@7MMLq5+5jb143uL?l>Og;KA4MUHH zcTVwbPk08nC-+$y%Gac}39ScwG0E(4Gn9Ln?oNJK)@R_rU^~Q=yfSX!*%X6yL>G+M zS5}EfqgSH;PD;0y&HkI3WZJIz$$aaEa~;1L=0TCJ*h2FC9N7JwN00%JDqTljm_e4_ zZZe{(wtraKGC28B)gw)zO6fIUMH57^={92~!&rK?iHU95tKuiA9`N!elMGe;oV29- zCdL&t$6hmpvI(uBd{v7o*i!_hyuUc&b5&>ILo4a_`b5)r@h{4xT;H6erQN~EsUEL>beqF|<1$uKi*WwJ~y;1=s)>4u7uM z8zAjBBma>0-Sbttl1aA7Zp1IXtt=q2ma;}Cas5rhtDhF~8l8^@Kf$Eiby$UMS&wam z-C~Tu`i|DFPtnmqhsCjb{PirNcnc2es`(eG@D8U{03mA?_!Nz&u3PNu;U)?82+x+ z%J=Wz&(50Rr(;$Ia9!j*#%di64YRILS(PDxGQR2kBZ9x2JxIxW{uo(4)U?P@HUE9n z`sEjiHF4RV3O9U)8rq?UpQH|gV=E=ErG>JblE{Wh2X%hIDF|nonMZ2Y8FR}vQ*c#8 zKDu>`GdFd^pkCl$hd=D$67}JBD_}WLHb||H#JZ=KwRZUrEKZ%`fdhM5@XvvrxscX* zcIII$azaD&Y|+4{sVV%R4}N)~O}s2TP4HT|PK(EArd;{K7iw*BKO}}Qi#skW($X}Nm_A&gsOTgg*pE=B2}3Io4%|4&!%QQ4THpW2sLnMvRf6L2Sz`(eq6|FwP)Sq z#>S5nvA~6hIWV?^U1xMj<{pjBvA9{fDmzG9)3}PLEP981mtS%WP-pHq0btKFBL5uF z(_`0Vm}2G=KjTDLX8_Nl4BUoRdZ{)}IaRM*WmP`IWc#orh2Kl2&cn|or28);Q~I`< zbHJCsa2_xpFy9Qbc!G4>Ua8dCMXci?cvK;^*U|?0ZM);b1WkQrp>eaIc?4&KwjpYM z2)YVH9T#;^>Fyf9PvQXux8Xp!CDOz#>ixlN^pM-_C9v|^7k5j1sp zLH|an>tKQV)MI6CMUSMhuY=`U*YL*MdA97_cYy7_8vn!o?=M6(pA$MhNExfGvbaA{ z&JAkZeRY7iVaW*VeA(x&UQd!qnyQR95E`|w#Mqk{wws5(2EP1mIufwouAbR;b?ZP( ze6FGg-aC^Q_n-GJn|Q2?7X0g>J}u<|e&pP{koQcMCqtX0e?E3|``-uB;M4o^pO+T@ z#4?1>RB{|J1Fzmq|Kn-=bGyI|+y8UQ|1Qrk{JYP;>o0fyIlh0F?|T2;>fiN)7yq2j zzstK~|8Dv3I{F_U`5zYs$Q^$E|7GhR^EA#j$tPQ|8$&W+!If@%F3&Lc*i+j`5mzU2 zw4f=x;+f^bDq2u9+44OhAmXQNFoMjQ&|PJ09)H{PILB_G7DyZ};JXYRe%Pe~SK9NR zEB-P6r%;p{y#IGRtI{vSLs85a+;}=%)PrnJU~PQh3{+7a#&z$u-rQ#zQVMc4M5;AM zqsT|mw7_GZZzy<~LY3v$#S>J!hm_9G=0P24ePJ&~Vh+FMNl7S3^cLDSu)CJbLKEnC zJF+<3hyy1-cLaX>e@_4Aw44xXu`syG#GH>0J4GWNpA6=`w7nGChn%y(wL@7hhSr`P z&)=Dz3W7KMINTp2NN)*`+DeQa_fdJPOc^B|l7aKCqWkwj-L0^Oc03I0YUJ-mQV_$o zySezC^E*gox2EYRemH7`w)=Da6No#Ml1gTw5WY@ZKcZRnRoHUgWLz~MddhvpeU!5@ z$|20n4KJa&!9cA6)%Xd2aLFT41U3~n?cx%c(-E@oaiS-a9elc)s7EFI2{a&34q*1p zPNOs(WOsZ@IU{NzOt<4x+8tVEN4`Pg0=uWOw;DLC^~c}fjf^zI3fitM_Y?1~3D3)L zYLe(QExS^UYevV~V^CQSCXX)4yxgXhM9}x*{GSz0;;g@cr9WC_Uu8j}H0wa(oywmB<#UQRYu2F?>8J7P=_K4>N=D)PMGmZJFGy(ndxl{( zJNXh11O%j(jtZ9SolhBhExT(D(whAlVQgK?L!JXxwev$z{-B-u`jwZv^nrZN9ExCb z^V*NN9`?Yn%F+Fe5*M2j_i(ubP-_)j9(7DE>)L6WciXjR&jm_ZghTP|CtzLMqn22% zcFpyi)?%Bimax@Y^KQAXCR+qX)12d?30HVa1IZiB2o30+O${t%7Zg|~%mj9kWSp}5 zY?xsTL$ZNI7E|5xOWKsOJ=;@(vi9Ls_GmOu7kS+>v)cfD+ds2*HH-Y6?#!7#bpJ}9 zr)KUiI{bIG$FQ^muEuK%`|A|cTA8ed)ppn4b#1j-_Rtnfg&R5~0~GuXp_=}-RVigM z6-`A?wpG29*R?V~DWL#|zXTkVXFfK_-NqtETI}BGet7lZVhVq;l~D6Az-$sM@P=qn z4+UPEDk#tCk+O#%6@zwZOixr+I+;rt^3r-0nQ+Jq+HxrNNyO~QB(dH38~2HA#|mCo zZfMlRM*e8(tBTM$dA4K%Q|6fo^};iNf*1Q=tX9ScWX}}qg$fVk!I~*^x9nNmv&(ZR zm}iZGDLt%Xo{J~=^($Ib*_k^8bd^zjh--U~VaNJGEXQb%isf-}2h1%1NKXGR!JV@3 zQ5`3@@S{pPt2T3DJEn9EJ~Qm?<-<+2qS)VKl%-)t%R|v_LUST1Z?4+Nf}1*r1nz!I zU4_UAlKLFBm{R6rY3!d)l9^D3;z1XQlsC;yRQgj%B9^SVnDWPAsW(4`wj32Uh^ZE= z&fa&6BcZ?7uV02fsmQh4&IALJFO!z3aH=W>?Fn*6HWb?phn zw;#>)T;zHGkqzL1h5(G_eMra@cIo340;Bf<^1C_k?!Whl5B%+-E&}W60fhB$zyI=- zG@t0PsDM^4aCE~nU>O9viF@Ez-fYIi=-&zg=6p7Z_pDgL8%?>_yHZneYE zZt!mzN3Li3uh(lPWRl#twWz20^-Q4?Ekg*<>63&@88O&jaHH^NkU9R2&F73iXmkgGJ_AY zGs9TNnnXwu8Cxilts&ctWl(k|%h=bEec$)}Ig{__d4B)=uIqXJ_+8KMd9LsK4;N$3 zIrq8m*S(zcKKFg6ZHNG46--Yrr<>__e=lAajqYYsTRz0LQW zo3zq)N5wp|hT7-S%zlJ{dsceDw*5l(>8j**y&B?j=P%FrT_Vx;TPmS{KO9MnSQMwp ze&Zc645&+_Or}r8UUu2@0Pz#;Sz$%wyQS|dU?e`OF>KEisP&711Ae5YY^bb`bh_~G z2o4N8y}2}u2M{jMu*8e?Uf7*$4jbUsTTR))T4Il|ez^GH*A6gF7k1WuZ@sOV+h2_D z6Yp$`-0?K5+m)+R+nU%|NtkyZ=1#e|8qR-@v@<8=oI%{Du_wC~b*= zGJXnN1!-Z{*VqSW!gVY8S;E(>%yQV*f;LZMzl6O3-XUn4(M**XP&b2Y#S@dS4R;nc zlJ;|TW>4nN?IyXDWW&A{x-OMhn@|aq!I@q@D}w>@uO=FJ2JcX%?Ms({k@S*Ue%1B- zDNkZzo1aC-mpQQz^vD7ex+FLM(e)ajBEJs;Ji0#ZDBFsDU& z`Sn{7%N;&$LoQ_tVRbfmdsiN_=B@1wWzv__w%xa?xR~5i)PBy4T!&{Bd=n2F)(cR2 zLRYEND#`7G{eISFp68RLU6QvjzJZbTP*!rkfLotZwivZ3iGwonZb6Oo{kMW?1=OlQ zrE^mW#3aJ$P=yMe+(1As-~7*qdn=>2lXQ3?k9hp{;JQ41_{%N3pu;0Jzdcwk`yFCRT|MzP%Mq)rBMb5jZP{F@ zO?q^4dp=uA3~f@+>B{oxSMMG58XFulL@)J0maGco-U86q-wiUalo` zQh5FtJ>ubkICGNkYSXQoH0qci! z0bTBkmTZd>oKwLYw@+JE#}WLl4L_c_|ABJq$CKxdPtIb38Q&{JQns&-u7yGA^G5%SP`Bb6a1JrlNIc%!exGL{RSjvbpsNc>;Z{+P(Y$FHz1MD z|4NeY%TN?ela)*1QIrAZ9I-7IWt39FS>?Kk zTy!9N{}}jK`TlR(#^H1nZ%{9hlNnwRgIOr)obe~2KWluJr%CIGlby~>@m9#t8<7atlyDT86ew_ZI`QA+TH z{hE+Ws0@D0ahR5ElyUComR-Jrl1B-VN$I0j-qGr~8kMGkqaXT$Q3UYS?~i1a=0yY9 zcV&1WN#2noW-BM&e+ZV{#zj$VWdqscZvJ(NCa>iq(+O&DyS*OE*I;Y0SAxSFRfDw?T>?n9l7xyklmR27nhC?n8^$Yz=B}be`YZ;) zjVE6Q(HOA#a`pYI@_>Z+1=C7PZ9sM1St@vFREV`u4_*Y95BP!S#?Y8Y zYu7_-r*RIn`$=nOQwiFo-uwTfor2c)Qs&DLUaxf?cHYO6Jg0^^W}stzy%HP?|^hd0?g^R9eh-$fid!RFZ!{KVXm zT)g_{c)-)2TVg)nf^XgSc^+&rCeKl=$oHRgjek*vh?PR~QyD(}?HMf(SNix-UQFqx z!{t-MiA=RM6G<#Q4HE;>kA6(#n!S=vLQwHF?(-!??6Mh+s!-U>Wqkm% zGXmq2?C#v zuzO1Wm3KU;H*0~BrkJ-FIyx_()l&LcdHA03gTD^tollZemuD2)vN>*XPKjtZ$V#Kn z?)xb|yLqp|5 zOxBtP#zLJ@hjUJMw3PSR2KA9%Vr;cl`LMUADtCrjmdr%%>Kgib|m?YB_$LP>`SM2ng2&vkSQV0%yE3e!}9O&#k0G3XkRW3M?%3Ncj%qkB9L5l?YHP z^SnepI5bXIgXma#N%}Z*U2)BfuUim`)~G*E*Q+snMQd@=>)4}F%j`^6#mX-@gLUZ< zv#W{|m0!n#0;_skjIT_oHClT8V9`)zU(ApF5H@WB?1g)$rqhTFzTD*ldkzD>8{S{@ zwnyQt?vm3BfN9En_SsU}5EUZGfug~?DdGG)9Jr+p3TZ5{PfQLD2pN}fI{hmketJZt*l!nP--f)EWNLA9(fa+O=E<^Eqj=NgRY@UMaO zqWi*{$A6(bl!G>OzX{1{XTyF7szY*`YD;_h^6zDzl46w=$njNA#tnLlt~lb<$PabcsIJc1AOyYb=ud$3aq z&gb58nmWG-ht(kbw%#ln4>N1FwrFUCF%Lx$&`3Q42iD%}qeq@a2lW~6JEY53BYMM3 z@)a#NBZQZO&X}1KJ{_NQ%}Dnf!lxr`lN>5OZFl(e(BBfCl`rxB5Vx_xtB88a_R8b< zA*GwI59M6~*7#7UL351m@%xpC(jmOVcq0o7%jP@c+Dvy+H6j7r8L&Kz$KcaM^vYK0 zPiJRl3Tt(Qz4SzsKSDaZ$MV_!6i(tBC|3RY-)2(=Il) zWba)Hnnt6If}9KCHkiy*$LybeN1oN$qnN8kitOt=Y;3T~r5QaR^fZ*d=^RaIg5;-j z#wN_BSLdz#n&~?{Pd_E4LEl5I)4|z58<;uM8l&IqcYT_JF=Fyu8X(s#c7`5|!!Mp| zL=q77r)_p`$utz=xoz=M{Mc?k-gIWxN<$pk9OGisU$pwe)HXin%3@1Ty*GN==gOI~ z+c@$aS!aCzLqy2OuJ?L!)Ewlkr`!BafvV4D^LQ0aSGO)luyA#+EIyn+!R<-H*1RWY zUL|A9G6-E=AsF?KPYk>hf8Af_o1J|efWHQjURZR`tniwC&lqoZXNc56!Hhl1%o$BA zvSQ)tO4o{UXdT#gwcfp%HaDuGugx;swevpLU$aG)`Z;sSkGar*TC^CHuN6n}?+OAh z2`ZzR^=7s8uSpMMeh#f4o_5Z2pchG?r1RNoX7Z&TZV5P4qz9U^6cyT{Sbaa;P5rfN*HJYXi5+Oqp6wIyxnJ zU6!ZOv(&X;L#8aN9zja(4e}q7VnuNFc2z^l)(UDDi!kTx3rAN8H~INeoOdyKs$zT( zd$mMrq6DR=p6S-u_@kQ3%iptNp*%9;$!n*O))qpK-mZV2Op9fdA;D}&+t<+cfq|zC z;y-Br9)B7aIfr#ZdogGybd@G=`P@P@bJY?6D5xV+Ii~31Ay1zcwgzM5B zkMUpZ02PTnY7pa13Fy(qj;c4To|Oo250wmNI6TI`vW^m-X$LENbsQeMwKU{rBdd?rs^{Cp{jI*f0*IM1$Tqi4y>^Z33>Ps>EL zTi~xDXRf-H4IzE$VUuI+i%;k;4P>n`v<@}Ym6|PIKua*~@Ud*gsHLSUK@9cp7(#S7 z(b$3y8j-r~W4_do>?MDf6L$F5HLm2c3hJ^=qr~+^5AsnbTL+b0ENjR-a$?|V-1O*d z`?indPQhkw3dfyGZPPMPZuejz6Ah7G@Pg*>FBmv*^Rf~_avG_9pY$+fD}X3$K9HtPR)ariSAM`ToVhJJAh+Nb8LnJt;zG=TfenG50XzHM!{WF^9ZOA z8~ay##;cKUeM99hZKItwU&}4RZH#*eeWV>y!&VQBikvYqaj56a@_3E7!4VmTc%mCh zgi3ry&F+K{J-AFdhGu^KTKP~k!6(~Z_)t9OjZ9lf!fVe8525PKmwj%WEU|g`J+E^a z@Rr~DVXe6s48inE+o*%6y>fJ{-^_<16w!E_uPf%@ys z1@vrBeg^v@+|tq#5=i`udl7DA^tr~>dZ5(Pij;3sbNXorIK8sxH1nqA*VU$yyF;yQ zupf@lg#yP}x11uMuJ$!&>^n&vv(I%#+Ddamznt^O+wWc>qN3KKzA3Cf_<5hyE`QIh z|86pBdTds^XtByT|4okyQR0!a>Ln?0L-&XM54QL-{!=_;V=5UUa zms|4#_i7NOA=z7R-Zm{e`99u1?Y?UxT8B+`ip?BIwaqVSBP6>vfW*$Km=v|vDbfw` zY${`{msY3qx`X|G!6s2Yq~<>MUGFtZr$xAGUr&hh$K$@|cEH&tBae?whvd(a_V>1d z2kd^wb*JqQo4^~~@^S_4MO@5j<%{Tuh=|PqVq?5a?+vQ7<3uQely6GLO}`#vS)OV(yG|i z@=~*l?Wp3e*&k~TK9@pXyJ=66PWY%J#wS8|nBOr(D2HlM@e)ym}enrM1D{sqpyB%kh|Ik}xUNQC7e1@%K#;>XK(LR_~jX7uOm!P!LS) zaf0mZ1@!3XC^(xw*I!J35uN538DCg~DDp2trD8^fpqlrT^ouR>>4TD(vDr<35TP4TBCG;~V(P-&_u$pd;r5u*3o&ej@Vd%clKunxg zaY57vrZebSu+>y63ir-l+^a@V&$!Po;snK?_G&s2`L8#m7304wmxeb46JzYPYLYjD zh&#wnWsA6?Y(Ff!pdR#EUhfmycCq~Qrz%9T%RGD-Pa@qVx=yc5wxSl{%F4<=o4$|C942Bp{!(_@H8c*>hc0`}FS~NN!@QS&Za6ya z!kj#{t#ZS_ie%3QfC*;U>*s`3Mfz^9Z)($nqphn#Ji_^s3PSeWi5WgeOWvNZik&{H zre0gSo}ay^UAp(<5ngS;@qVuRynwa_YgPLE^fp^YS$h1j@fNd{>F?`Q?kQoN4a!!zXFC!w@NXpFI7k=^+13q=q{Mn+N> zJHXxN?XD0xx&5we6L10=B)t)rT&JhA%7lf5*VxcpvL3o`iEDHH86ZLiISe2|E|RoW zMS3V08ykDrs6L2`vLT-4S7DTpz0C)T(CGwcBm`t;yl-h#d!(kWt`1XE(L%jojZMsZ ztG3Brbo+|&5Oa7q)9^5|!~`%c+0v<`HZ0cxlhe8?6|Xr?aoRb@82q+L$l{hpv0%oW z0k%Gfk8g60Kjq!2EDIIVXic>n%!45}>_abNy+E6s{Sz z^2WI&Yu@D7ra{{3Ucy;!&e#w0MjqaBXWX+Earrki*WI#f!l&9@jdAV0LgR>BaAT5Z9XWkI7GYzb<<1YB<<+!3;3|_8QG1U<)(I5 z>v?L470GF1!6;-AZg0N`GRUBwq-1{NsbPGEPS(^go{?49VzEQV(6b#_AdqbcOs)NJ zwb|UU{@E6eAmyGJ>f!av2E_^S`M2&=lU1#Tc+I*$&P)owZKR5x^1a$5-r1N$z%z=; zJij;xg0J3}1zPw!f#V+&=N@~Y1{F;>5#BeFit_8#R!L7U-63o|rN6YDg)Mm3q&Fe^ z#dFtf0Yb$vC&cTxU&NL%wPw{5&G_7+>ux9Y2wbaywYPg48rDQP=ue}rq(RH>mEC?l z@VX>x&$m~D1ig|;2#HCFl)8W}?C8h}Y9CP1$T*Q-gY@m|2sz@`N10oMW8X#Yo{t@# zY&}7P;!;n6eG-VT7JmN(fhCx7autGA7+mLv(8)4bWkaXk)~KyQ=p7T@AI2vpUXh?` zpyN|Rh^H^!x@=|J6fXnv=yqr)`3GNfOFGEuGPW|wNLZQ-wMtog22SNKn>h9t8xMs! z1Wm8r%E66%t(3Cpt*%Z%w^sLMkC_&xoVTy*=BH2}XPrvV`~0pFloY(j6!~E$=Alcn zwz5C!?6f1=S0{2TnZKaK*2W4~DiS!Jjr$mf?-SU{&F&bonf10Ts!X{mb${T*qlnO$ z*}}mA*HgN=;dzjgz(^OJi&R+>TSarlhJIUph~bP%%LErRAViCFYOb1&SZq^!tGDzw z>w8SUPK4KYjhx4u7|dRN_Vwi!_Nk4P838WGz6lBmtvCm_XFe`*3kXoQ$y>**S5QrM zJL{TM+RGxAmR_}yia3^5F#4p3F&+h#>&?`@rXaOU7tOW@=Bz?zxTWMSOxQn^Vr%?% zHEGaR*MvD|`2>;1_&iBa7JQJFI~@mj*qv(*PXTF#n%8%4xboZhy0Bh%2^C>f6__q4FKl&dc(bB(S41)Uw4| zH|dbz7`{=Q_u!j>a$2W-AsH65yu4Iddi~n9>w>GH7XvPkbRT@q3DpP>84UTT!dS%- zasI-2oO?p6mVtqu0d*p=9>!3m!oqrCWE-g$zLA|BZ=kJ*3>7gDFnIQ)rORzwlin*A zhr5}xJ%vvZrmE;De8P-YRq-|GGM5PrXzBIUF5y+G0*|oZZo)fDLqs!f8LJKz2(A;N z__@~%o{{4?p_i5zVTZlv<-LVEga}&wdUDRlzh(J5Fs3K!dEy0};V)!uX&gJNU?bTJ zF614@BZ%pXIJe#hfE{it6N|$&?XJ_mqQ!y!!Xkz9!(3s_LwJZz<_0@DO-fyB7~j{| zr(f*s2`+{JS?b1nxbA1Ci5Y7XFV4X^3inN{tBw9-2`nTR6x@P9ra_iUSH5*5sN6w+ z?6d_@ZAE}ugc%LGfKF3>{~UBZuD+Ka{QAdX=xK1bEU-jp3_TXBKm~;&&u!;bLg4n=?Dqa_e>YkS z>-=NUTW}vCrhL4Z?%w5BY-|^NpV`7qd<7+aMSuILiNE)M_vCwVQmW-E4hh(pk%8NY z*3_4f#|Z-(>+pUAvCl*93~9JX-7wCW+a~@F-fTG`-xXj3f)H z8qaq+v3+d1M4LnC%2ay>$jV;mu0)q^@~_$q0WVK2^UlJ;;?;I`Hgnr}xcV8Ear|F- z>JfvR&`6@!&SH%RH77)%eiNUZoLpE~n3k3XQpAbqfii+K9thZO{6tY|Tr}-ZN*?H}4j)NA$*RQLpsevn(p-||g{$^WlpfI{l9~(*R z8^jwmA=0Lo!iX!2l{e6y>-{dXWn{4TJ2M=J(cc40Wni)pNTkjFGX%Z^c;Cv(%4l)( z>gsBxhYv$QGALMPR)AblX-A9a&qsdv(1V*~2f&Eb68H6)?p&~+2yiqDwkT@earJ`F z3AVi*0F5BI9lJcH7AtAnSFo5MEosxW5W=bIa#4+*=B1JMAgzsRyr%3?-pvrTFM?KRcajUR7|i;9ZgzTIt=KQ=aYft57@G#sj8bkW&co$f?a zNdWxs&6$(1u(^8gtrbBh9WUJ_oJ?8!eX5X`{@y4#vME8%(7?bzS2rpF)G+`3v%lB{ z-CyLiJl4P|g;G^lHv|*`$w!J9mbxw)Z=2up-rFg381Ip*OVdp0DQf^>uKLGY_B$Jk zYgtY!6HhIT!YWQ*y4$sPdmo>)+q!36vuC(N7FlC=XWnC{0g3L@7cKMeP{0*_MnN`U z{zAWsiiu$se&4Ip*7)}Bl8oC-SN1TdFmua(2&kEfi3v#amIfKyVARG0IXO{L`^BLu z5HJ~*xUKf&Ter5hN}>7+fG~hm=BOpxzkm8}Zf*jgfp{D2mrM`huegkE*C7bEPFYg7 z08&Sw+pdYl!UKE7V2#l=z2q#nIN6#4gTZFy=D>!-C0UQIJw#Juqsq8dzTRxYAgCv= zsi_$r9&WiE%up?(ewV9Af3c<$g86alPobJ zH%*l5IJmeXhImA2O?q;xYicAc^$RhkAndiWngU$|;w|#^H1f^N&AIQoE-VaI01}|r zuV05kWjwdqQ2af`OArV|7(J2 zIkACj3msEaRzJ;|%RDx(I6YE%+DRHctW|-9thySzdS&eDJc=90*$x!@!H1m&3>&1= z0VR;5qu(DAF03A9=-k-YC_F8QoV?68Q=UJvrIC16IzFu+kqD( zSR5;u@k-?S9h7;kr`&0>g%65E1(OwpXOS^QdCrQltbZmdKWg))S^jgK0)rA8!O;TN z+mQ^5EGLY1FwIWj`c;G9p(f3YU0q>IxJy)({)k9Ygqx&&*D~By-(Zco*ZW9uLR1~X zS&nkrZZgQY)UGZY`%EkEJ!A$9Vl#_rAm2XyXP74%>EZl6|%hBXnP z`mmD^iDI#Va|<2o1KuK7m?ZO?z6frxb6(+ub@76&gCX9(+ztfNrLZWvyn-=C8pK4F zCz~Lp>sV%yLMIKL3jFDxPNlx{C}*ygZoZ>2S@^0-Zx~`J({{2BKcQ#rswJBro%)*i z+!3%VV@7}Tb1g#pM=~~}VH7F@*d{>OXDCYOa(Y3Q`J4&~a(hK)5iYqoUtMq&Gg*{K zW0%bWrU7!3R$Gvc?ukaJq{WBt$qGGwaHzhbqY=!Xu!195Bit~MBHYGM)tk&DL{aoL zEKCWw1t1KK*EZA^3jW?Wl(jHu1pmtk+ppfXj2PSw1dy;&q;L%~Fh+6>V-A>>=j_)2 zapd?j)Tb{Vw%_#?O#H?e5&0TM)>c+R?Sz#PxD`}XqKE~>Z$-^{O%!t(eKUf$h~jXh z3Y8{w?Li)_GgllECMFgX6jxFsRhzVC z4<2P$Ixe=Wg}`T&(QY*f-TZFbo&Uh)DfKO?J86m1P&xFPn23es;&jo}96v}5G0(1W z8G(|^o~DZ|5k>2qUp*d)5}ZoL7N@3~AW`~HrFEi;+NunT|8R}&iFhQhO`4rDtR{a( zD3PnD#qU80U)G&KHw-zGujkDYIEJDT8)#VSK_NucBcdx1Z%6S%+ks)k=PzIb>L<_q znx@lnRHU#7yT8uZ)of^Nv>MDg7$y>?uUBldj1m41)+(vl?z1xat+jGH=02i@01T*Y zZ%ZN67D36cv~whLMR@P;mApgkuC%I0*zjkDkRs%6WYHtHUKtl8raml4^dm!sdTLEy z7tY*`%+Ti`wY9&39L&S>k;Jh`{+rJ%nsRdWoRMTdXmKc;Ee&VLEMJv9I=WL#$`9^o z!P<^7_fNq0Qg_@M5Cl8FaUycCg_L}3EQz&X<%Ht1r)@gtHT_`14aJIztc5c-BICwe z+LH5OzL8F+4q#?x^uAg5^QJ;LP78V`bF>_Xc+`eiq7ag^`0DkHH~voK>~Bc|p$)P( z=n^%@He-;a4On%_^VdncZu;fHBbgIHiBKf)&23OcPnhV%;g(vUoWf4szejT-B@PC8 zl4kMp``dB?qnaKi-LwM7+0){}H5Cnj($}35T1X<6pCCwT$V{t5G%ggxZAz^nDYH4DW5ON8ZC@e&nWQ%+t zEcFZM$U8^N*_Pj?xsg@}f^PdYdK@8i)6jzEnzVtiExW=#LoNApLR06jD)r(#p%jA; zB6o@++{A$`hW|X2De3YzRrd1)>KCgZt#^c0n`ov0mva=k!NGE>r6>6(xhUL;^ML(8 z%a2dL@@G_IkIBok>b8fbU2(PmMr`U%pkfcM_}cs>)ix5}Xv*)2jwd5{;8OID6_m3m z%9KaYC^z1&v3nE5QD`&n)@L+cc-83yC#h{Fs~==Hf+sbad`=i{@r&tC*PMtJrK>iD zeh(}WOOK7yY4*_$Dk@jhzHDY3frV%nECKK3WxVo(`+3fmW?Go#h&K z>o9s<*mpPbi?B{Hav8G-8Ku=G0h?{gn>}YcPV@@rnRkCl)+WERR^|yjZL8cH=EAf} zg}XkM&Bs}AtN!8!iCt#K-Nj4#OYrx#tGSdWI-P<<3&zNg(L`}1!ETaGXIqCNDjbM( zj)Hvr2ct0|*yDeOdE#pkV3)1H>u+`{?IH>ehWR6eQ-~~s5{6z}qwVBvY%f8>I#4DA z)lJftw9yVH260E75wRPk84MlWf)!|$-P5Nv1$)g06ZtB9rz<)BuS*A^5=4G$ zzw7?`v_m0QI2L%Q3ZK53*e3>y2*vPmbKhU4H+cN3t=z$%&0fEiagQHTFE zf%CkP9hS7@TZ_;u(7-~Zf3!OchKULz3TD_Ml`<{HTd=}v!1Ua7wOq#F4!S*hjpG_X zWOH*RPgO;ORd+gzKh)jE+Q~`VpWucA5osd(5wjApab@&n-_-Dp}SEQmzCfH=I$&>E~)$0(0umj8q{mJ66}$c*71n&{{+ z;23&EZ=x*bLbr^}^S@Y)3J|s|5rcKmSmMpItCB?$%_MD)7ZBvrlTE);75Wj%t`WC2{(ru#F#?M@(tAhD5O*#n|zmZ~8? zSWUrEIwKOKDLB8o{V*N%T!(|5)32EO@ zDfnOnc|H9s2FNYP2&QvRzl-5DA#wgH2yh|{`_skH+6D!E*;uLSh(KgdA#y6HLzt74 zNbBQ(F|@^R z^fS~kJrNG~0wD|jB_lXb1<$t*bQ;C0Fz8qX zLs$yS8%H%F@%ogph`@hoX$5clP2`rH(F5PW3_bk{xRpi55 z?yzI8RAlN^U($wf6Vh!FYGe4H=Y=^76DyF>jVyS5qlNm3Ey}^y+tOWYj&nZhQcl!{ zNM}a$C|yh^Xy2nw;qA29fZ@fYL0CwM4H*GL1I&LK$fMmdE>P&0oS9fP5{LD){qTqK z@K#G5dZ+v#%!Oh!Fj0CUEDe%Z*3u5J_-adpCG99v2UDb`hBkzm;GbfPKXo0=avix@ z8^Jyn^fl9Bwq7bLes%xEAMm}%QXBQTqODMF#^fBK)jq{R^9>ad#Ez|NNKd8Ap|lL^ zWufGy`9IrSbRMHZ$`_)qhNH~mt7tagd8+Xu^tI>&a{}C;vg*vZ4wS9 z?AGki{D>vY;_-q3Oe>LXb<>jrd@5<)llOPw~t{!BxaKG;ZZjqnl7H{GU&j1UY*4@iKv->sn6Yd$?%tgW?kht zwkK3QpxHqWGpQOn_td=K{+ZuzYaPv%Yb*wC$M4X;dF)F@B)%?F>~7R{SvW8mx-M=R zkdlaxhsM9&8^`AxFzO_vz4@1JdMyjp@q2!a{Ym_KbO|@HETXMFe$eWN;dZ9p+gDJE zE|qC_e^9G+;DDJw+%$}EmIM)rk3=m$?Dp7dXV0H|pB${nDCE-^+}$^L!}QLDA=V1fFhGjme5t?K(YG-EP>=}(`( zttpPjgp6cHp(&Gw2U~5wiAj?!t;J3si5f9`v^qQB@z-e`{pwcslcbGoP575GNW^4b zSKCToK3JC0b=+C{=Qq*+&EK;3k6a%+?Ooak7XxElcU07M)I^&(x)@7E&(o}0P~ zKd^MLzI@HX(a}y?MC3X6Ll}GT4~&x_a*A;bv=g?}(sjI#wzV}yInrpQb1*eQqn;aK ru$L`ujm%9QE<3mwIht5pwl%Uu9ei|t+H{@vO=ZQ$4>A@0e)&HD4eJuv diff --git a/documents/wiki_images/amazon/pics-ashes.png b/documents/wiki_images/amazon/pics-ashes.png deleted file mode 100644 index 0cf0aa1de0e9d7ad5798023e03c574255a096ec8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410889 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%0A**e=Yx0767LJlLx=J>zxZhKUA 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°Avk|L))ZU(fyg+5erqEn5En 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

p^%iX|OTyy= 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

t$x?O#f>~`q{ye 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

nD5V_vMb+B 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 Date: Wed, 10 May 2017 15:54:19 +0300 Subject: [PATCH 69/93] fix build --- .../services/assignments/AmazonOrderAssignmentsManager.scala | 2 +- .../app/services/assignments/AmazonOrderWatchersManager.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala b/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala index d6a0adec14..428f321827 100644 --- a/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala +++ b/phoenix-scala/app/services/assignments/AmazonOrderAssignmentsManager.scala @@ -3,7 +3,7 @@ package services.assignments import models.cord._ import models.{Assignment, NotificationSubscription} import responses.cord.AmazonOrderResponse._ -import slick.driver.PostgresDriver.api._ +import slick.jdbc.PostgresProfile.api._ import utils.aliases._ import utils.db._ diff --git a/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala b/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala index 3ac1379a43..84d1e15b07 100644 --- a/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala +++ b/phoenix-scala/app/services/assignments/AmazonOrderWatchersManager.scala @@ -3,7 +3,7 @@ package services.assignments import models.cord._ import models.{Assignment, NotificationSubscription} import responses.cord.AmazonOrderResponse._ -import slick.driver.PostgresDriver.api._ +import slick.jdbc.PostgresProfile.api._ import utils.aliases._ import utils.db._ From ce4fe6eed16c16c294f368d88b317ccf466ec686 Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Wed, 10 May 2017 17:03:05 +0300 Subject: [PATCH 70/93] fix sql versions --- ...search_view_rules.sql => V4.117__coupon_search_view_rules.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename phoenix-scala/sql/{V4.118__coupon_search_view_rules.sql => V4.117__coupon_search_view_rules.sql} (100%) diff --git a/phoenix-scala/sql/V4.118__coupon_search_view_rules.sql b/phoenix-scala/sql/V4.117__coupon_search_view_rules.sql similarity index 100% rename from phoenix-scala/sql/V4.118__coupon_search_view_rules.sql rename to phoenix-scala/sql/V4.117__coupon_search_view_rules.sql From 12d68805e19c7cc9863c9ab4ed7f9fd26ba122d7 Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Thu, 1 Jun 2017 02:00:45 +0300 Subject: [PATCH 71/93] fix flow&lint --- ashes/src/components/orders/order.jsx | 2 +- ashes/test/unit/lib/language-utils.js | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/ashes/src/components/orders/order.jsx b/ashes/src/components/orders/order.jsx index 15758424ba..528ccf0ef6 100644 --- a/ashes/src/components/orders/order.jsx +++ b/ashes/src/components/orders/order.jsx @@ -147,7 +147,7 @@ export default class Order extends React.Component { } get subNav(): Element<*> { - return ; + return ; } @autobind diff --git a/ashes/test/unit/lib/language-utils.js b/ashes/test/unit/lib/language-utils.js index 3e9c300fbd..a8a180dac7 100644 --- a/ashes/test/unit/lib/language-utils.js +++ b/ashes/test/unit/lib/language-utils.js @@ -1,7 +1,3 @@ -const { stringToCurrency } = requireSource('lib/language-utils', [ - 'codeToName' -]); - // @todo // const { default: formatCurrency, stringToCurrency } = requireSource('lib/language-utils', [ // 'codeToName' From 8b1ae583ea6fafe2bcd6a9ce765d30b20e5793e5 Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Thu, 1 Jun 2017 03:12:43 +0300 Subject: [PATCH 72/93] drop orderId from ReturnsSearchViewResult --- .../phoenix/test/integration/ReturnsSearchViewTest.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/phoenix-scala/phoenix/test/integration/ReturnsSearchViewTest.scala b/phoenix-scala/phoenix/test/integration/ReturnsSearchViewTest.scala index 917f7ae65b..38484bf568 100644 --- a/phoenix-scala/phoenix/test/integration/ReturnsSearchViewTest.scala +++ b/phoenix-scala/phoenix/test/integration/ReturnsSearchViewTest.scala @@ -11,7 +11,6 @@ import core.utils.Money._ case class ReturnsSearchViewResult( id: Int, referenceNumber: String, - orderId: Int, orderRef: String, createdAt: String, state: Return.State, From fd60b7646e33f2da3457c758579eae7efa52a4e6 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 1 Jun 2017 10:00:41 +0700 Subject: [PATCH 73/93] Fix all orders integration test --- ...search_view_id_seq_and_change_triggers.sql | 93 ------------------- 1 file changed, 93 deletions(-) diff --git a/phoenix-scala/sql/V4.223__add_orders_search_view_id_seq_and_change_triggers.sql b/phoenix-scala/sql/V4.223__add_orders_search_view_id_seq_and_change_triggers.sql index 4a983697d1..fd084aaa8d 100644 --- a/phoenix-scala/sql/V4.223__add_orders_search_view_id_seq_and_change_triggers.sql +++ b/phoenix-scala/sql/V4.223__add_orders_search_view_id_seq_and_change_triggers.sql @@ -6,96 +6,3 @@ select setval ('orders_search_view_id_seq', alter table orders_search_view alter column id set default nextval ('orders_search_view_id_seq'); - --- from amazon orders -create or replace function update_orders_search_view_from_amazon_orders_insert_fn() returns trigger as $$ -begin - insert into orders_search_view ( - id, - scope, - reference_number, - state, - placed_at, - currency, - sub_total, - shipping_total, - adjustments_total, - taxes_total, - grand_total, - customer) - select distinct on (new.id) - nextval('orders_search_view_id_seq') as id, - -- order - new.scope as scope, - new.amazon_order_id as reference_number, - new.order_status as state, - to_char(new.purchase_date, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, - new.currency as currency, - -- totals - 0 as sub_total, - 0 as shipping_total, - 0 as adjustments_total, - 0 as taxes_total, - new.order_total as grand_total, - -- customer - json_build_object( - 'id', c.id, - 'name', c.name, - 'email', c.email, - 'is_blacklisted', c.is_blacklisted, - 'joined_at', c.joined_at, - 'rank', c.rank, - 'revenue', c.revenue - )::jsonb as customer - from customers_search_view as c - where (new.account_id = c.id); - return null; -end; -$$ language plpgsql; - --- from orders - -create or replace function update_orders_view_from_orders_insert_fn() returns trigger as $$ -begin - insert into orders_search_view ( - id, - scope, - reference_number, - state, - placed_at, - currency, - sub_total, - shipping_total, - adjustments_total, - taxes_total, - grand_total, - customer) - select distinct on (new.id) - nextval('orders_search_view_id_seq') as id, - -- order - new.scope as scope, - new.reference_number as reference_number, - new.state as state, - to_char(new.placed_at, 'yyyy-mm-dd"t"hh24:mi:ss.ms"z"') as placed_at, - new.currency as currency, - -- totals - new.sub_total as sub_total, - new.shipping_total as shipping_total, - new.adjustments_total as adjustments_total, - new.taxes_total as taxes_total, - new.grand_total as grand_total, - -- customer - json_build_object( - 'id', c.id, - 'name', c.name, - 'email', c.email, - 'is_blacklisted', c.is_blacklisted, - 'joined_at', c.joined_at, - 'rank', c.rank, - 'revenue', c.revenue - )::jsonb as customer - from customers_search_view as c - where (new.account_id = c.id); - return null; -end; -$$ language plpgsql; From dd29d9c149df23d7e21dd1dce8cdca9c5203d4ac Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 1 Jun 2017 10:05:03 +0700 Subject: [PATCH 74/93] Update update_orders_view_from_orders_update_fn function --- .../sql/V1.111__orders_search_view_triggers_orders.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phoenix-scala/sql/V1.111__orders_search_view_triggers_orders.sql b/phoenix-scala/sql/V1.111__orders_search_view_triggers_orders.sql index 9be16e15f5..1d9f01242d 100644 --- a/phoenix-scala/sql/V1.111__orders_search_view_triggers_orders.sql +++ b/phoenix-scala/sql/V1.111__orders_search_view_triggers_orders.sql @@ -33,7 +33,6 @@ $$ language plpgsql; create or replace function update_orders_view_from_orders_update_fn() returns trigger as $$ begin update orders_search_view set - reference_number = new.reference_number, state = new.state, placed_at = to_char(new.placed_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), currency = new.currency, @@ -42,7 +41,7 @@ begin adjustments_total = new.adjustments_total, taxes_total = new.taxes_total, grand_total = new.grand_total - where id = new.id; + where reference_number = new.reference_number; return null; end; From 7ae419adddb379261a61a89a446793473e8fda74 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 1 Jun 2017 10:06:08 +0700 Subject: [PATCH 75/93] Revert "Update update_orders_view_from_orders_update_fn function" This reverts commit dd29d9c149df23d7e21dd1dce8cdca9c5203d4ac. --- .../sql/V1.111__orders_search_view_triggers_orders.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phoenix-scala/sql/V1.111__orders_search_view_triggers_orders.sql b/phoenix-scala/sql/V1.111__orders_search_view_triggers_orders.sql index 1d9f01242d..9be16e15f5 100644 --- a/phoenix-scala/sql/V1.111__orders_search_view_triggers_orders.sql +++ b/phoenix-scala/sql/V1.111__orders_search_view_triggers_orders.sql @@ -33,6 +33,7 @@ $$ language plpgsql; create or replace function update_orders_view_from_orders_update_fn() returns trigger as $$ begin update orders_search_view set + reference_number = new.reference_number, state = new.state, placed_at = to_char(new.placed_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), currency = new.currency, @@ -41,7 +42,7 @@ begin adjustments_total = new.adjustments_total, taxes_total = new.taxes_total, grand_total = new.grand_total - where reference_number = new.reference_number; + where id = new.id; return null; end; From d628912505a216327c471363e6ff2db82a2f04c6 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Thu, 1 Jun 2017 10:06:52 +0700 Subject: [PATCH 76/93] Fix migrations --- .../sql/R__orders_search_view_triggers.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/phoenix-scala/sql/R__orders_search_view_triggers.sql b/phoenix-scala/sql/R__orders_search_view_triggers.sql index fb0c216b70..c5ea261208 100644 --- a/phoenix-scala/sql/R__orders_search_view_triggers.sql +++ b/phoenix-scala/sql/R__orders_search_view_triggers.sql @@ -84,3 +84,20 @@ begin return null; end; $$ language plpgsql; + +create or replace function update_orders_view_from_orders_update_fn() returns trigger as $$ +begin + update orders_search_view set + state = new.state, + placed_at = to_char(new.placed_at, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'), + currency = new.currency, + sub_total = new.sub_total, + shipping_total = new.shipping_total, + adjustments_total = new.adjustments_total, + taxes_total = new.taxes_total, + grand_total = new.grand_total + where reference_number = new.reference_number; + + return null; +end; +$$ language plpgsql; From 40fed5d7a9b94afbe78956113417c371b590d513 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Mon, 5 Jun 2017 17:24:48 +0700 Subject: [PATCH 77/93] Apply CR comments WIP --- .../core/app/core/db/SearchTerms.scala | 13 ---- .../app/phoenix/models/cord/AmazonOrder.scala | 23 +++--- .../payloads/AmazonOrderPayloads.scala | 4 +- .../responses/cord/AmazonOrderResponse.scala | 77 +++++++++++-------- .../routes/admin/AmazonOrderRoutes.scala | 2 +- .../phoenix/services/AmazonOrderManager.scala | 24 +++--- .../AmazonOrderAssignmentsManager.scala | 7 +- .../AmazonOrderWatchersManager.scala | 7 +- .../testutils/apis/PhoenixAdminApi.scala | 2 +- 9 files changed, 83 insertions(+), 76 deletions(-) diff --git a/phoenix-scala/core/app/core/db/SearchTerms.scala b/phoenix-scala/core/app/core/db/SearchTerms.scala index 6bdd1be322..67afe9a882 100644 --- a/phoenix-scala/core/app/core/db/SearchTerms.scala +++ b/phoenix-scala/core/app/core/db/SearchTerms.scala @@ -46,19 +46,6 @@ trait SearchByRefNum[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T } } -trait SearchByAmazonOrderId[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T] { - - def findOneByAmazonOrderId(amazonOrderId: String): DBIO[Option[M]] - - def mustFindByAmazonOrderId( - amazonOrderId: String, - notFoundFailure: String ⇒ Failure = notFound404K)(implicit ec: EC, db: DB): DbResultT[M] = - findOneByAmazonOrderId(amazonOrderId).dbresult.flatMap { - case Some(model) ⇒ DbResultT.good(model) - case None ⇒ DbResultT.failure(notFoundFailure(amazonOrderId)) - } -} - trait SearchByCode[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T] { def findOneByCode(code: String): DBIO[Option[M]] diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala index b9fea447b7..c6b1b5b764 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala @@ -10,13 +10,13 @@ import core.utils.Money.Currency import core.failures._ import core.db._ -case class AmazonOrder(id: Int = 0, - amazonOrderId: String = "", - orderTotal: Int = 0, - paymentMethodDetail: String = "", - orderType: String = "", - currency: Currency = Currency.USD, - orderStatus: String = "", +case class AmazonOrder(id: Int, + amazonOrderId: String, + orderTotal: Long, + paymentMethodDetail: String, + orderType: String, + currency: Currency, + orderStatus: String, purchaseDate: Instant, scope: LTree, accountId: Int, @@ -56,23 +56,22 @@ object AmazonOrder { object AmazonOrders extends FoxTableQuery[AmazonOrder, AmazonOrders](new AmazonOrders(_)) - with ReturningId[AmazonOrder, AmazonOrders] - with SearchByAmazonOrderId[AmazonOrder, AmazonOrders] { + with ReturningId[AmazonOrder, AmazonOrders] { val returningLens: Lens[AmazonOrder, Int] = lens[AmazonOrder].id def findOneByAmazonOrderId(amazonOrderId: String): DBIO[Option[AmazonOrder]] = filter(_.amazonOrderId === amazonOrderId).one - def mustFindOneOr404(amazonOrderId: String)(implicit ec: EC): DbResultT[AmazonOrder] = + def mustFindOneOr(amazonOrderId: String)(implicit ec: EC): DbResultT[AmazonOrder] = findOneByAmazonOrderId(amazonOrderId).mustFindOr( - NotFoundFailure404(s"Amazon order with id=$amazonOrderId not found")) + NotFoundFailure404(AmazonOrder, amazonOrderId)) } class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def amazonOrderId = column[String]("amazon_order_id") - def orderTotal = column[Int]("order_total") + def orderTotal = column[Long]("order_total") def paymentMethodDetail = column[String]("payment_method_detail") def orderType = column[String]("order_type") def currency = column[Currency]("currency") diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/AmazonOrderPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/AmazonOrderPayloads.scala index e6c9b212b2..22cc7e6259 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/AmazonOrderPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/AmazonOrderPayloads.scala @@ -1,4 +1,4 @@ -package phoenix.payloads; +package phoenix.payloads import java.time.Instant @@ -8,7 +8,7 @@ import com.github.tminglei.slickpg.LTree object AmazonOrderPayloads { case class CreateAmazonOrderPayload(amazonOrderId: String, - orderTotal: Int, + orderTotal: Long, paymentMethodDetail: String, orderType: String, currency: Currency = Currency.USD, diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala index c7d85a5e79..d1d9dc3731 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala @@ -8,12 +8,12 @@ import phoenix.responses._ import com.github.tminglei.slickpg.LTree case class AmazonOrderResponse(id: Int, - amazonOrderId: String = "", - orderTotal: Int = 0, - paymentMethodDetail: String = "", - orderType: String = "", - currency: Currency = Currency.USD, - orderStatus: String = "", + amazonOrderId: String, + orderTotal: Long, + paymentMethodDetail: String, + orderType: String, + currency: Currency, + orderStatus: String, purchaseDate: Instant, scope: LTree, accountId: Int, @@ -22,32 +22,45 @@ case class AmazonOrderResponse(id: Int, extends ResponseItem object AmazonOrderResponse { + def build(amazonOrder: AmazonOrder): AmazonOrderResponse = + AmazonOrderResponse(id = amazonOrder.id, + amazonOrderId = amazonOrder.amazonOrderId, + orderTotal = amazonOrder.orderTotal, + paymentMethodDetail = amazonOrder.paymentMethodDetail, + orderType = amazonOrder.orderType, + currency = amazonOrder.currency, + orderStatus = amazonOrder.orderStatus, + purchaseDate = amazonOrder.purchaseDate, + scope = amazonOrder.scope, + accountId = amazonOrder.accountId, + createdAt = amazonOrder.createdAt, + updatedAt = amazonOrder.updatedAt) - case class Root(id: Int, - amazonOrderId: String, - orderTotal: Int, - paymentMethodDetail: String, - orderType: String, - currency: Currency, - orderStatus: String, - purchaseDate: Instant, - scope: LTree, - accountId: Int, - createdAt: Instant, - updatedAt: Instant) - extends ResponseItem + // case class Root(id: Int, + // amazonOrderId: String, + // orderTotal: Long, + // paymentMethodDetail: String, + // orderType: String, + // currency: Currency, + // orderStatus: String, + // purchaseDate: Instant, + // scope: LTree, + // accountId: Int, + // createdAt: Instant, + // updatedAt: Instant) + // extends ResponseItem - def build(amazonOrder: AmazonOrder): Root = - Root(id = amazonOrder.id, - amazonOrderId = amazonOrder.amazonOrderId, - orderTotal = amazonOrder.orderTotal, - paymentMethodDetail = amazonOrder.paymentMethodDetail, - orderType = amazonOrder.orderType, - currency = amazonOrder.currency, - orderStatus = amazonOrder.orderStatus, - purchaseDate = amazonOrder.purchaseDate, - scope = amazonOrder.scope, - accountId = amazonOrder.accountId, - createdAt = amazonOrder.createdAt, - updatedAt = amazonOrder.updatedAt) + // def build(amazonOrder: AmazonOrder): Root = + // Root(id = amazonOrder.id, + // amazonOrderId = amazonOrder.amazonOrderId, + // orderTotal = amazonOrder.orderTotal, + // paymentMethodDetail = amazonOrder.paymentMethodDetail, + // orderType = amazonOrder.orderType, + // currency = amazonOrder.currency, + // orderStatus = amazonOrder.orderStatus, + // purchaseDate = amazonOrder.purchaseDate, + // scope = amazonOrder.scope, + // accountId = amazonOrder.accountId, + // createdAt = amazonOrder.createdAt, + // updatedAt = amazonOrder.updatedAt) } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/AmazonOrderRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/AmazonOrderRoutes.scala index 47b5882882..2a6a4f2dc3 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/AmazonOrderRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/AmazonOrderRoutes.scala @@ -16,7 +16,7 @@ import phoenix.utils.http.Http._ object AmazonOrderRoutes { def routes(implicit ec: EC, db: DB, auth: AU): Route = { activityContext(auth) { implicit ac ⇒ - pathPrefix("amazon_orders") { + pathPrefix("amazon-orders") { (post & pathEnd & entity(as[CreateAmazonOrderPayload])) { payload ⇒ mutateOrFailures { createAmazonOrder(payload) diff --git a/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala b/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala index d0403b2a98..f53c427bd8 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala @@ -14,15 +14,21 @@ object AmazonOrderManager { def createAmazonOrder(payload: CreateAmazonOrderPayload)( implicit ec: EC, db: DB, - au: AU): DbResultT[AmazonOrderResponse.Root] = { + au: AU): DbResultT[AmazonOrderResponse] = { - val amazonOrderT = - AmazonOrders.findOneByAmazonOrderId(payload.amazonOrderId).findOrCreate(createInner(payload)) + for { + amazonOrder ← * <~ AmazonOrders + .findOneByAmazonOrderId(payload.amazonOrderId) + .findOrCreate(createInner(payload)) + } yield AmazonOrderResponse.build(amazonOrder) + + // val amazonOrderT = + // AmazonOrders.findOneByAmazonOrderId(payload.amazonOrderId).findOrCreate(createInner(payload)) - amazonOrderT.map { - case (existingOrder) ⇒ - AmazonOrderResponse.build(AmazonOrder.fromExistingAmazonOrder(existingOrder)) - } + // amazonOrderT.map { + // case (existingOrder) ⇒ + // AmazonOrderResponse.build(AmazonOrder.fromExistingAmazonOrder(existingOrder)) + // } } private def createInner( @@ -37,9 +43,9 @@ object AmazonOrderManager { def updateAmazonOrder(amazonOrderId: String, payload: UpdateAmazonOrderPayload)( implicit ec: EC, db: DB, - au: AU): DbResultT[AmazonOrderResponse.Root] = + au: AU): DbResultT[AmazonOrderResponse] = for { - amazonOrder ← * <~ AmazonOrders.mustFindOneOr404(amazonOrderId) + amazonOrder ← * <~ AmazonOrders.mustFindOneOr(amazonOrderId) up ← * <~ AmazonOrders.update(amazonOrder, amazonOrder.copy(orderStatus = payload.orderStatus)) } yield AmazonOrderResponse.build(up) diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderAssignmentsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderAssignmentsManager.scala index 660417a3fe..98dd53b0a9 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderAssignmentsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderAssignmentsManager.scala @@ -3,7 +3,8 @@ package phoenix.services.assignments import phoenix.models.cord._ import phoenix.models.activity.Dimension import phoenix.models.{Assignment, NotificationSubscription} -import phoenix.responses.cord.AmazonOrderResponse._ +import phoenix.responses.cord.AmazonOrderResponse +import phoenix.responses.cord.AmazonOrderResponse.build import phoenix.utils.aliases._ import slick.jdbc.PostgresProfile.api._ import core.db._ @@ -15,10 +16,10 @@ object AmazonOrderAssignmentsManager extends AssignmentsManager[String, AmazonOr val notifyDimension = Dimension.amazonOrder val notifyReason = NotificationSubscription.Assigned - def buildResponse(model: AmazonOrder): Root = build(model) + def buildResponse(model: AmazonOrder): AmazonOrderResponse = build(model) def fetchEntity(refNum: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[AmazonOrder] = - AmazonOrders.mustFindByAmazonOrderId(refNum) + AmazonOrders.mustFindOneOr(refNum) def fetchSequence( refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[AmazonOrder]] = diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderWatchersManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderWatchersManager.scala index 00717c24e4..a768bab214 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderWatchersManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderWatchersManager.scala @@ -3,7 +3,8 @@ package phoenix.services.assignments import phoenix.models.cord._ import phoenix.models.activity.Dimension import phoenix.models.{Assignment, NotificationSubscription} -import phoenix.responses.cord.AmazonOrderResponse._ +import phoenix.responses.cord.AmazonOrderResponse +import phoenix.responses.cord.AmazonOrderResponse.build import phoenix.utils.aliases._ import slick.jdbc.PostgresProfile.api._ import core.db._ @@ -15,10 +16,10 @@ object AmazonOrderWatchersManager extends AssignmentsManager[String, AmazonOrder val notifyDimension = Dimension.amazonOrder val notifyReason = NotificationSubscription.Watching - def buildResponse(model: AmazonOrder): Root = build(model) + def buildResponse(model: AmazonOrder): AmazonOrderResponse = build(model) def fetchEntity(refNum: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[AmazonOrder] = - AmazonOrders.mustFindByAmazonOrderId(refNum) + AmazonOrders.mustFindOneOr(refNum) def fetchSequence( refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[AmazonOrder]] = diff --git a/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala index 5120a37008..82018832eb 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -44,7 +44,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ private val rootPrefix = "v1" object amazonOrderApi { - val amazonOrdersPrefix = s"$rootPrefix/amazon_orders" + val amazonOrdersPrefix = s"$rootPrefix/amazon-orders" def create(payload: CreateAmazonOrderPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(amazonOrdersPrefix, payload, aa.jwtCookie.some) From e5452b83f866456399fb588d62d90d59076b4e1b Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Mon, 5 Jun 2017 23:18:40 +0700 Subject: [PATCH 78/93] Refactor AmazonOrders --- .../app/phoenix/models/cord/AmazonOrder.scala | 14 ----- .../responses/cord/AmazonOrderResponse.scala | 28 ---------- .../phoenix/services/AmazonOrderManager.scala | 14 ++--- .../AmazonOrderIntegrationTest.scala | 51 ++++++++++--------- .../testutils/apis/PhoenixAdminApi.scala | 11 ++-- 5 files changed, 39 insertions(+), 79 deletions(-) diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala index c6b1b5b764..9d5b43752a 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala @@ -38,20 +38,6 @@ object AmazonOrder { accountId = accountId, createdAt = Instant.now, updatedAt = Instant.now) - - def fromExistingAmazonOrder(existingOrder: AmazonOrder): AmazonOrder = - AmazonOrder(id = existingOrder.id, - amazonOrderId = existingOrder.amazonOrderId, - orderTotal = existingOrder.orderTotal, - paymentMethodDetail = existingOrder.paymentMethodDetail, - orderType = existingOrder.orderType, - currency = existingOrder.currency, - orderStatus = existingOrder.orderStatus, - purchaseDate = existingOrder.purchaseDate, - scope = existingOrder.scope, - accountId = existingOrder.accountId, - createdAt = existingOrder.createdAt, - updatedAt = existingOrder.updatedAt) } object AmazonOrders diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala index d1d9dc3731..14289b876a 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala @@ -35,32 +35,4 @@ object AmazonOrderResponse { accountId = amazonOrder.accountId, createdAt = amazonOrder.createdAt, updatedAt = amazonOrder.updatedAt) - - // case class Root(id: Int, - // amazonOrderId: String, - // orderTotal: Long, - // paymentMethodDetail: String, - // orderType: String, - // currency: Currency, - // orderStatus: String, - // purchaseDate: Instant, - // scope: LTree, - // accountId: Int, - // createdAt: Instant, - // updatedAt: Instant) - // extends ResponseItem - - // def build(amazonOrder: AmazonOrder): Root = - // Root(id = amazonOrder.id, - // amazonOrderId = amazonOrder.amazonOrderId, - // orderTotal = amazonOrder.orderTotal, - // paymentMethodDetail = amazonOrder.paymentMethodDetail, - // orderType = amazonOrder.orderType, - // currency = amazonOrder.currency, - // orderStatus = amazonOrder.orderStatus, - // purchaseDate = amazonOrder.purchaseDate, - // scope = amazonOrder.scope, - // accountId = amazonOrder.accountId, - // createdAt = amazonOrder.createdAt, - // updatedAt = amazonOrder.updatedAt) } diff --git a/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala b/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala index f53c427bd8..ce9e1e20e7 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala @@ -17,18 +17,14 @@ object AmazonOrderManager { au: AU): DbResultT[AmazonOrderResponse] = { for { + user ← * <~ Users + .findByEmail(payload.customerEmail) + .mustFindOneOr(NotFoundFailure404(User, "email", payload.customerEmail)) + inner = AmazonOrders.create(AmazonOrder.build(payload, user.accountId)) amazonOrder ← * <~ AmazonOrders .findOneByAmazonOrderId(payload.amazonOrderId) - .findOrCreate(createInner(payload)) + .findOrCreate(inner) } yield AmazonOrderResponse.build(amazonOrder) - - // val amazonOrderT = - // AmazonOrders.findOneByAmazonOrderId(payload.amazonOrderId).findOrCreate(createInner(payload)) - - // amazonOrderT.map { - // case (existingOrder) ⇒ - // AmazonOrderResponse.build(AmazonOrder.fromExistingAmazonOrder(existingOrder)) - // } } private def createInner( diff --git a/phoenix-scala/phoenix/test/integration/AmazonOrderIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/AmazonOrderIntegrationTest.scala index 86f4349e14..87e95111fd 100644 --- a/phoenix-scala/phoenix/test/integration/AmazonOrderIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/AmazonOrderIntegrationTest.scala @@ -1,6 +1,7 @@ import testutils._ import testutils.apis._ import testutils.fixtures._ +import testutils.fixtures.api.ApiFixtureHelpers import phoenix.payloads.AmazonOrderPayloads._ import phoenix.responses.cord.AmazonOrderResponse import phoenix.models.cord._ @@ -17,37 +18,39 @@ class AmazonOrderIntegrationTest with PhoenixAdminApi with BakedFixtures with DefaultJwtAdminAuth - with TestActivityContext.AdminAC { + with TestActivityContext.AdminAC + with ApiFixtureHelpers { - "POST /v1/amazon_orders" - { - "successfully creates amazonOrder from payload" in new Customer_Seed { - val payload = CreateAmazonOrderPayload(amazonOrderId = "111-5296499-9653859", - orderTotal = 4500, - paymentMethodDetail = "CreditCard", - orderType = "StandardOrder", - currency = Currency.USD, - orderStatus = "Shipped", - purchaseDate = Instant.now, - scope = LTree("1"), - customerEmail = customer.email.value) - - val root = amazonOrderApi.create(payload).as[AmazonOrderResponse.Root] - val created = AmazonOrders.findOneByAmazonOrderId(root.amazonOrderId).gimme.value - created.id must === (root.id) + "POST /v1/amazon-orders" - { + "successfully creates amazonOrder from payload" in new Fixture { + val created = + AmazonOrders.findOneByAmazonOrderId(amazonOrderResponse.amazonOrderId).gimme.value + created.id must === (amazonOrderResponse.id) } } - "PATCH /v1/amazon_orders/:amazonOrderId" - { + "PATCH /v1/amazon-orders/:amazonOrderId" - { "update existing order" in new Fixture { - val updPayload = UpdateAmazonOrderPayload(orderStatus = "ChangedStatus") - val updated = - amazonOrderApi.update(amazonOrder.amazonOrderId, updPayload).as[AmazonOrderResponse.Root] - updated.orderStatus must === (updPayload.orderStatus) + val updatePayload = UpdateAmazonOrderPayload(orderStatus = "ChangedStatus") + val updated = amazonOrdersApi(amazonOrderResponse.amazonOrderId) + .update(updatePayload) + .as[AmazonOrderResponse] + updated.orderStatus must === (updatePayload.orderStatus) } } - trait Fixture extends Customer_Seed { - val amazonOrder = - AmazonOrders.create(Factories.amazonOrder.copy(accountId = customer.accountId)).gimme + trait Fixture { + val customer = api_newCustomer + val amazonOrderPayload = CreateAmazonOrderPayload(amazonOrderId = "111-5296499-9653859", + orderTotal = 4500, + paymentMethodDetail = "CreditCard", + orderType = "StandardOrder", + currency = Currency.USD, + orderStatus = "Shipped", + purchaseDate = Instant.now, + scope = LTree("1"), + customerEmail = customer.email.value) + + val amazonOrderResponse = amazonOrdersApi.create(amazonOrderPayload).as[AmazonOrderResponse] } } diff --git a/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala index 82018832eb..dcee6ce334 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -43,15 +43,18 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ private val rootPrefix = "v1" - object amazonOrderApi { + object amazonOrdersApi { val amazonOrdersPrefix = s"$rootPrefix/amazon-orders" def create(payload: CreateAmazonOrderPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(amazonOrdersPrefix, payload, aa.jwtCookie.some) + } - def update(amazonOrderId: String, payload: UpdateAmazonOrderPayload)( - implicit aa: TestAdminAuth): HttpResponse = - PATCH(s"$amazonOrdersPrefix/$amazonOrderId", payload, aa.jwtCookie.some) + case class amazonOrdersApi(refNum: String) { + val amazonOrdersPath = s"${amazonOrdersApi.amazonOrdersPrefix}/$refNum" + + def update(payload: UpdateAmazonOrderPayload)(implicit aa: TestAdminAuth): HttpResponse = + PATCH(amazonOrdersPath, payload, aa.jwtCookie.some) } object customersApi { From 9eb37e7a35e617239afd40d393150649bda6b933 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 6 Jun 2017 16:28:19 +0700 Subject: [PATCH 79/93] Update api-docs --- .../content/reference/amazon_orders.apib | 3 +++ developer-portal/content/reference/index.md | 3 +++ .../reference/objects/amazon_order.apib | 25 +++++++++++++++++++ .../resources/admin_amazon_orders.apib | 15 +++++++++++ 4 files changed, 46 insertions(+) create mode 100644 developer-portal/content/reference/amazon_orders.apib create mode 100644 developer-portal/content/reference/objects/amazon_order.apib create mode 100644 developer-portal/content/reference/resources/admin_amazon_orders.apib diff --git a/developer-portal/content/reference/amazon_orders.apib b/developer-portal/content/reference/amazon_orders.apib new file mode 100644 index 0000000000..64ad0305d6 --- /dev/null +++ b/developer-portal/content/reference/amazon_orders.apib @@ -0,0 +1,3 @@ +# Data Amazon Orders + + \ No newline at end of file diff --git a/developer-portal/content/reference/index.md b/developer-portal/content/reference/index.md index 8372ccb223..43ce49441b 100644 --- a/developer-portal/content/reference/index.md +++ b/developer-portal/content/reference/index.md @@ -252,6 +252,7 @@ in the `5xx` range indicate an error with Fox's platform. + @@ -260,3 +261,5 @@ in the `5xx` range indicate an error with Fox's platform. + + diff --git a/developer-portal/content/reference/objects/amazon_order.apib b/developer-portal/content/reference/objects/amazon_order.apib new file mode 100644 index 0000000000..80b213a768 --- /dev/null +++ b/developer-portal/content/reference/objects/amazon_order.apib @@ -0,0 +1,25 @@ +# Data structures + +### AmazonOrderBase ++ amazonOrderId: `111-5296499-9653859` (required, string) - Amazon Order ID ++ orderTotal: `4500` (required, number) - Order total amount in cents ++ paymentMethodDetail: `CreditCard` (required, string) - Payment method name ++ orderType: `StandardOrder` (required, string) - Amazon Order type ++ currency: `USD` (required, string) - Order currency ++ orderStatus: `Shipped` (required, string) - Order status ++ purchaseDate: `2017-03-08T19:38:36Z` (required, string) - Timestamp of when order was placed. ++ scope: `1` (required, string) - Scope ID + +### AmazonOrderPayload +- Include AmazonOrderBase ++ customerEmail: `67xlr8kb83lx0t2@marketplace.amazon.com` (required, string) - Customer email anonymized by amazon + +### AmazonOrderResponse ++ id: `2` (required, number) - Unique identifier +- Include AmazonOrderBase ++ accountId: `1` (required, number) - Customer accountId ++ createdAt: `2017-06-05T10:14:46.982Z` (required, string) - Timestamp of when exact record was created. ++ updatedAt: `2017-06-05T10:14:46.982Z` (required, string) - Timestamp of when exact record was updated last time. + +### AmazonOrderUpdatePayload ++ orderStatus: `Shipped` (required, string) - Order status \ No newline at end of file diff --git a/developer-portal/content/reference/resources/admin_amazon_orders.apib b/developer-portal/content/reference/resources/admin_amazon_orders.apib new file mode 100644 index 0000000000..64afc10b95 --- /dev/null +++ b/developer-portal/content/reference/resources/admin_amazon_orders.apib @@ -0,0 +1,15 @@ +## Amazon Orders + +### Create [POST /v1/amazon-orders] + ++ Request (application/json) + + Attributes (AmazonOrderPayload) ++ Response 200 (application/json) + + Attributes (AmazonOrderResponse) + +### Update [PATCH /v1/amazon-orders/{amazonOrderId}] + ++ Request (application/json) + + Attributes(AmazonOrderUpdatePayload) ++ Response 200 (application/json) + + Attributes (AmazonOrderResponse) From 339efa167f3c728845bcd5af0d3a4ec0fdd65c5a Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 6 Jun 2017 16:36:28 +0700 Subject: [PATCH 80/93] Add description --- .../content/reference/resources/admin_amazon_orders.apib | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/developer-portal/content/reference/resources/admin_amazon_orders.apib b/developer-portal/content/reference/resources/admin_amazon_orders.apib index 64afc10b95..ac6a284f96 100644 --- a/developer-portal/content/reference/resources/admin_amazon_orders.apib +++ b/developer-portal/content/reference/resources/admin_amazon_orders.apib @@ -1,5 +1,11 @@ ## Amazon Orders +All orders from Amazon sales channel duplicated in Fox platform. +Orders are fetched by platform automatically but also can be added via API. + +`CREATE` call is immutable — if order with such `amazonOrderId` has +been created already — previously created order will return. + ### Create [POST /v1/amazon-orders] + Request (application/json) From 8e4e8ccfcfd6017ed5e23af3496ee223708bc9a6 Mon Sep 17 00:00:00 2001 From: Anna Zubenko Date: Wed, 7 Jun 2017 18:11:54 +0300 Subject: [PATCH 81/93] Scalafmt run --- green-river/build.sbt | 63 +- .../main/scala/consumer/AvroProcessor.scala | 42 +- .../src/main/scala/consumer/Main.scala | 19 +- .../src/main/scala/consumer/MainConfig.scala | 36 +- .../scala/consumer/MultiTopicConsumer.scala | 35 +- .../src/main/scala/consumer/Workers.scala | 251 +-- .../consumer/activity/AccountConnector.scala | 50 +- .../ActivityConnectionTransformer.scala | 30 +- .../consumer/activity/ActivityProcessor.scala | 74 +- .../consumer/activity/CouponConnector.scala | 2 +- .../consumer/activity/GiftCardConnector.scala | 24 +- .../consumer/activity/OrderConnector.scala | 29 +- .../consumer/activity/ProductConnector.scala | 13 +- .../activity/PromotionConnector.scala | 2 +- .../activity/SharedSearchConnector.scala | 11 +- .../consumer/activity/SkuConnector.scala | 14 +- .../activity/StoreCreditConnector.scala | 13 +- .../consumer/elastic/AvroTransformer.scala | 2 +- .../elastic/ElasticSearchProcessor.scala | 28 +- .../consumer/elastic/ScopeProcessor.scala | 40 +- .../consumer/elastic/ScopedIndexer.scala | 41 +- .../mappings/CountriesSearchView.scala | 20 +- .../mappings/ProductReviewsSearchView.scala | 28 +- .../mappings/ProductsCatalogView.scala | 48 +- .../elastic/mappings/RegionsSearchView.scala | 8 +- .../mappings/admin/CartsSearchView.scala | 136 +- .../admin/CouponCodesSearchView.scala | 14 +- .../mappings/admin/CouponsSearchView.scala | 28 +- .../admin/CustomerGroupsSearchView.scala | 16 +- .../mappings/admin/CustomerItemsView.scala | 32 +- .../mappings/admin/CustomersSearchView.scala | 130 +- .../FailedAuthorizationsSearchView.scala | 48 +- .../GiftCardTransactionsSearchView.scala | 50 +- .../mappings/admin/GiftCardsSearchView.scala | 24 +- .../mappings/admin/InventorySearchView.scala | 42 +- .../InventoryTransactionSearchView.scala | 22 +- .../mappings/admin/NotesSearchView.scala | 128 +- .../mappings/admin/OrdersSearchView.scala | 176 +-- .../mappings/admin/ProductsSearchView.scala | 54 +- .../mappings/admin/PromotionsSearchView.scala | 28 +- .../mappings/admin/SkuSearchView.scala | 26 +- .../admin/StoreAdminsSearchView.scala | 18 +- .../StoreCreditTransactionsSearchView.scala | 50 +- .../admin/StoreCreditsSearchView.scala | 36 +- .../mappings/admin/TaxonomiesSearchView.scala | 28 +- .../mappings/admin/TaxonsSearchView.scala | 30 +- .../consumer/elastic/mappings/package.scala | 56 +- .../src/main/scala/consumer/package.scala | 3 +- .../scala/consumer/utils/HttpSupport.scala | 20 +- .../consumer/utils/JsonTransformers.scala | 17 +- phoenix-scala/build.sbt | 35 +- .../core/app/core/db/ExPostgresDriver.scala | 7 +- .../app/core/db/FoxFailureException.scala | 3 +- phoenix-scala/core/app/core/db/FoxModel.scala | 5 +- .../core/app/core/db/FoxTableQuery.scala | 7 +- .../core/app/core/db/SearchTerms.scala | 19 +- phoenix-scala/core/app/core/db/Star.scala | 3 +- .../core/app/core/db/UpdateReturning.scala | 14 +- phoenix-scala/core/app/core/db/package.scala | 68 +- phoenix-scala/core/app/core/failures.scala | 9 +- phoenix-scala/core/app/core/utils/Money.scala | 2 +- .../core/app/core/utils/Strings.scala | 7 +- .../core/app/core/utils/Validation.scala | 35 +- .../core/utils/time/JavaTimeSlickMapper.scala | 4 +- .../app/objectframework/DbObjectUtils.scala | 8 +- .../app/objectframework/FormShadowGet.scala | 12 +- .../objectframework/IlluminateAlgorithm.scala | 10 +- .../app/objectframework/ObjectFailures.scala | 9 +- .../app/objectframework/ObjectUtils.scala | 85 +- .../objectframework/models/FullObject.scala | 3 +- .../models/IlluminatedObject.scala | 2 +- .../models/ObjectContext.scala | 5 +- .../objectframework/models/ObjectHead.scala | 18 +- .../models/ObjectHeadLinks.scala | 11 +- .../objectframework/models/ObjectSchema.scala | 3 +- .../objectframework/models/OrderedLinks.scala | 3 +- .../payloads/ObjectPayloads.scala | 5 +- .../payloads/ObjectSchemaValidation.scala | 6 +- .../services/ObjectManager.scala | 18 +- .../services/ObjectSchemasManager.scala | 13 +- .../app/phoenix/facades/ImageFacade.scala | 104 +- .../phoenix/facades/NotificationFacade.scala | 30 +- .../phoenix/failures/ArchiveFailures.scala | 5 +- .../phoenix/failures/AssignmentFailures.scala | 8 +- .../phoenix/failures/CategoryFailures.scala | 2 +- .../app/phoenix/failures/CouponFailures.scala | 14 +- .../failures/CustomerGroupFailures.scala | 4 +- .../failures/DiscountCompilerFailures.scala | 11 +- .../phoenix/failures/DiscountFailures.scala | 2 +- .../app/phoenix/failures/Failure.scala | 13 +- .../app/phoenix/failures/OrderFailures.scala | 2 +- .../phoenix/failures/ProductFailures.scala | 8 +- .../phoenix/failures/PromotionFailures.scala | 2 +- .../app/phoenix/failures/ReturnFailures.scala | 16 +- .../app/phoenix/failures/TreeFailures.scala | 5 +- .../phoenix/app/phoenix/failures/Util.scala | 4 +- .../app/phoenix/libs/oauth/google.scala | 5 +- .../app/phoenix/libs/oauth/oauthv2.scala | 21 +- .../app/phoenix/libs/oauth/package.scala | 7 +- .../app/phoenix/models/Assignment.scala | 8 +- .../models/LastSeenNotifications.scala | 8 +- .../phoenix/app/phoenix/models/Note.scala | 3 +- .../models/NotificationSubscription.scala | 4 +- .../app/phoenix/models/Notifications.scala | 2 +- .../phoenix/app/phoenix/models/Reason.scala | 7 +- .../app/phoenix/models/SaveForLater.scala | 5 +- .../app/phoenix/models/account/Account.scala | 3 +- .../models/account/AccountAccessMethod.scala | 24 +- .../models/account/AccountOrganization.scala | 3 +- .../phoenix/models/account/Organization.scala | 9 +- .../models/account/RolePermission.scala | 3 +- .../app/phoenix/models/account/Scope.scala | 6 +- .../app/phoenix/models/account/User.scala | 30 +- .../models/account/UserPasswordReset.scala | 8 +- .../phoenix/models/activity/Activity.scala | 25 +- .../phoenix/models/activity/Dimension.scala | 5 +- .../app/phoenix/models/admin/AdminData.scala | 6 +- .../app/phoenix/models/auth/Credentials.scala | 14 +- .../app/phoenix/models/auth/Token.scala | 17 +- .../models/category/IlluminatedCategory.scala | 2 +- .../app/phoenix/models/category/package.scala | 5 +- .../app/phoenix/models/cord/AmazonOrder.scala | 29 +- .../app/phoenix/models/cord/Cord.scala | 3 +- .../app/phoenix/models/cord/Order.scala | 73 +- .../phoenix/models/cord/OrderPayment.scala | 13 +- .../phoenix/models/cord/OrderPromotion.scala | 6 +- .../models/cord/OrderShippingAddress.scala | 45 +- .../models/cord/OrderShippingMethod.scala | 3 +- .../lineitems/CartLineItemAdjustment.scala | 19 +- .../models/cord/lineitems/OrderLineItem.scala | 16 +- .../app/phoenix/models/coupon/Coupon.scala | 15 +- .../phoenix/models/coupon/CouponCode.scala | 17 +- .../models/coupon/CouponCustomerUsage.scala | 3 +- .../models/coupon/IlluminatedCoupon.scala | 20 +- .../models/customer/CustomerData.scala | 18 +- .../models/customer/CustomerGroup.scala | 28 +- .../models/customer/CustomerGroupMember.scala | 3 +- .../customer/CustomerGroupTemplate.scala | 8 +- .../customer/GroupTemplateInstance.scala | 3 +- .../phoenix/models/discount/Discount.scala | 6 +- .../models/discount/DiscountHelpers.scala | 6 +- .../models/discount/DiscountValidator.scala | 9 +- .../models/discount/IlluminatedDiscount.scala | 13 +- .../models/discount/SearchReference.scala | 6 +- .../discount/offers/ItemsAmountOffer.scala | 15 +- .../discount/offers/ItemsPercentOffer.scala | 15 +- .../models/discount/offers/Offer.scala | 9 +- .../discount/offers/SetPriceOffer.scala | 8 +- .../qualifiers/ItemsAnyQualifier.scala | 16 +- .../app/phoenix/models/image/Album.scala | 3 +- .../models/image/AlbumImagesLink.scala | 9 +- .../models/inventory/IlluminatedSku.scala | 14 +- .../app/phoenix/models/inventory/Sku.scala | 3 +- .../models/inventory/SkuValidator.scala | 3 +- .../app/phoenix/models/location/Address.scala | 30 +- .../app/phoenix/models/location/Country.scala | 15 +- .../app/phoenix/models/location/Region.scala | 4 +- .../models/objects/ProductAlbumLink.scala | 6 +- .../models/objects/ProductSkuLink.scala | 7 +- .../models/objects/ProductVariantLink.scala | 6 +- .../objects/PromotionDiscountLink.scala | 8 +- .../phoenix/models/objects/SkuAlbumLink.scala | 10 +- .../models/objects/TaxonProductLink.scala | 9 +- .../models/objects/VariantValueLink.scala | 6 +- .../models/payment/ExternalCharge.scala | 15 +- .../payment/InStorePaymentAdjustment.scala | 5 +- .../payment/applepay/ApplePayCharge.scala | 7 +- .../payment/applepay/ApplePayment.scala | 12 +- .../payment/creditcard/CreditCard.scala | 167 +- .../models/payment/giftcard/GiftCard.scala | 167 +- .../payment/giftcard/GiftCardAdjustment.scala | 14 +- .../giftcard/GiftCardFromStoreCredit.scala | 6 +- .../payment/giftcard/GiftCardManual.scala | 3 +- .../payment/storecredit/StoreCredit.scala | 70 +- .../storecredit/StoreCreditAdjustment.scala | 4 +- .../storecredit/StoreCreditCustom.scala | 8 +- .../storecredit/StoreCreditFromGiftCard.scala | 6 +- .../storecredit/StoreCreditManual.scala | 8 +- .../storecredit/StoreCreditRefund.scala | 3 +- .../storecredit/StoreCreditSubtype.scala | 3 +- .../app/phoenix/models/plugins/Plugin.scala | 37 +- .../models/plugins/PluginSettings.scala | 3 +- .../models/product/IlluminatedProduct.scala | 17 +- .../models/product/IlluminatedVariant.scala | 8 +- .../app/phoenix/models/product/MvpModel.scala | 179 +-- .../app/phoenix/models/product/Product.scala | 7 +- .../models/product/ProductValidator.scala | 4 +- .../phoenix/models/product/VariantValue.scala | 2 +- .../models/product/VariantValueSkuLink.scala | 6 +- .../promotion/IlluminatedPromotion.scala | 21 +- .../models/promotion/PromotionHelpers.scala | 6 +- .../models/promotion/PromotionValidator.scala | 4 +- .../app/phoenix/models/returns/Return.scala | 32 +- .../models/returns/ReturnLineItem.scala | 2 +- .../returns/ReturnLineItemShippingCost.scala | 10 +- .../models/returns/ReturnLineItemSku.scala | 6 +- .../models/returns/ReturnPayment.scala | 11 +- .../models/returns/ReturnStripePayment.scala | 5 +- .../app/phoenix/models/rules/Condition.scala | 12 +- .../phoenix/models/rules/QueryStatement.scala | 7 +- .../models/sharedsearch/SharedSearch.scala | 24 +- .../SharedSearchAssociations.scala | 11 +- .../shipping/DefaultShippingMethod.scala | 12 +- .../models/shipping/ShippingRestriction.scala | 21 +- .../app/phoenix/models/taxonomy/Taxon.scala | 6 +- .../phoenix/models/taxonomy/Taxonomy.scala | 11 +- .../models/taxonomy/TaxonomyTaxonLink.scala | 35 +- .../phoenix/models/traits/Addressable.scala | 7 +- .../models/tree/GenericTreeNodes.scala | 7 +- .../app/phoenix/payloads/AuthPayload.scala | 2 +- .../app/phoenix/payloads/CartPayloads.scala | 6 +- .../phoenix/payloads/CustomerPayloads.scala | 12 +- .../payloads/EntityExportPayloads.scala | 26 +- .../phoenix/payloads/GiftCardPayloads.scala | 29 +- .../app/phoenix/payloads/ImagePayloads.scala | 9 +- .../phoenix/payloads/LineItemPayloads.scala | 4 +- .../app/phoenix/payloads/Payloads.scala | 4 +- .../phoenix/payloads/PaymentPayloads.scala | 31 +- .../app/phoenix/payloads/PluginPayloads.scala | 29 +- .../payloads/ProductReviewPayloads.scala | 4 +- .../app/phoenix/payloads/ReturnPayloads.scala | 49 +- .../payloads/SharedSearchPayloads.scala | 5 +- .../phoenix/payloads/StoreAdminPayloads.scala | 14 +- .../payloads/StoreCreditPayloads.scala | 15 +- .../app/phoenix/payloads/UserPayloads.scala | 3 +- .../phoenix/payloads/VariantPayloads.scala | 6 +- .../phoenix/responses/ActivityResponse.scala | 12 +- .../phoenix/responses/AddressResponse.scala | 83 +- .../responses/AssignmentResponse.scala | 8 +- .../phoenix/responses/CategoryResponses.scala | 9 +- .../phoenix/responses/CouponResponses.scala | 19 +- .../responses/CreditCardsResponse.scala | 42 +- .../phoenix/responses/CustomerResponse.scala | 34 +- .../responses/GenericTreeResponses.scala | 16 +- .../GiftCardAdjustmentsResponse.scala | 3 +- .../responses/GiftCardBulkResponse.scala | 3 +- .../phoenix/responses/GiftCardResponse.scala | 38 +- .../responses/GiftCardSubTypesResponse.scala | 6 +- .../app/phoenix/responses/GroupResponse.scala | 30 +- .../phoenix/responses/ImageResponses.scala | 6 +- .../phoenix/responses/ProductResponses.scala | 20 +- .../responses/ProductReviewResponses.scala | 3 +- .../responses/PromotionResponses.scala | 18 +- .../phoenix/responses/PublicResponses.scala | 2 +- .../phoenix/responses/ReturnResponse.scala | 90 +- .../responses/SaveForLaterResponse.scala | 13 +- .../responses/ShippingMethodsResponse.scala | 3 +- .../app/phoenix/responses/SkuResponses.scala | 16 +- .../StoreCreditAdjustmentsResponse.scala | 3 +- .../responses/StoreCreditBulkResponse.scala | 3 +- .../responses/StoreCreditResponse.scala | 31 +- .../StoreCreditSubTypesResponse.scala | 7 +- .../phoenix/responses/TaxonResponses.scala | 28 +- .../phoenix/responses/TaxonomyResponses.scala | 14 +- .../app/phoenix/responses/TheResponse.scala | 23 +- .../app/phoenix/responses/UserResponse.scala | 19 +- .../phoenix/responses/VariantResponses.scala | 21 +- .../phoenix/responses/cord/AllOrders.scala | 18 +- .../responses/cord/AmazonOrderResponse.scala | 26 +- .../phoenix/responses/cord/CartResponse.scala | 55 +- .../responses/cord/OrderResponse.scala | 48 +- .../cord/base/CordResponseLineItems.scala | 65 +- .../cord/base/CordResponsePayments.scala | 21 +- .../cord/base/CordResponsePromotions.scala | 26 +- .../cord/base/CordResponseShipping.scala | 3 +- .../cord/base/CordResponseTotals.scala | 20 +- .../plugins/PluginCommonResponses.scala | 6 +- .../app/phoenix/routes/AuthRoutes.scala | 68 +- .../phoenix/app/phoenix/routes/Customer.scala | 524 +++--- .../phoenix/app/phoenix/routes/Public.scala | 110 +- .../phoenix/routes/admin/AdminRoutes.scala | 506 +++--- .../routes/admin/AmazonOrderRoutes.scala | 13 +- .../routes/admin/AssignmentsRoutes.scala | 1406 ++++++++--------- .../app/phoenix/routes/admin/CartRoutes.scala | 248 +-- .../phoenix/routes/admin/CategoryRoutes.scala | 56 +- .../phoenix/routes/admin/CouponRoutes.scala | 76 +- .../routes/admin/CustomerGroupsRoutes.scala | 68 +- .../phoenix/routes/admin/CustomerRoutes.scala | 268 ++-- .../app/phoenix/routes/admin/DevRoutes.scala | 69 +- .../phoenix/routes/admin/DiscountRoutes.scala | 54 +- .../routes/admin/GenericTreeRoutes.scala | 44 +- .../phoenix/routes/admin/GiftCardRoutes.scala | 88 +- .../phoenix/routes/admin/ImageRoutes.scala | 72 +- .../routes/admin/NotificationRoutes.scala | 21 +- .../phoenix/routes/admin/ObjectRoutes.scala | 35 +- .../phoenix/routes/admin/OrderRoutes.scala | 316 ++-- .../phoenix/routes/admin/PluginRoutes.scala | 45 +- .../routes/admin/ProductReviewRoutes.scala | 31 +- .../phoenix/routes/admin/ProductRoutes.scala | 117 +- .../routes/admin/PromotionRoutes.scala | 35 +- .../phoenix/routes/admin/ReturnRoutes.scala | 157 +- .../routes/admin/ShippingMethodRoutes.scala | 39 +- .../app/phoenix/routes/admin/SkuRoutes.scala | 50 +- .../routes/admin/StoreAdminRoutes.scala | 47 +- .../routes/admin/StoreCreditRoutes.scala | 25 +- .../phoenix/routes/admin/TaxonomyRoutes.scala | 100 +- .../phoenix/routes/admin/VariantRoutes.scala | 38 +- .../routes/service/CustomerGroupRoutes.scala | 15 +- .../routes/service/MigrationRoutes.scala | 4 +- .../routes/service/PaymentRoutes.scala | 4 +- .../phoenix/app/phoenix/server/Main.scala | 79 +- .../app/phoenix/services/AddressManager.scala | 8 +- .../phoenix/services/AmazonOrderManager.scala | 18 +- .../app/phoenix/services/Authenticators.scala | 110 +- .../app/phoenix/services/Capture.scala | 64 +- .../app/phoenix/services/CartValidator.scala | 46 +- .../app/phoenix/services/Checkout.scala | 69 +- .../app/phoenix/services/CordQueries.scala | 3 +- .../phoenix/services/CreditCardManager.scala | 57 +- .../services/CustomerCreditConverter.scala | 50 +- .../app/phoenix/services/EntityExporter.scala | 36 +- .../phoenix/services/LineItemManager.scala | 45 +- .../phoenix/services/LineItemUpdater.scala | 74 +- .../app/phoenix/services/LogActivity.scala | 298 ++-- .../services/NotificationManager.scala | 49 +- .../app/phoenix/services/PublicService.scala | 7 +- .../services/SaveForLaterManager.scala | 9 +- .../services/SharedSearchService.scala | 18 +- .../phoenix/services/ShippingManager.scala | 51 +- .../phoenix/services/StoreAdminManager.scala | 28 +- .../phoenix/services/StoreCreditService.scala | 76 +- .../services/account/AccountManager.scala | 67 +- .../services/activity/CartTailored.scala | 3 +- .../activity/CustomerGroupsTailored.scala | 23 +- .../services/activity/CustomerTailored.scala | 5 +- .../services/activity/OrderTailored.scala | 12 +- .../services/activity/ReturnTailored.scala | 10 +- .../activity/StoreAdminsTailored.scala | 9 +- .../services/activity/UserTailored.scala | 3 +- .../services/actors/RemorseTimer.scala | 28 +- .../AmazonOrderAssignmentsManager.scala | 3 +- .../AmazonOrderWatchersManager.scala | 3 +- .../assignments/AssignmentsManager.scala | 24 +- .../CouponAssignmentsManager.scala | 18 +- .../CustomerAssignmentsManager.scala | 2 +- .../assignments/CustomerWatchersManager.scala | 2 +- .../GiftCardAssignmentsManager.scala | 5 +- .../assignments/GiftCardWatchersManager.scala | 3 +- .../PromotionAssignmentsManager.scala | 18 +- .../ReturnAssignmentsManager.scala | 3 +- .../assignments/ReturnWatchersManager.scala | 3 +- .../assignments/SkuAssignmentsManager.scala | 2 +- .../assignments/SkuWatchersManager.scala | 2 +- .../services/assignments/package.scala | 21 +- .../phoenix/services/auth/GoogleOauth.scala | 26 +- .../app/phoenix/services/auth/Oauth.scala | 40 +- .../phoenix/services/carts/CartCreator.scala | 11 +- .../services/carts/CartPaymentUpdater.scala | 74 +- .../services/carts/CartPromotionUpdater.scala | 55 +- .../phoenix/services/carts/CartQueries.scala | 35 +- .../carts/CartShippingAddressUpdater.scala | 4 +- .../carts/CartShippingMethodUpdater.scala | 6 +- .../phoenix/services/carts/CartTotaler.scala | 8 +- .../app/phoenix/services/carts/package.scala | 5 +- .../services/category/CategoryManager.scala | 48 +- .../services/coupon/CouponManager.scala | 73 +- .../services/coupon/CouponUsageService.scala | 51 +- .../customerGroups/GroupManager.scala | 28 +- .../customerGroups/GroupMemberManager.scala | 71 +- .../services/customers/CustomerManager.scala | 132 +- .../services/discount/DiscountManager.scala | 36 +- .../compilers/QualifierCompiler.scala | 3 +- .../services/giftcards/GiftCardService.scala | 38 +- .../phoenix/services/image/ImageManager.scala | 189 +-- .../services/inventory/SkuManager.scala | 72 +- .../migration/CustomerImportService.scala | 8 +- .../phoenix/services/notes/NoteManager.scala | 30 +- .../app/phoenix/services/notes/package.scala | 39 +- .../services/orders/OrderQueries.scala | 12 +- .../services/orders/OrderStateUpdater.scala | 37 +- .../services/orders/OrderUpdater.scala | 9 +- .../phoenix/services/orders/TimeMachine.scala | 3 +- .../services/plugins/PluginsManager.scala | 82 +- .../services/product/ProductManager.scala | 213 ++- .../services/promotion/PromotionManager.scala | 68 +- .../returns/ReturnLineItemManager.scala | 123 +- .../returns/ReturnPaymentManager.scala | 187 +-- .../services/returns/ReturnService.scala | 39 +- .../services/returns/ReturnValidator.scala | 21 +- .../review/ProductReviewManager.scala | 29 +- .../services/taxonomy/TaxonomyManager.scala | 216 ++- .../phoenix/services/tree/TreeManager.scala | 40 +- .../services/variant/VariantManager.scala | 138 +- .../app/phoenix/utils/ElasticsearchApi.scala | 26 +- .../phoenix/app/phoenix/utils/FSM.scala | 9 +- .../app/phoenix/utils/HashPasswords.scala | 6 +- .../app/phoenix/utils/TestStripeSupport.scala | 52 +- .../app/phoenix/utils/Typeclasses.scala | 15 +- .../app/phoenix/utils/apis/AmazonApi.scala | 3 +- .../app/phoenix/utils/apis/FoxStripe.scala | 91 +- .../utils/apis/MiddlewarehouseApi.scala | 7 +- .../phoenix/utils/apis/StripeMappings.scala | 22 +- .../phoenix/utils/apis/StripeWrapper.scala | 6 +- .../phoenix/app/phoenix/utils/config.scala | 24 +- .../phoenix/app/phoenix/utils/db/Flyway.scala | 2 +- .../phoenix/utils/http/CustomDirectives.scala | 46 +- .../phoenix/utils/http/CustomHandlers.scala | 13 +- .../phoenix/app/phoenix/utils/http/Http.scala | 42 +- .../app/phoenix/utils/http/HttpLogger.scala | 16 +- .../app/phoenix/utils/http/JsonSupport.scala | 3 +- .../utils/io/ByteBufferInputStream.scala | 3 +- .../phoenix/app/phoenix/utils/json.scala | 4 +- .../phoenix/utils/seeds/AddressSeeds.scala | 134 +- .../utils/seeds/AmazonOrdersSeeds.scala | 26 +- .../app/phoenix/utils/seeds/CouponSeeds.scala | 19 +- .../phoenix/utils/seeds/CreditCardSeeds.scala | 187 +-- .../phoenix/utils/seeds/CustomerSeeds.scala | 37 +- .../phoenix/utils/seeds/DiscountSeeds.scala | 53 +- .../app/phoenix/utils/seeds/Factories.scala | 56 +- .../phoenix/utils/seeds/GiftCardSeeds.scala | 16 +- .../utils/seeds/GroupTemplatesSeeds.scala | 16 +- .../utils/seeds/ObjectSchemaSeeds.scala | 15 +- .../app/phoenix/utils/seeds/OrderSeeds.scala | 20 +- .../phoenix/utils/seeds/ProductSeeds.scala | 137 +- .../phoenix/utils/seeds/PromotionSeeds.scala | 36 +- .../app/phoenix/utils/seeds/ReturnSeeds.scala | 128 +- .../utils/seeds/SharedSearchSeeds.scala | 38 +- .../phoenix/utils/seeds/ShipmentSeeds.scala | 64 +- .../phoenix/utils/seeds/StoreAdminSeeds.scala | 4 +- .../utils/seeds/StoreCreditSeeds.scala | 6 +- .../seeds/generators/AddressGenerator.scala | 20 +- .../seeds/generators/CouponGenerator.scala | 16 +- .../generators/CreditCardGenerator.scala | 80 +- .../seeds/generators/DiscountGenerator.scala | 13 +- .../seeds/generators/GiftCardGenerator.scala | 13 +- .../seeds/generators/OrderGenerator.scala | 222 ++- .../seeds/generators/ProductGenerator.scala | 107 +- .../seeds/generators/PromotionGenerator.scala | 17 +- .../seeds/generators/SeedsGenerator.scala | 9 +- .../app/phoenix/utils/seeds/package.scala | 15 +- .../utils/time/JavaTimeJson4sSerializer.scala | 2 +- .../AddressesIntegrationTest.scala | 2 +- .../AllOrdersIntegrationTest.scala | 9 +- .../AmazonOrderIntegrationTest.scala | 20 +- .../integration/ApplePayIntegrationTest.scala | 16 +- .../AssignmentsIntegrationTest.scala | 61 +- .../AutoPromotionsIntegrationTest.scala | 123 +- ...artCreditCardPaymentsIntegrationTest.scala | 8 +- .../CartGiftCardPaymentsIntegrationTest.scala | 5 +- .../integration/CartIntegrationTest.scala | 90 +- .../CartPaymentsIntegrationTestBase.scala | 3 +- ...rtStoreCreditPaymentsIntegrationTest.scala | 4 +- .../CartValidatorIntegrationTest.scala | 40 +- .../integration/CategoryIntegrationTest.scala | 14 +- .../integration/CheckoutIntegrationTest.scala | 76 +- .../integration/CouponsIntegrationTest.scala | 9 +- .../CreditCardsIntegrationTest.scala | 79 +- .../CustomerGroupIntegrationTest.scala | 20 +- .../CustomerGroupMembersIntegrationTest.scala | 35 +- ...CustomerGroupTemplateIntegrationTest.scala | 16 +- .../integration/CustomerIntegrationTest.scala | 112 +- .../DbResultSequenceIntegrationTest.scala | 7 +- .../GenericTreeIntegrationTest.scala | 20 +- .../integration/GiftCardIntegrationTest.scala | 92 +- .../GiftCardNotesIntegrationTest.scala | 5 +- .../integration/ImageIntegrationTest.scala | 56 +- .../JsonExceptionHandlerIntegrationTest.scala | 17 +- .../test/integration/JwtAuthTest.scala | 12 +- .../NotificationIntegrationTest.scala | 26 +- .../PaymentTypesIntegrationTest.scala | 18 +- .../integration/ProductIntegrationTest.scala | 279 ++-- .../ProductReviewIntegrationTest.scala | 44 +- .../PromotionsIntegrationTest.scala | 60 +- .../integration/ReasonsIntegrationTest.scala | 4 +- .../integration/ReturnIntegrationTest.scala | 195 ++- .../SharedSearchIntegrationTest.scala | 18 +- .../ShippingMethodsIntegrationTest.scala | 17 +- .../test/integration/SkuIntegrationTest.scala | 36 +- .../StoreAdminIntegrationTest.scala | 9 +- .../StoreCreditIntegrationTest.scala | 33 +- .../integration/TaxonomyIntegrationTest.scala | 77 +- .../integration/VariantIntegrationTest.scala | 32 +- .../models/CartsIntegrationTest.scala | 14 +- .../models/CreditCardIntegrationTest.scala | 8 +- .../GiftCardAdjustmentIntegrationTest.scala | 8 +- .../models/GiftCardIntegrationTest.scala | 10 +- ...StoreCreditAdjustmentIntegrationTest.scala | 54 +- .../models/StoreCreditIntegrationTest.scala | 13 +- .../CartShippingAddressUpdaterTest.scala | 6 +- .../services/CartTotalerTest.scala | 3 +- .../services/CartValidatorTest.scala | 41 +- .../integration/services/CheckoutTest.scala | 43 +- .../services/LineItemUpdaterTest.scala | 13 +- .../services/ShippingManagerTest.scala | 100 +- .../integration/services/StripeTest.scala | 2 +- .../integration/testutils/DbTestSupport.scala | 43 +- .../integration/testutils/HttpSupport.scala | 33 +- .../testutils/IntegrationTestBase.scala | 3 +- .../integration/testutils/JwtTestAuth.scala | 49 +- .../testutils/PayloadHelpers.scala | 2 +- .../testutils/SearchViewTestBase.scala | 15 +- .../integration/testutils/TaxonomySeeds.scala | 44 +- .../testutils/TestObjectContext.scala | 3 +- .../integration/testutils/TestSeeds.scala | 23 +- .../testutils/apis/PhoenixAdminApi.scala | 56 +- .../testutils/apis/PhoenixStorefrontApi.scala | 6 +- .../testutils/fixtures/BakedFixtures.scala | 5 +- .../testutils/fixtures/PaymentFixtures.scala | 16 +- .../fixtures/PromotionFixtures.scala | 33 +- .../testutils/fixtures/RawFixtures.scala | 12 +- .../testutils/fixtures/ReturnsFixtures.scala | 112 +- .../fixtures/api/ApiFixtureHelpers.scala | 8 +- .../testutils/fixtures/api/ApiFixtures.scala | 109 +- .../api/PromotionPayloadBuilder.scala | 29 +- .../testutils/fixtures/api/package.scala | 8 +- .../test/integration/testutils/package.scala | 24 +- .../integration/time/JavaTimeMapperTest.scala | 2 +- .../test/integration/utils/MockedApis.scala | 35 +- .../utils/ModelIntegrationTest.scala | 17 +- .../integration/utils/RemorseTimerTest.scala | 3 +- .../test/integration/utils/SlickTest.scala | 10 +- .../utils/apis/MiddlewarehouseApiTest.scala | 12 +- .../test/unit/models/AddressTest.scala | 20 +- .../unit/models/CartShippingAddressTest.scala | 6 +- .../test/unit/models/CreditCardTest.scala | 14 +- .../test/unit/models/CustomerTest.scala | 6 +- .../test/unit/models/GiftCardTest.scala | 3 +- .../phoenix/test/unit/models/ReasonTest.scala | 4 +- .../test/unit/models/StoreCreditTest.scala | 12 +- .../unit/models/objects/ObjectUtilsTest.scala | 2 +- .../unit/models/rules/ConditionTest.scala | 57 +- .../unit/payloads/PaymentPayloadsTest.scala | 11 +- .../unit/services/OfferAstCompilerTest.scala | 3 +- .../services/QualifierAstCompilerTest.scala | 5 +- .../test/unit/testutils/CatsHelpers.scala | 19 +- .../test/unit/testutils/CatsHelpersTest.scala | 28 +- .../test/unit/testutils/CustomMatchers.scala | 15 +- .../test/unit/testutils/TestBase.scala | 4 +- .../phoenix/test/unit/utils/FSMTest.scala | 24 +- .../test/unit/utils/JsonFormattersTest.scala | 15 +- .../phoenix/test/unit/utils/UtilsTest.scala | 3 +- phoenix-scala/project/Dependencies.scala | 54 +- phoenix-scala/project/Settings.scala | 16 +- .../seeder/app/gatling/package.scala | 2 +- .../seeder/app/gatling/seeds/Seeder.scala | 2 +- .../gatling/seeds/requests/Addresses.scala | 26 +- .../app/gatling/seeds/requests/Auth.scala | 5 +- .../app/gatling/seeds/requests/Cart.scala | 9 +- .../gatling/seeds/requests/CreditCards.scala | 21 +- .../gatling/seeds/requests/Customers.scala | 8 +- .../gatling/seeds/requests/GiftCards.scala | 20 +- .../app/gatling/seeds/requests/Payments.scala | 4 +- .../simulations/OneshotSeedsSimulation.scala | 8 +- phoenix-scala/seeder/app/seeds/Seeds.scala | 124 +- 544 files changed, 9029 insertions(+), 10507 deletions(-) diff --git a/green-river/build.sbt b/green-river/build.sbt index d000cfb033..8a52aa45d3 100644 --- a/green-river/build.sbt +++ b/green-river/build.sbt @@ -1,9 +1,10 @@ lazy val commonSettings = Seq( - version := "1.0", - scalaVersion := "2.11.8", + version := "1.0", + scalaVersion := "2.11.8", updateOptions := updateOptions.value.withCachedResolution(true), scalacOptions ++= List( - "-encoding", "UTF-8", + "-encoding", + "UTF-8", "-target:jvm-1.8", "-feature", "-unchecked", @@ -19,12 +20,11 @@ lazy val commonSettings = Seq( ) ) - -lazy val greenRiver = (project in file(".")). - settings(commonSettings). - settings( - name := "green-river", - version := "1.0", +lazy val greenRiver = (project in file(".")) + .settings(commonSettings) + .settings( + name := "green-river", + version := "1.0", resolvers ++= Seq( "confluent" at "http://packages.confluent.io/maven" ), @@ -35,28 +35,28 @@ lazy val greenRiver = (project in file(".")). Seq( // Config - "com.typesafe" % "config" % "1.3.0", + "com.typesafe" % "config" % "1.3.0", // Cache - "com.github.cb372" %% "scalacache-lrumap" % "0.8.1", + "com.github.cb372" %% "scalacache-lrumap" % "0.8.1", // JSON - "org.json4s" %% "json4s-core" % json4sV, - "org.json4s" %% "json4s-jackson" % json4sV, - "org.json4s" %% "json4s-ext" % json4sV, + "org.json4s" %% "json4s-core" % json4sV, + "org.json4s" %% "json4s-jackson" % json4sV, + "org.json4s" %% "json4s-ext" % json4sV, // Search - "org.apache.kafka" % "kafka_2.11" % "0.9.0.1", - "io.confluent" % "kafka-avro-serializer" % "1.0", - "com.sksamuel.elastic4s" %% "elastic4s-core" % "2.3.0", + "org.apache.kafka" % "kafka_2.11" % "0.9.0.1", + "io.confluent" % "kafka-avro-serializer" % "1.0", + "com.sksamuel.elastic4s" %% "elastic4s-core" % "2.3.0", // Akka - "com.typesafe.akka" %% "akka-slf4j" % akkaV, - "com.typesafe.akka" %% "akka-actor" % akkaV, - "com.typesafe.akka" %% "akka-agent" % akkaV, - "com.typesafe.akka" %% "akka-stream" % akkaV, - "com.typesafe.akka" %% "akka-http-core" % akkaV, - "de.heikoseeberger" %% "akka-http-json4s" % "1.6.0", + "com.typesafe.akka" %% "akka-slf4j" % akkaV, + "com.typesafe.akka" %% "akka-actor" % akkaV, + "com.typesafe.akka" %% "akka-agent" % akkaV, + "com.typesafe.akka" %% "akka-stream" % akkaV, + "com.typesafe.akka" %% "akka-http-core" % akkaV, + "de.heikoseeberger" %% "akka-http-json4s" % "1.6.0", // Cats - "org.typelevel" %% "cats" % "0.5.0", + "org.typelevel" %% "cats" % "0.5.0", // Testing - "org.scalatest" %% "scalatest" % scalaTestV % "test" + "org.scalatest" %% "scalatest" % scalaTestV % "test" ) }, (mainClass in Compile) := Some("consumer.Main"), @@ -86,15 +86,14 @@ lazy val greenRiver = (project in file(".")). |val conn = Phoenix(connInfo) """.stripMargin, assemblyMergeStrategy in assembly := { - case PathList("org", "joda", xs @ _*) ⇒ MergeStrategy.last - case x ⇒ { - val old = (assemblyMergeStrategy in assembly).value - old(x) - } + case PathList("org", "joda", xs @ _ *) ⇒ MergeStrategy.last + case x ⇒ { + val old = (assemblyMergeStrategy in assembly).value + old(x) + } } //test in assembly := {} -) - + ) lazy val consume = inputKey[Unit]("Runs the Kafka Consumers") consume := { (runMain in Compile).partialInput(" consumer.Main").evaluated } diff --git a/green-river/src/main/scala/consumer/AvroProcessor.scala b/green-river/src/main/scala/consumer/AvroProcessor.scala index dc9767d5e4..fa33df9913 100644 --- a/green-river/src/main/scala/consumer/AvroProcessor.scala +++ b/green-river/src/main/scala/consumer/AvroProcessor.scala @@ -119,8 +119,7 @@ class AvroProcessor(schemaRegistryUrl: String, processor: JsonProcessor)(implici extends AbstractKafkaAvroDeserializer with MessageProcessor { - this.schemaRegistry = new CachedSchemaRegistryClient( - schemaRegistryUrl, DEFAULT_MAX_SCHEMAS_PER_SUBJECT) + this.schemaRegistry = new CachedSchemaRegistryClient(schemaRegistryUrl, DEFAULT_MAX_SCHEMAS_PER_SUBJECT) val encoderFactory = EncoderFactory.get() register("scoped_activities-value", AvroProcessor.activitySchema) @@ -129,13 +128,13 @@ class AvroProcessor(schemaRegistryUrl: String, processor: JsonProcessor)(implici register("scoped_activities-key", AvroProcessor.keySchema) register("scoped_activity_trails-key", AvroProcessor.keySchema) - def process(offset: Long, topic: String, key: Array[Byte], message: Array[Byte]): Future[Unit] = { + def process(offset: Long, topic: String, key: Array[Byte], message: Array[Byte]): Future[Unit] = try { val keyJson = if (key == null || key.isEmpty) { Console.err.println( - s"Warning, message has no key for topic ${topic}: ${new String(message, "UTF-8")}") + s"Warning, message has no key for topic $topic: ${new String(message, "UTF-8")}") "" } else { deserializeAvro(key) @@ -150,12 +149,11 @@ class AvroProcessor(schemaRegistryUrl: String, processor: JsonProcessor)(implici val readableKey = new String(key, "UTF-8") val readableMessage = new String(message, "UTF-8") Console.err.println( - s"Error deserializing avro message with key $readableKey: error $e\n\t$readableMessage") + s"Error deserializing avro message with key $readableKey: error $e\n\t$readableMessage") e } case e: Throwable ⇒ Future.failed(e) } - } def deserializeAvro(v: Array[Byte]): String = { val obj = deserialize(v) @@ -177,13 +175,11 @@ class AvroProcessor(schemaRegistryUrl: String, processor: JsonProcessor)(implici */ object AvroJsonHelper { - def transformJson(json: String, fields: List[String] = List.empty): String = { + def transformJson(json: String, fields: List[String] = List.empty): String = compact(render(transformJsonRaw(json, fields))) - } - def transformJsonRaw(json: String, fields: List[String] = List.empty): JValue = { + def transformJsonRaw(json: String, fields: List[String] = List.empty): JValue = JsonTransformers.camelCase(stringToJson(deannotateAvroTypes(parse(json)), fields)) - } private def convertType(typeName: String, value: JValue): JValue = typeName match { @@ -192,26 +188,24 @@ object AvroJsonHelper { case _ ⇒ value } - private def deannotateAvroTypes(input: JValue): JValue = { + private def deannotateAvroTypes(input: JValue): JValue = input.transformField { case JField(name, (JObject(JField(typeName, value) :: Nil))) ⇒ { - (name, convertType(typeName, value)) - } + (name, convertType(typeName, value)) + } } - } - private def stringToJson(input: JValue, fields: List[String]): JValue = { + private def stringToJson(input: JValue, fields: List[String]): JValue = input.transformField { case JField(name, JString(text)) if fields.contains(name) ⇒ { - // Try to parse the text as json, otherwise treat it as text - try { - (name, parse(text)) - } catch { - case NonFatal(e) ⇒ - Console.println(s"Error during parsing field $name: ${e.getMessage}") - (name, JString(text)) - } + // Try to parse the text as json, otherwise treat it as text + try { + (name, parse(text)) + } catch { + case NonFatal(e) ⇒ + Console.println(s"Error during parsing field $name: ${e.getMessage}") + (name, JString(text)) } + } } - } } diff --git a/green-river/src/main/scala/consumer/Main.scala b/green-river/src/main/scala/consumer/Main.scala index aaccfd685b..7c7f18c03d 100644 --- a/green-river/src/main/scala/consumer/Main.scala +++ b/green-river/src/main/scala/consumer/Main.scala @@ -81,15 +81,16 @@ object Main { conf.indexTopics.foreach { case (index, topics) ⇒ val esProcessor = - new ElasticSearchProcessor(uri = conf.elasticSearchUrl, - cluster = conf.elasticSearchCluster, - indexName = index, - topics = topics, - jsonTransformers = - Workers.topicTransformers(conf.connectionInfo())) - - Console.err.println(s"index: ${index}") - Console.err.println(s"topics: ${topics}") + new ElasticSearchProcessor( + uri = conf.elasticSearchUrl, + cluster = conf.elasticSearchCluster, + indexName = index, + topics = topics, + jsonTransformers = Workers.topicTransformers(conf.connectionInfo()) + ) + + Console.err.println(s"index: $index") + Console.err.println(s"topics: $topics") // Create ES mappings esProcessor.createMappings() Console.out.println(s"Done") diff --git a/green-river/src/main/scala/consumer/MainConfig.scala b/green-river/src/main/scala/consumer/MainConfig.scala index f6e72e7477..2b305305dc 100644 --- a/green-river/src/main/scala/consumer/MainConfig.scala +++ b/green-river/src/main/scala/consumer/MainConfig.scala @@ -40,22 +40,22 @@ object MainConfig { val scopedIndexTopics = getIndexMap(conf, "kafka.scoped.indices"); MainConfig( - activityTopic = conf.getString(s"$env.activity.kafka.topic"), - avroSchemaRegistryUrl = conf.getString(s"$env.avro.schemaRegistryUrl"), - elasticSearchCluster = conf.getString(s"$env.elastic.cluster"), - elasticSearchIndex = conf.getString(s"$env.elastic.index"), - elasticSearchUrl = conf.getString(s"$env.elastic.host"), - kafkaBroker = conf.getString(s"$env.kafka.broker"), - kafkaGroupId = conf.getString(s"$env.kafka.groupId"), - indexTopics = indexTopics, - scopedIndexTopics = scopedIndexTopics, - phoenixPass = conf.getString(s"$env.activity.phoenix.pass"), - phoenixUri = conf.getString(s"$env.activity.phoenix.url"), - phoenixUser = conf.getString(s"$env.activity.phoenix.user"), - phoenixOrg = conf.getString(s"$env.activity.phoenix.org"), - maxConnections = conf.getInt(s"$env.max.connections"), - startFromBeginning = conf.getBoolean(s"$env.consume.restart"), - doSetup = conf.getBoolean(s"$env.elastic.setup") + activityTopic = conf.getString(s"$env.activity.kafka.topic"), + avroSchemaRegistryUrl = conf.getString(s"$env.avro.schemaRegistryUrl"), + elasticSearchCluster = conf.getString(s"$env.elastic.cluster"), + elasticSearchIndex = conf.getString(s"$env.elastic.index"), + elasticSearchUrl = conf.getString(s"$env.elastic.host"), + kafkaBroker = conf.getString(s"$env.kafka.broker"), + kafkaGroupId = conf.getString(s"$env.kafka.groupId"), + indexTopics = indexTopics, + scopedIndexTopics = scopedIndexTopics, + phoenixPass = conf.getString(s"$env.activity.phoenix.pass"), + phoenixUri = conf.getString(s"$env.activity.phoenix.url"), + phoenixUser = conf.getString(s"$env.activity.phoenix.user"), + phoenixOrg = conf.getString(s"$env.activity.phoenix.org"), + maxConnections = conf.getInt(s"$env.max.connections"), + startFromBeginning = conf.getBoolean(s"$env.consume.restart"), + doSetup = conf.getBoolean(s"$env.elastic.setup") ) } @@ -63,8 +63,8 @@ object MainConfig { val topicConf = conf.getConfig(key) topicConf.entrySet.foldLeft(Map[String, Seq[String]]()) { case (m, entry) ⇒ { - m + (entry.getKey → topicConf.getStringList(entry.getKey).toSeq) - } + m + (entry.getKey → topicConf.getStringList(entry.getKey).toSeq) + } } } } diff --git a/green-river/src/main/scala/consumer/MultiTopicConsumer.scala b/green-river/src/main/scala/consumer/MultiTopicConsumer.scala index 13d61d4415..f3ee2206ca 100644 --- a/green-river/src/main/scala/consumer/MultiTopicConsumer.scala +++ b/green-river/src/main/scala/consumer/MultiTopicConsumer.scala @@ -19,63 +19,54 @@ import scala.language.postfixOps import org.elasticsearch.client.transport.NoNodeAvailableException private object Sync { - def commit[A, B](consumer: KafkaConsumer[A, B]): Unit = { + def commit[A, B](consumer: KafkaConsumer[A, B]): Unit = try { consumer.commitSync() } catch { case e: CommitFailedException ⇒ Console.err.println(s"Failed to commit: $e") case e: KafkaException ⇒ Console.err.println(s"Unexpectedly to commit: $e") } - } - def commit[A, B]( - consumer: KafkaConsumer[A, B], offsets: Map[TopicPartition, OffsetAndMetadata]): Unit = { + def commit[A, B](consumer: KafkaConsumer[A, B], offsets: Map[TopicPartition, OffsetAndMetadata]): Unit = try { consumer.commitSync(offsets) } catch { case e: CommitFailedException ⇒ Console.err.println(s"Failed to commit: $e") case e: KafkaException ⇒ Console.err.println(s"Unexpectedly to commit: $e") } - } } -private case class StartFromBeginning[A, B](consumer: KafkaConsumer[A, B]) - extends ConsumerRebalanceListener { +private case class StartFromBeginning[A, B](consumer: KafkaConsumer[A, B]) extends ConsumerRebalanceListener { - def onPartitionsRevoked(partitions: Collection[TopicPartition]): Unit = { + def onPartitionsRevoked(partitions: Collection[TopicPartition]): Unit = Sync.commit(consumer) - } - def onPartitionsAssigned(partitions: Collection[TopicPartition]): Unit = { + def onPartitionsAssigned(partitions: Collection[TopicPartition]): Unit = partitions.foreach { p ⇒ - Console.out.println( - s"Consuming from beggining for topic ${p.topic} using partition ${p.partition}") + Console.out.println(s"Consuming from beggining for topic ${p.topic} using partition ${p.partition}") consumer.seekToBeginning(p) } - } } private case class StartFromLastCommit[A, B](consumer: KafkaConsumer[A, B]) extends ConsumerRebalanceListener { - def onPartitionsRevoked(partitions: Collection[TopicPartition]): Unit = { + def onPartitionsRevoked(partitions: Collection[TopicPartition]): Unit = Sync.commit(consumer) - } - def onPartitionsAssigned(partitions: Collection[TopicPartition]): Unit = { + def onPartitionsAssigned(partitions: Collection[TopicPartition]): Unit = partitions.foreach { p ⇒ val offsetMetadata = consumer.committed(p) if (offsetMetadata == null) { Console.out.println( - s"No offset commited. Consuming from beggining for topic ${p.topic} using partition ${p.partition}") + s"No offset commited. Consuming from beggining for topic ${p.topic} using partition ${p.partition}") consumer.seekToBeginning(p) } else { Console.out.println( - s"Consuming from offset ${offsetMetadata.offset} for topic ${p.topic} using partition ${p.partition}") + s"Consuming from offset ${offsetMetadata.offset} for topic ${p.topic} using partition ${p.partition}") consumer.seek(p, offsetMetadata.offset) } } - } } case class ProcessOffsetsResult(ok: Map[TopicPartition, OffsetAndMetadata] = Map.empty, @@ -106,7 +97,7 @@ class MultiTopicConsumer(topics: Seq[String], val consumer = new RawConsumer(props) subscribe(topics, startFromBeginning) - def readForever(): Unit = { + def readForever(): Unit = while (true) { val records = consumer.poll(timeout) @@ -152,8 +143,7 @@ class MultiTopicConsumer(topics: Seq[String], case Some(e) if e.isInstanceOf[NoNodeAvailableException] ⇒ result.errorTopicAndOffset.foreach { case (tp, offset) ⇒ - Console.err.println( - s"NoNodeAvailableException workaround, seek to offset $offset again") + Console.err.println(s"NoNodeAvailableException workaround, seek to offset $offset again") consumer.seek(tp, offset) } case Some(e) if e.isInstanceOf[TryAgainLater] ⇒ @@ -164,7 +154,6 @@ class MultiTopicConsumer(topics: Seq[String], case _ ⇒ } } - } def subscribe(topics: Seq[String], startFromBeginning: Boolean): Unit = { Console.out.println(s"Subscribing to topics: $topics") diff --git a/green-river/src/main/scala/consumer/Workers.scala b/green-river/src/main/scala/consumer/Workers.scala index 1c0b911371..ce1fca5266 100644 --- a/green-river/src/main/scala/consumer/Workers.scala +++ b/green-river/src/main/scala/consumer/Workers.scala @@ -11,45 +11,53 @@ import consumer.elastic.mappings.admin._ import consumer.utils.PhoenixConnectionInfo object Workers { - def activityWorker(conf: MainConfig, connectionInfo: PhoenixConnectionInfo)( - implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC): Future[Unit] = Future { - // Init - val activityConnectors = Seq(AccountConnector, - OrderConnector, - GiftCardConnector, - SharedSearchConnector, - StoreCreditConnector, - ProductConnector, - SkuConnector, - PromotionConnector, - CouponConnector) - - val kafkaInfo = KafkaConnectionInfo( - broker = conf.kafkaBroker, schemaRegistryURL = conf.avroSchemaRegistryUrl) - val activityProcessor = new ActivityProcessor(kafkaInfo, connectionInfo, activityConnectors) - - val avroProcessor = new AvroProcessor( - schemaRegistryUrl = conf.avroSchemaRegistryUrl, processor = activityProcessor) - - val consumer = new MultiTopicConsumer(topics = Seq(conf.activityTopic), - broker = conf.kafkaBroker, - groupId = s"${conf.kafkaGroupId}_activity", - processor = avroProcessor, - startFromBeginning = conf.startFromBeginning) - - // Start consuming & processing - Console.out.println(s"Reading activities from broker ${conf.kafkaBroker}") - consumer.readForever() - } - - def searchViewWorkers(conf: MainConfig, connectionInfo: PhoenixConnectionInfo)( - implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC): Future[Unit] = Future { - - val transformers = topicTransformers(connectionInfo) - val indexTopics = conf.indexTopics - - val futures = indexTopics.flatMap { - case (index, topics) ⇒ { + def activityWorker( + conf: MainConfig, + connectionInfo: PhoenixConnectionInfo)(implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC): Future[Unit] = + Future { + // Init + val activityConnectors = Seq( + AccountConnector, + OrderConnector, + GiftCardConnector, + SharedSearchConnector, + StoreCreditConnector, + ProductConnector, + SkuConnector, + PromotionConnector, + CouponConnector + ) + + val kafkaInfo = + KafkaConnectionInfo(broker = conf.kafkaBroker, schemaRegistryURL = conf.avroSchemaRegistryUrl) + val activityProcessor = new ActivityProcessor(kafkaInfo, connectionInfo, activityConnectors) + + val avroProcessor = + new AvroProcessor(schemaRegistryUrl = conf.avroSchemaRegistryUrl, processor = activityProcessor) + + val consumer = new MultiTopicConsumer( + topics = Seq(conf.activityTopic), + broker = conf.kafkaBroker, + groupId = s"${conf.kafkaGroupId}_activity", + processor = avroProcessor, + startFromBeginning = conf.startFromBeginning + ) + + // Start consuming & processing + Console.out.println(s"Reading activities from broker ${conf.kafkaBroker}") + consumer.readForever() + } + + def searchViewWorkers( + conf: MainConfig, + connectionInfo: PhoenixConnectionInfo)(implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC): Future[Unit] = + Future { + + val transformers = topicTransformers(connectionInfo) + val indexTopics = conf.indexTopics + + val futures = indexTopics.flatMap { + case (index, topics) ⇒ { topics.map { topic ⇒ Future { @@ -62,66 +70,66 @@ object Workers { cluster = conf.elasticSearchCluster, indexName = index, topics = Seq(topic), - jsonTransformers = - Map(topic → transformer)) + jsonTransformers = Map(topic → transformer)) val avroProcessor = - new AvroProcessor(schemaRegistryUrl = conf.avroSchemaRegistryUrl, - processor = esProcessor) + new AvroProcessor(schemaRegistryUrl = conf.avroSchemaRegistryUrl, processor = esProcessor) val consumer = new MultiTopicConsumer(topics = Seq(topic), broker = conf.kafkaBroker, groupId = s"${conf.kafkaGroupId}_$topic", processor = avroProcessor, - startFromBeginning = - conf.startFromBeginning) + startFromBeginning = conf.startFromBeginning) // Start consuming & processing Console.out.println(s"Reading from broker ${conf.kafkaBroker}") consumer.readForever() case None ⇒ - throw new IllegalArgumentException( - s"The Topic '$topic' does not have a json transformer") + throw new IllegalArgumentException(s"The Topic '$topic' does not have a json transformer") } } } } - } - - Future.sequence(futures) - } + } - def scopedSearchViewWorkers(conf: MainConfig, connectionInfo: PhoenixConnectionInfo)( - implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC): Future[Unit] = Future { - - val transformers = topicTransformers(connectionInfo) - val indexTopics = conf.scopedIndexTopics - val ADMIN_INDEX = "admin" - val SCOPES_TABLE = "scopes" - - val scopeProcessorFuture = Future { - - val scopedProcessor = new ScopeProcessor(uri = conf.elasticSearchUrl, - cluster = conf.elasticSearchCluster, - indexTopics = indexTopics, - jsonTransformers = transformers) - - val avroProcessor = new AvroProcessor(schemaRegistryUrl = conf.avroSchemaRegistryUrl, - processor = scopedProcessor) - - val consumer = new MultiTopicConsumer(topics = Seq(SCOPES_TABLE), - broker = conf.kafkaBroker, - groupId = s"${conf.kafkaGroupId}_scopes", - processor = avroProcessor, - startFromBeginning = conf.startFromBeginning) - - // Start consuming & processing - Console.out.println(s"Scope Processor reading from broker ${conf.kafkaBroker}") - consumer.readForever() + Future.sequence(futures) } - val indexers = indexTopics.flatMap { - case (index, topics) ⇒ { + def scopedSearchViewWorkers( + conf: MainConfig, + connectionInfo: PhoenixConnectionInfo)(implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC): Future[Unit] = + Future { + + val transformers = topicTransformers(connectionInfo) + val indexTopics = conf.scopedIndexTopics + val ADMIN_INDEX = "admin" + val SCOPES_TABLE = "scopes" + + val scopeProcessorFuture = Future { + + val scopedProcessor = new ScopeProcessor(uri = conf.elasticSearchUrl, + cluster = conf.elasticSearchCluster, + indexTopics = indexTopics, + jsonTransformers = transformers) + + val avroProcessor = + new AvroProcessor(schemaRegistryUrl = conf.avroSchemaRegistryUrl, processor = scopedProcessor) + + val consumer = new MultiTopicConsumer( + topics = Seq(SCOPES_TABLE), + broker = conf.kafkaBroker, + groupId = s"${conf.kafkaGroupId}_scopes", + processor = avroProcessor, + startFromBeginning = conf.startFromBeginning + ) + + // Start consuming & processing + Console.out.println(s"Scope Processor reading from broker ${conf.kafkaBroker}") + consumer.readForever() + } + + val indexers = indexTopics.flatMap { + case (index, topics) ⇒ { topics.map { topic ⇒ Future { @@ -137,59 +145,58 @@ object Workers { jsonTransformers = Map(topic → transformer)) val avroProcessor = - new AvroProcessor(schemaRegistryUrl = conf.avroSchemaRegistryUrl, - processor = esProcessor) + new AvroProcessor(schemaRegistryUrl = conf.avroSchemaRegistryUrl, processor = esProcessor) val consumer = - new MultiTopicConsumer(topics = Seq(topic), - broker = conf.kafkaBroker, - groupId = s"scoped_${conf.kafkaGroupId}_$topic", - processor = avroProcessor, - startFromBeginning = conf.startFromBeginning) + new MultiTopicConsumer( + topics = Seq(topic), + broker = conf.kafkaBroker, + groupId = s"scoped_${conf.kafkaGroupId}_$topic", + processor = avroProcessor, + startFromBeginning = conf.startFromBeginning + ) // Start consuming & processing - Console.out.println( - s"Scoped $topic Processor Reading from broker ${conf.kafkaBroker}") + Console.out.println(s"Scoped $topic Processor Reading from broker ${conf.kafkaBroker}") consumer.readForever() case None ⇒ - throw new IllegalArgumentException( - s"The Topic '$topic' does not have a json transformer") + throw new IllegalArgumentException(s"The Topic '$topic' does not have a json transformer") } } } } + } + + Future.sequence(Seq(scopeProcessorFuture) ++ indexers) } - Future.sequence(Seq(scopeProcessorFuture) ++ indexers) - } - - def topicTransformers(connectionInfo: PhoenixConnectionInfo)( - implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC) = Map( - "carts_search_view" → CartsSearchView(), - "countries" → CountriesSearchView(), - "customer_items_view" → CustomerItemsView(), - "customers_search_view" → CustomersSearchView(), - "customer_groups_search_view" → CustomerGroupsSearchView(), - "failed_authorizations_search_view" → FailedAuthorizationsSearchView(), - "inventory_search_view" → InventorySearchView(), - "inventory_transactions_search_view" → InventoryTransactionSearchView(), - "notes_search_view" → NotesSearchView(), - "orders_search_view" → OrdersSearchView(), - "products_catalog_view" → ProductsCatalogView(), - "products_search_view" → ProductsSearchView(), - "product_reviews_search_view" → ProductReviewsSearchView(), - "promotions_search_view" → PromotionsSearchView(), - "coupons_search_view" → CouponsSearchView(), - "coupon_codes_search_view" → CouponCodesSearchView(), - "regions" → RegionsSearchView(), - "sku_search_view" → SkuSearchView(), - "gift_card_transactions_view" → GiftCardTransactionsSearchView(), - "gift_cards_search_view" → GiftCardsSearchView(), - "store_admins_search_view" → StoreAdminsSearchView(), - "store_credit_transactions_search_view" → StoreCreditTransactionsSearchView(), - "store_credits_search_view" → StoreCreditsSearchView(), - "scoped_activity_trails" → ActivityConnectionTransformer(connectionInfo), - "taxonomies_search_view" → TaxonomiesSearchView(), - "taxons_search_view" → TaxonsSearchView() + def topicTransformers( + connectionInfo: PhoenixConnectionInfo)(implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC) = Map( + "carts_search_view" → CartsSearchView(), + "countries" → CountriesSearchView(), + "customer_items_view" → CustomerItemsView(), + "customers_search_view" → CustomersSearchView(), + "customer_groups_search_view" → CustomerGroupsSearchView(), + "failed_authorizations_search_view" → FailedAuthorizationsSearchView(), + "inventory_search_view" → InventorySearchView(), + "inventory_transactions_search_view" → InventoryTransactionSearchView(), + "notes_search_view" → NotesSearchView(), + "orders_search_view" → OrdersSearchView(), + "products_catalog_view" → ProductsCatalogView(), + "products_search_view" → ProductsSearchView(), + "product_reviews_search_view" → ProductReviewsSearchView(), + "promotions_search_view" → PromotionsSearchView(), + "coupons_search_view" → CouponsSearchView(), + "coupon_codes_search_view" → CouponCodesSearchView(), + "regions" → RegionsSearchView(), + "sku_search_view" → SkuSearchView(), + "gift_card_transactions_view" → GiftCardTransactionsSearchView(), + "gift_cards_search_view" → GiftCardsSearchView(), + "store_admins_search_view" → StoreAdminsSearchView(), + "store_credit_transactions_search_view" → StoreCreditTransactionsSearchView(), + "store_credits_search_view" → StoreCreditsSearchView(), + "scoped_activity_trails" → ActivityConnectionTransformer(connectionInfo), + "taxonomies_search_view" → TaxonomiesSearchView(), + "taxons_search_view" → TaxonsSearchView() ) } diff --git a/green-river/src/main/scala/consumer/activity/AccountConnector.scala b/green-river/src/main/scala/consumer/activity/AccountConnector.scala index 24641f7aad..7eb678b1c1 100644 --- a/green-river/src/main/scala/consumer/activity/AccountConnector.scala +++ b/green-river/src/main/scala/consumer/activity/AccountConnector.scala @@ -5,7 +5,7 @@ import scala.concurrent.Future import consumer.aliases._ import consumer.utils.JsonTransformers.extractStringSeq -import org.json4s.JsonAST.{JInt, JString, JNothing} +import org.json4s.JsonAST.{JInt, JNothing, JString} object AccountConnector extends ActivityConnector { val dimension = "account" @@ -14,30 +14,26 @@ object AccountConnector extends ActivityConnector { Future { val accountIds = byContextType(activity) ++: - byNoteData(activity) ++: - byData(activity, "account") ++: - byData(activity, "user") ++: - byData(activity, "admin") ++: - byData(activity, "customer") ++: - byData(activity, "assignee") ++: - byId(activity, "accountId") ++: - byId(activity, "userId") ++: - byId(activity, "customerId") ++: - byId(activity, "adminId") ++: - byUpdatedActivity(activity) ++: - byAssignmentSingleData(activity) ++: - byAssignmentBulkData(activity) ++: - byAssigneesData(activity) + byNoteData(activity) ++: + byData(activity, "account") ++: + byData(activity, "user") ++: + byData(activity, "admin") ++: + byData(activity, "customer") ++: + byData(activity, "assignee") ++: + byId(activity, "accountId") ++: + byId(activity, "userId") ++: + byId(activity, "customerId") ++: + byId(activity, "adminId") ++: + byUpdatedActivity(activity) ++: + byAssignmentSingleData(activity) ++: + byAssignmentBulkData(activity) ++: + byAssigneesData(activity) accountIds.distinct.map(createConnection(_, activity.id)) } - def createConnection(accountId: String, activityId: String): Connection = { - Connection(dimension = dimension, - objectId = accountId, - data = JNothing, - activityId = activityId) - } + def createConnection(accountId: String, activityId: String): Connection = + Connection(dimension = dimension, objectId = accountId, data = JNothing, activityId = activityId) private def byContextType(activity: Activity): Seq[String] = activity.context.userType match { @@ -48,12 +44,11 @@ object AccountConnector extends ActivityConnector { case _ ⇒ Seq.empty } - private def byNoteData(activity: Activity): Seq[String] = { + private def byNoteData(activity: Activity): Seq[String] = activity.data \ "note" \ "referenceId" match { case JInt(id) ⇒ Seq(id.toString) case _ ⇒ Seq.empty } - } private def byData(activity: Activity, fieldName: String): Seq[String] = activity.data \ fieldName \ "id" match { @@ -67,29 +62,26 @@ object AccountConnector extends ActivityConnector { case _ ⇒ Seq.empty } - private def byUpdatedActivity(activity: Activity): Seq[String] = { + private def byUpdatedActivity(activity: Activity): Seq[String] = (activity.kind, activity.data \ "oldInfo" \ "id") match { case ("user_updated", JInt(accountId)) ⇒ Seq(accountId.toString) case ("customer_updated", JInt(customerId)) ⇒ Seq(customerId.toString) case _ ⇒ Seq.empty } - } - private def byAssignmentSingleData(activity: Activity): Seq[String] = { + private def byAssignmentSingleData(activity: Activity): Seq[String] = (activity.kind, activity.data \ "entity" \ "id") match { case ("assigned", JInt(accountId)) ⇒ Seq(accountId.toString) case ("unassigned", JInt(accountId)) ⇒ Seq(accountId.toString) case _ ⇒ Seq.empty } - } - private def byAssignmentBulkData(activity: Activity): Seq[String] = { + private def byAssignmentBulkData(activity: Activity): Seq[String] = (activity.kind, activity.data \ "referenceType") match { case ("bulk_assigned", JString(entity)) ⇒ extractStringSeq(activity.data, "entityIds") case ("bulk_unassigned", JString(entity)) ⇒ extractStringSeq(activity.data, "entityIds") case _ ⇒ Seq.empty } - } private def byAssigneesData(activity: Activity): Seq[String] = extractStringSeq(activity.data, "assignees") diff --git a/green-river/src/main/scala/consumer/activity/ActivityConnectionTransformer.scala b/green-river/src/main/scala/consumer/activity/ActivityConnectionTransformer.scala index 213ebb124c..33ea7bca48 100644 --- a/green-river/src/main/scala/consumer/activity/ActivityConnectionTransformer.scala +++ b/green-river/src/main/scala/consumer/activity/ActivityConnectionTransformer.scala @@ -31,22 +31,22 @@ final case class ActivityConnectionTransformer( val topic = "scoped_activity_trails" def mapping() = esMapping(topic).fields( - field("id", LongType), - field("dimension", StringType), - field("objectId", StringType) index "not_analyzed", - field("activity").nested( - field("id", StringType), - field("createdAt", DateType) format dateFormat, - field("kind", StringType) index "not_analyzed", - field("context").nested( - field("transactionId", StringType) index "not_analyzed", - field("userId", IntegerType), - field("userType", StringType) index "not_analyzed" - ), - field("data", ObjectType) + field("id", LongType), + field("dimension", StringType), + field("objectId", StringType) index "not_analyzed", + field("activity").nested( + field("id", StringType), + field("createdAt", DateType) format dateFormat, + field("kind", StringType) index "not_analyzed", + field("context").nested( + field("transactionId", StringType) index "not_analyzed", + field("userId", IntegerType), + field("userType", StringType) index "not_analyzed" ), - field("scope", StringType) index "not_analyzed", - field("createdAt", DateType) format dateFormat + field("data", ObjectType) + ), + field("scope", StringType) index "not_analyzed", + field("createdAt", DateType) format dateFormat ) val jsonFields = List("id", "activity", "connectedBy") diff --git a/green-river/src/main/scala/consumer/activity/ActivityProcessor.scala b/green-river/src/main/scala/consumer/activity/ActivityProcessor.scala index 5716b3c643..ff2973a1c2 100644 --- a/green-river/src/main/scala/consumer/activity/ActivityProcessor.scala +++ b/green-river/src/main/scala/consumer/activity/ActivityProcessor.scala @@ -15,7 +15,7 @@ import org.apache.avro.io._ import org.apache.avro.specific.SpecificDatumWriter import org.apache.kafka.clients.producer.{KafkaProducer, ProducerConfig, ProducerRecord} -import consumer.{AvroJsonHelper, JsonProcessor, AvroProcessor} +import consumer.{AvroJsonHelper, AvroProcessor, JsonProcessor} import consumer.aliases._ import consumer.failures.{Failures, GeneralFailure} import consumer.utils.HttpSupport.HttpResult @@ -27,34 +27,32 @@ import org.json4s.jackson.JsonMethods.parse import org.json4s.jackson.Serialization.{write ⇒ render} import cats.implicits._ -final case class ActivityContext( - userId: Int, userType: String, transactionId: String, scope: String) +final case class ActivityContext(userId: Int, userType: String, transactionId: String, scope: String) -final case class Activity(id: String, - kind: String, - data: JValue, - context: ActivityContext, - createdAt: String) +final case class Activity(id: String, kind: String, data: JValue, context: ActivityContext, createdAt: String) final case class Connection(dimension: String, objectId: String, data: JValue, activityId: String) -final case class AppendNotification( - sourceDimension: String, sourceObjectId: String, activity: Activity) +final case class AppendNotification(sourceDimension: String, sourceObjectId: String, activity: Activity) trait ActivityConnector { def process(offset: Long, activity: Activity)(implicit ec: EC): Future[Seq[Connection]] } -final case class FailedToConnectActivity( - activityId: String, dimension: String, objectId: String, failures: Failures) +final case class FailedToConnectActivity(activityId: String, + dimension: String, + objectId: String, + failures: Failures) extends RuntimeException( - s"Failed to connect activity $activityId to dimension '$dimension' and object $objectId " + + s"Failed to connect activity $activityId to dimension '$dimension' and object $objectId " + s"failures: $failures") -final case class FailedToConnectNotification( - activityId: String, dimension: String, objectId: String, response: HttpResponse) +final case class FailedToConnectNotification(activityId: String, + dimension: String, + objectId: String, + response: HttpResponse) extends RuntimeException( - s"Failed to create notification for connection of activity $activityId to dimension " + + s"Failed to create notification for connection of activity $activityId to dimension " + s"'$dimension' and object $objectId response: $response") final case class KafkaConnectionInfo(broker: String, schemaRegistryURL: String) @@ -64,9 +62,9 @@ final case class KafkaConnectionInfo(broker: String, schemaRegistryURL: String) * This is a JsonProcessor which listens to the activity stream and processes the activity * using a sequence of activity connectors */ -class ActivityProcessor( - kafka: KafkaConnectionInfo, conn: PhoenixConnectionInfo, connectors: Seq[ActivityConnector])( - implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC) +class ActivityProcessor(kafka: KafkaConnectionInfo, + conn: PhoenixConnectionInfo, + connectors: Seq[ActivityConnector])(implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC) extends JsonProcessor { implicit val formats: DefaultFormats.type = DefaultFormats @@ -95,10 +93,10 @@ class ActivityProcessor( val activity = parse(activityJson).extract[Activity] Console.err.println( - s"Got Activity ${activity.kind} with ID ${activity.id} created at ${activity.createdAt}") + s"Got Activity ${activity.kind} with ID ${activity.id} created at ${activity.createdAt}") if (activity.context == null) { Console.err.println( - s"Warning, got Activity ${activity.kind} with ID ${activity.id} without a context, skipping...") + s"Warning, got Activity ${activity.kind} with ID ${activity.id} without a context, skipping...") Future { () } } else { val result = connectors.map { connector ⇒ @@ -119,10 +117,9 @@ class ActivityProcessor( } } - private def process(activity: Activity, cs: Seq[Connection]): Future[Seq[Unit]] = { + private def process(activity: Activity, cs: Seq[Connection]): Future[Seq[Unit]] = Future.sequence(cs.map(c ⇒ pushActivityConnectionToKafka(activity, c)) ++ cs.map(c ⇒ - createPhoenixNotification(activity, c, phoenix))) - } + createPhoenixNotification(activity, c, phoenix))) private def pushActivityConnectionToKafka(activity: Activity, connection: Connection) = Future { val record = new GenericData.Record(AvroProcessor.activityTrailSchema) @@ -140,13 +137,13 @@ class ActivityProcessor( val key = new GenericData.Record(AvroProcessor.keySchema) key.put("id", activity.id) - kafkaProducer.send( - new ProducerRecord[GenericData.Record, GenericData.Record](trailTopic, key, record)) + kafkaProducer.send(new ProducerRecord[GenericData.Record, GenericData.Record](trailTopic, key, record)) () } - private def createPhoenixNotification( - activity: Activity, conn: Connection, phoenix: Phoenix): Future[Unit] = Future { + private def createPhoenixNotification(activity: Activity, + conn: Connection, + phoenix: Phoenix): Future[Unit] = Future { val body = AppendNotification(sourceDimension = conn.dimension, sourceObjectId = conn.objectId, activity = activity) @@ -156,17 +153,18 @@ class ActivityProcessor( phoenix .post("notifications", notification) - .fold({ failures ⇒ - Console.err.println(s"Failed Notification ${conn.dimension} ${conn.activityId}: $failures") - throw FailedToConnectActivity(conn.activityId, conn.dimension, conn.objectId, failures) - }, { resp ⇒ - if (resp.status != StatusCodes.OK) { - Console.err.println(s"Failed Notification ${conn.dimension} ${conn.activityId}: $resp") - throw new FailedToConnectNotification( - conn.activityId, conn.dimension, conn.objectId, resp) + .fold( + { failures ⇒ + Console.err.println(s"Failed Notification ${conn.dimension} ${conn.activityId}: $failures") + throw FailedToConnectActivity(conn.activityId, conn.dimension, conn.objectId, failures) + }, { resp ⇒ + if (resp.status != StatusCodes.OK) { + Console.err.println(s"Failed Notification ${conn.dimension} ${conn.activityId}: $resp") + throw new FailedToConnectNotification(conn.activityId, conn.dimension, conn.objectId, resp) + } + resp } - resp - }) + ) .map(_ ⇒ ()) } } diff --git a/green-river/src/main/scala/consumer/activity/CouponConnector.scala b/green-river/src/main/scala/consumer/activity/CouponConnector.scala index 4a002bb569..1458ca111a 100644 --- a/green-river/src/main/scala/consumer/activity/CouponConnector.scala +++ b/green-river/src/main/scala/consumer/activity/CouponConnector.scala @@ -4,7 +4,7 @@ import scala.concurrent.Future import consumer.aliases._ -import org.json4s.JsonAST.{JInt, JString, JNothing} +import org.json4s.JsonAST.{JInt, JNothing, JString} object CouponConnector extends ActivityConnector { val dimension = "coupon" diff --git a/green-river/src/main/scala/consumer/activity/GiftCardConnector.scala b/green-river/src/main/scala/consumer/activity/GiftCardConnector.scala index 7afed3fe56..99abb624f7 100644 --- a/green-river/src/main/scala/consumer/activity/GiftCardConnector.scala +++ b/green-river/src/main/scala/consumer/activity/GiftCardConnector.scala @@ -5,7 +5,7 @@ import scala.concurrent.Future import consumer.aliases._ import consumer.utils.JsonTransformers.extractStringSeq -import org.json4s.JsonAST.{JInt, JString, JNothing} +import org.json4s.JsonAST.{JInt, JNothing, JString} object GiftCardConnector extends ActivityConnector { val dimension = "gift_card" @@ -14,45 +14,37 @@ object GiftCardConnector extends ActivityConnector { Future { val giftCardIds = byGiftCardData(activity) ++: byAssignmentSingleData(activity) ++: - byAssignmentBulkData(activity) ++: byNoteData(activity) + byAssignmentBulkData(activity) ++: byNoteData(activity) giftCardIds.distinct.map(createConnection(_, activity.id)) } - def createConnection(code: String, activityId: String): Connection = { - Connection(dimension = dimension, - objectId = code, - data = JNothing, - activityId = activityId) - } + def createConnection(code: String, activityId: String): Connection = + Connection(dimension = dimension, objectId = code, data = JNothing, activityId = activityId) - private def byNoteData(activity: Activity): Seq[String] = { + private def byNoteData(activity: Activity): Seq[String] = (activity.data \ "note" \ "referenceType", activity.data \ "entity" \ "code") match { case (JString("giftCard"), JString(code)) ⇒ Seq(code) case _ ⇒ Seq.empty } - } - private def byGiftCardData(activity: Activity): Seq[String] = { + private def byGiftCardData(activity: Activity): Seq[String] = activity.data \ "giftCard" \ "code" match { case JString(refNum) ⇒ Seq(refNum) case _ ⇒ Seq.empty } - } - private def byAssignmentSingleData(activity: Activity): Seq[String] = { + private def byAssignmentSingleData(activity: Activity): Seq[String] = (activity.kind, activity.data \ "entity" \ "code") match { case ("assigned", JString(code)) ⇒ Seq(code) case ("unassigned", JString(code)) ⇒ Seq(code) case _ ⇒ Seq.empty } - } - private def byAssignmentBulkData(activity: Activity): Seq[String] = { + private def byAssignmentBulkData(activity: Activity): Seq[String] = (activity.kind, activity.data \ "referenceType") match { case ("bulk_assigned", JString("giftCard")) ⇒ extractStringSeq(activity.data, "entityIds") case ("bulk_unassigned", JString("giftCard")) ⇒ extractStringSeq(activity.data, "entityIds") case _ ⇒ Seq.empty } - } } diff --git a/green-river/src/main/scala/consumer/activity/OrderConnector.scala b/green-river/src/main/scala/consumer/activity/OrderConnector.scala index dd47ffca3f..774ee2fd99 100644 --- a/green-river/src/main/scala/consumer/activity/OrderConnector.scala +++ b/green-river/src/main/scala/consumer/activity/OrderConnector.scala @@ -5,7 +5,7 @@ import scala.concurrent.Future import consumer.aliases._ import consumer.utils.JsonTransformers.extractStringSeq -import org.json4s.JsonAST.{JString, JNothing} +import org.json4s.JsonAST.{JNothing, JString} object OrderConnector extends ActivityConnector { val dimension = "order" @@ -14,25 +14,20 @@ object OrderConnector extends ActivityConnector { Future { val orderIds = byOrderData(activity) ++: byCartData(activity) ++: byOrderReferenceNumber(activity) ++: - byAssignmentBulkData(activity) ++: byAssignmentSingleData(activity) ++: - byBulkData(activity) ++: byNoteData(activity) + byAssignmentBulkData(activity) ++: byAssignmentSingleData(activity) ++: + byBulkData(activity) ++: byNoteData(activity) orderIds.distinct.map(createConnection(_, activity.id)) } - def createConnection(refNum: String, activityId: String): Connection = { - Connection(dimension = dimension, - objectId = refNum, - data = JNothing, - activityId = activityId) - } + def createConnection(refNum: String, activityId: String): Connection = + Connection(dimension = dimension, objectId = refNum, data = JNothing, activityId = activityId) - private def byNoteData(activity: Activity): Seq[String] = { + private def byNoteData(activity: Activity): Seq[String] = (activity.data \ "note" \ "referenceType", activity.data \ "entity" \ "referenceNumber") match { case (JString("order"), JString(refNum)) ⇒ Seq(refNum) case _ ⇒ Seq.empty } - } private def byOrderReferenceNumber(activity: Activity): Seq[String] = activity.data \ "orderReferenceNumber" match { @@ -44,36 +39,32 @@ object OrderConnector extends ActivityConnector { * We are connecting cart data to order so that when a cart becomes an order * the trail is nice and smooth. smooth smooth smooth. */ - private def byCartData(activity: Activity): Seq[String] = { + private def byCartData(activity: Activity): Seq[String] = activity.data \ "cart" \ "referenceNumber" match { case JString(refNum) ⇒ Seq(refNum) case _ ⇒ Seq.empty } - } - private def byOrderData(activity: Activity): Seq[String] = { + private def byOrderData(activity: Activity): Seq[String] = activity.data \ "order" \ "referenceNumber" match { case JString(refNum) ⇒ Seq(refNum) case _ ⇒ Seq.empty } - } - private def byAssignmentSingleData(activity: Activity): Seq[String] = { + private def byAssignmentSingleData(activity: Activity): Seq[String] = (activity.kind, activity.data \ "entity" \ "referenceNumber") match { case ("assigned", JString(refNum)) ⇒ Seq(refNum) case ("unassigned", JString(refNum)) ⇒ Seq(refNum) case _ ⇒ Seq.empty } - } private def byBulkData(activity: Activity): Seq[String] = extractStringSeq(activity.data, "orderRefNums") - private def byAssignmentBulkData(activity: Activity): Seq[String] = { + private def byAssignmentBulkData(activity: Activity): Seq[String] = (activity.kind, activity.data \ "referenceType") match { case ("bulk_assigned", JString("order")) ⇒ extractStringSeq(activity.data, "entityIds") case ("bulk_unassigned", JString("order")) ⇒ extractStringSeq(activity.data, "entityIds") case _ ⇒ Seq.empty } - } } diff --git a/green-river/src/main/scala/consumer/activity/ProductConnector.scala b/green-river/src/main/scala/consumer/activity/ProductConnector.scala index 5486ca261c..9863746a68 100644 --- a/green-river/src/main/scala/consumer/activity/ProductConnector.scala +++ b/green-river/src/main/scala/consumer/activity/ProductConnector.scala @@ -4,7 +4,7 @@ import scala.concurrent.Future import consumer.aliases._ -import org.json4s.JsonAST.{JInt, JString, JNothing} +import org.json4s.JsonAST.{JInt, JNothing, JString} object ProductConnector extends ActivityConnector { val dimension = "product" @@ -16,17 +16,12 @@ object ProductConnector extends ActivityConnector { productIds.distinct.map(createConnection(_, activity.id)) } - def createConnection(formId: String, activityId: String): Connection = { - Connection(dimension = dimension, - objectId = formId, - data = JNothing, - activityId = activityId) - } + def createConnection(formId: String, activityId: String): Connection = + Connection(dimension = dimension, objectId = formId, data = JNothing, activityId = activityId) - private def byProductData(activity: Activity): Seq[String] = { + private def byProductData(activity: Activity): Seq[String] = activity.data \ "product" \ "id" match { case JInt(formId) ⇒ Seq(formId.toString) case _ ⇒ Seq.empty } - } } diff --git a/green-river/src/main/scala/consumer/activity/PromotionConnector.scala b/green-river/src/main/scala/consumer/activity/PromotionConnector.scala index 813cadc507..0681f7023d 100644 --- a/green-river/src/main/scala/consumer/activity/PromotionConnector.scala +++ b/green-river/src/main/scala/consumer/activity/PromotionConnector.scala @@ -4,7 +4,7 @@ import scala.concurrent.Future import consumer.aliases._ -import org.json4s.JsonAST.{JInt, JString, JNothing} +import org.json4s.JsonAST.{JInt, JNothing, JString} object PromotionConnector extends ActivityConnector { val dimension = "promotion" diff --git a/green-river/src/main/scala/consumer/activity/SharedSearchConnector.scala b/green-river/src/main/scala/consumer/activity/SharedSearchConnector.scala index 0d5694d27c..b12bb02b6a 100644 --- a/green-river/src/main/scala/consumer/activity/SharedSearchConnector.scala +++ b/green-river/src/main/scala/consumer/activity/SharedSearchConnector.scala @@ -19,19 +19,14 @@ object SharedSearchConnector extends ActivityConnector { } } - def createConnection(adminId: String, activityId: String): Connection = { - Connection(dimension = "notification", - objectId = adminId, - data = JNothing, - activityId = activityId) - } + def createConnection(adminId: String, activityId: String): Connection = + Connection(dimension = "notification", objectId = adminId, data = JNothing, activityId = activityId) - private def byAssociateData(activity: Activity): Seq[String] = { + private def byAssociateData(activity: Activity): Seq[String] = activity.data \ "associate" \ "id" match { case JInt(value) ⇒ Seq(value.toString) case _ ⇒ Seq.empty } - } private def byAssociatesData(activity: Activity): Seq[String] = extractStringSeq(activity.data, "associates") diff --git a/green-river/src/main/scala/consumer/activity/SkuConnector.scala b/green-river/src/main/scala/consumer/activity/SkuConnector.scala index 8bf204ce83..c9239377e6 100644 --- a/green-river/src/main/scala/consumer/activity/SkuConnector.scala +++ b/green-river/src/main/scala/consumer/activity/SkuConnector.scala @@ -13,24 +13,18 @@ object SkuConnector extends ActivityConnector { skuIds.distinct.map(createConnection(_, activity.id)) } - def createConnection(formId: String, activityId: String): Connection = { - Connection(dimension = dimension, - objectId = formId, - data = JNothing, - activityId = activityId) - } + def createConnection(formId: String, activityId: String): Connection = + Connection(dimension = dimension, objectId = formId, data = JNothing, activityId = activityId) - private def bySkuData(activity: Activity): Seq[String] = { + private def bySkuData(activity: Activity): Seq[String] = activity.data \ "sku" \ "id" match { case JInt(id) ⇒ Seq(id.toString) case _ ⇒ Seq.empty } - } - private def byNoteData(activity: Activity): Seq[String] = { + private def byNoteData(activity: Activity): Seq[String] = (activity.data \ "note" \ "referenceType", activity.data \ "entity" \ "id") match { case (JString("sku"), JInt(id)) ⇒ Seq(id.toString) case _ ⇒ Seq.empty } - } } diff --git a/green-river/src/main/scala/consumer/activity/StoreCreditConnector.scala b/green-river/src/main/scala/consumer/activity/StoreCreditConnector.scala index 4b92cf11a2..e5754e52df 100644 --- a/green-river/src/main/scala/consumer/activity/StoreCreditConnector.scala +++ b/green-river/src/main/scala/consumer/activity/StoreCreditConnector.scala @@ -16,19 +16,14 @@ object StoreCreditConnector extends ActivityConnector { storeCreditIds.distinct.map(createConnection(_, activity.id)) } - def createConnection(storeCreditId: String, activityId: String): Connection = { - Connection(dimension = dimension, - objectId = storeCreditId, - data = JNothing, - activityId = activityId) - } - - private def byStoreCreditData(activity: Activity): Seq[String] = { + def createConnection(storeCreditId: String, activityId: String): Connection = + Connection(dimension = dimension, objectId = storeCreditId, data = JNothing, activityId = activityId) + + private def byStoreCreditData(activity: Activity): Seq[String] = activity.data \ "storeCredit" \ "id" match { case JInt(storeCreditId) ⇒ Seq(storeCreditId.toString) case _ ⇒ Seq.empty } - } private def byBulkData(activity: Activity): Seq[String] = extractBigIntSeq(activity.data, "storeCreditIds") diff --git a/green-river/src/main/scala/consumer/elastic/AvroTransformer.scala b/green-river/src/main/scala/consumer/elastic/AvroTransformer.scala index 8e4276ead2..1be1c6cf78 100644 --- a/green-river/src/main/scala/consumer/elastic/AvroTransformer.scala +++ b/green-river/src/main/scala/consumer/elastic/AvroTransformer.scala @@ -1,6 +1,6 @@ package consumer.elastic -import scala.concurrent.{Future, ExecutionContext} +import scala.concurrent.{ExecutionContext, Future} import consumer.AvroJsonHelper diff --git a/green-river/src/main/scala/consumer/elastic/ElasticSearchProcessor.scala b/green-river/src/main/scala/consumer/elastic/ElasticSearchProcessor.scala index 0dee47371a..1d736fab0f 100644 --- a/green-river/src/main/scala/consumer/elastic/ElasticSearchProcessor.scala +++ b/green-river/src/main/scala/consumer/elastic/ElasticSearchProcessor.scala @@ -24,12 +24,11 @@ import org.json4s.JsonAST.JInt * id and uses it as the _id in elasticsearch for that item. This is important so that * we don't duplicate entries in ES. */ -class ElasticSearchProcessor( - uri: String, - cluster: String, - indexName: String, - topics: Seq[String], - jsonTransformers: Map[String, JsonTransformer])(implicit ec: ExecutionContext) +class ElasticSearchProcessor(uri: String, + cluster: String, + indexName: String, + topics: Seq[String], + jsonTransformers: Map[String, JsonTransformer])(implicit ec: ExecutionContext) extends JsonProcessor { val settings = Settings.settingsBuilder().put("cluster.name", cluster).build() @@ -45,7 +44,7 @@ class ElasticSearchProcessor( def process(offset: Long, topic: String, key: String, inputJson: String): Future[Unit] = getDocumentId(key, inputJson).fold { Console.err.println( - s"Can't find ID for document $inputJson and key $key for topic $topic, offset = $offset") + s"Can't find ID for document $inputJson and key $key for topic $topic, offset = $offset") futureUnit } { id ⇒ inputJson match { @@ -58,7 +57,7 @@ class ElasticSearchProcessor( save(json, topic, id) } case None ⇒ - Console.out.println(s"Skipping information from topic $topic with key ${key}") + Console.out.println(s"Skipping information from topic $topic with key $key") futureUnit } } @@ -80,7 +79,7 @@ class ElasticSearchProcessor( private val idFields = List("id") - private def getDocumentId(keyJson: String, dataJson: String): Option[BigInt] = { + private def getDocumentId(keyJson: String, dataJson: String): Option[BigInt] = if (keyJson.isEmpty) getIntKey(dataJson) else { getIntKey(keyJson) match { @@ -88,7 +87,6 @@ class ElasticSearchProcessor( case someId ⇒ someId } } - } private def getIntKey(rawJson: String): Option[BigInt] = { val idJson = AvroJsonHelper.transformJsonRaw(rawJson, idFields) @@ -118,9 +116,13 @@ class ElasticSearchProcessor( Console.out.println("Creating index and type mappings...") try { // Define analyzer in mapping - val jsonMappings = jsonTransformers.filter { - case (key, _) ⇒ topics.contains(key) - }.mapValues(_.mapping()).values.toSeq + val jsonMappings = jsonTransformers + .filter { + case (key, _) ⇒ topics.contains(key) + } + .mapValues(_.mapping()) + .values + .toSeq // Execute Elasticsearch query client.execute { diff --git a/green-river/src/main/scala/consumer/elastic/ScopeProcessor.scala b/green-river/src/main/scala/consumer/elastic/ScopeProcessor.scala index a40c78d143..578017dc71 100644 --- a/green-river/src/main/scala/consumer/elastic/ScopeProcessor.scala +++ b/green-river/src/main/scala/consumer/elastic/ScopeProcessor.scala @@ -25,11 +25,11 @@ final case class Scope(id: Int = 0, parentPath: Option[String]) { * This is a JsonProcessor which listens to scope creation and creates ES mappings * for the new scope. */ -class ScopeProcessor(uri: String, - cluster: String, - indexTopics: IndexTopicMap, - jsonTransformers: Map[String, JsonTransformer])( - implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC) +class ScopeProcessor( + uri: String, + cluster: String, + indexTopics: IndexTopicMap, + jsonTransformers: Map[String, JsonTransformer])(implicit ec: EC, ac: AS, mat: AM, cp: CP, sc: SC) extends JsonProcessor { implicit val formats: DefaultFormats.type = DefaultFormats @@ -52,26 +52,32 @@ class ScopeProcessor(uri: String, private def createIndex(scope: Scope): Future[Unit] = { val futures: Iterable[Future[Unit]] = indexTopics.map { case (indexName, topics) ⇒ { - val scopedIndexName = s"${indexName}_${scope.path}" - Console.out.println(s"Creating type mappings for index: ${scopedIndexName}") - //get json mappings for topics - val jsonMappings = jsonTransformers.filter { + val scopedIndexName = s"${indexName}_${scope.path}" + Console.out.println(s"Creating type mappings for index: $scopedIndexName") + //get json mappings for topics + val jsonMappings = jsonTransformers + .filter { case (key, _) ⇒ topics.contains(key) - }.mapValues(_.mapping()).values.toSeq + } + .mapValues(_.mapping()) + .values + .toSeq - // create index with scope in the - client.execute { + // create index with scope in the + client + .execute { create index scopedIndexName mappings (jsonMappings: _*) analysis (autocompleteAnalyzer, lowerCasedAnalyzer, upperCasedAnalyzer) - }.map { _ ⇒ + } + .map { _ ⇒ () - }.recover { - case e: RemoteTransportException - if e.getCause.isInstanceOf[IndexAlreadyExistsException] ⇒ + } + .recover { + case e: RemoteTransportException if e.getCause.isInstanceOf[IndexAlreadyExistsException] ⇒ Console.out.println(s"Index $scopedIndexName already exists, skip") case other ⇒ Console.println(s"Creation of index $scopedIndexName failed with error: $other") } - } + } } Future.sequence(futures).map(_ ⇒ ()) } diff --git a/green-river/src/main/scala/consumer/elastic/ScopedIndexer.scala b/green-river/src/main/scala/consumer/elastic/ScopedIndexer.scala index f74c729a25..e0a454416f 100644 --- a/green-river/src/main/scala/consumer/elastic/ScopedIndexer.scala +++ b/green-river/src/main/scala/consumer/elastic/ScopedIndexer.scala @@ -33,7 +33,7 @@ class ScopedIndexer(uri: String, val settings = Settings.settingsBuilder().put("cluster.name", cluster).build() val client = ElasticClient.transport(settings, ElasticsearchClientUri(uri)) - def process(offset: Long, topic: String, key: String, inputJson: String): Future[Unit] = { + def process(offset: Long, topic: String, key: String, inputJson: String): Future[Unit] = // Find json transformer jsonTransformers get topic match { case Some(t) ⇒ @@ -44,7 +44,6 @@ class ScopedIndexer(uri: String, Console.out.println(s"Skipping information from topic $topic") Future { () } } - } //This save will index into several indices based on scope. Scopes are //constructured as a path with '.' seperating the elements. We want to index @@ -66,7 +65,7 @@ class ScopedIndexer(uri: String, // if no scope found, just save the good old way case _ ⇒ Console.out.println( - s"No scope found for document ID $jid from $topic, performing unscoped indexing...") + s"No scope found for document ID $jid from $topic, performing unscoped indexing...") indexDocument(indexName, jid, document, topic) } case _ ⇒ @@ -86,37 +85,39 @@ class ScopedIndexer(uri: String, }.distinct } - private def indexScopes( - scopes: Seq[String], documentId: BigInt, document: String, topic: String): Future[Unit] = { + private def indexScopes(scopes: Seq[String], + documentId: BigInt, + document: String, + topic: String): Future[Unit] = Future - .sequence( - scopes.map { scope ⇒ + .sequence(scopes.map { scope ⇒ if (!scope.isEmpty()) { - val scopedIndexName = s"${indexName}_${scope}" + val scopedIndexName = s"${indexName}_$scope" indexDocument(scopedIndexName, documentId, document, topic) } else { - Console.out.println( - s"Skipping document with empty scope on topic $topic...\r\n$document") + Console.out.println(s"Skipping document with empty scope on topic $topic...\r\n$document") Future { () } } }) .map(_ ⇒ ()) - } private def indexDocument(scopedIndexName: String, documentId: BigInt, document: String, topic: String): Future[Unit] = { Console.out.println(s"Scoped Indexing $topic into $scopedIndexName") - val req = client.execute { - index into scopedIndexName / topic id documentId doc PassthroughSource(document) - }.map { _ ⇒ - () - }.recover { - case e: RemoteTransportException if e.getCause.isInstanceOf[IndexNotFoundException] ⇒ - Console.out.println(s"Index $scopedIndexName not found, let's try later") - throw ErrorTryAgainLater(s"Index $scopedIndexName not found") - } + val req = client + .execute { + index into scopedIndexName / topic id documentId doc PassthroughSource(document) + } + .map { _ ⇒ + () + } + .recover { + case e: RemoteTransportException if e.getCause.isInstanceOf[IndexNotFoundException] ⇒ + Console.out.println(s"Index $scopedIndexName not found, let's try later") + throw ErrorTryAgainLater(s"Index $scopedIndexName not found") + } req onFailure { case NonFatal(e) ⇒ Console.err.println(s"Error while indexing: $e") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/CountriesSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/CountriesSearchView.scala index 7b298a87b1..795c3720ae 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/CountriesSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/CountriesSearchView.scala @@ -10,15 +10,15 @@ import consumer.elastic.AvroTransformer final case class CountriesSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "countries_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("name", StringType).analyzer("autocomplete"), - field("alpha2", StringType).index("not_analyzed"), - field("alpha3", StringType).index("not_analyzed"), - field("code", StringType).index("not_analyzed"), - field("continent", StringType).analyzer("autocomplete"), - field("currency", StringType).index("not_analyzed"), - field("uses_postal_code", BooleanType), - field("is_billable", BooleanType), - field("is_shippable", BooleanType) + field("id", LongType), + field("name", StringType).analyzer("autocomplete"), + field("alpha2", StringType).index("not_analyzed"), + field("alpha3", StringType).index("not_analyzed"), + field("code", StringType).index("not_analyzed"), + field("continent", StringType).analyzer("autocomplete"), + field("currency", StringType).index("not_analyzed"), + field("uses_postal_code", BooleanType), + field("is_billable", BooleanType), + field("is_shippable", BooleanType) ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/ProductReviewsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/ProductReviewsSearchView.scala index 89bf3b59f4..4b2d17c538 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/ProductReviewsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/ProductReviewsSearchView.scala @@ -8,20 +8,20 @@ import consumer.elastic.AvroTransformer final case class ProductReviewsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "product_reviews_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("sku", StringType).index("not_analyzed"), - field("userId", LongType), - field("userName", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("title", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("rating", IntegerType).index("not_analyzed"), - field("attributes", ObjectType), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat), - field("archivedAt", DateType).format(dateFormat) + field("id", LongType), + field("sku", StringType).index("not_analyzed"), + field("userId", LongType), + field("userName", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("title", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("rating", IntegerType).index("not_analyzed"), + field("attributes", ObjectType), + field("createdAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat), + field("archivedAt", DateType).format(dateFormat) ) override def nestedFields(): List[String] = List("attributes") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/ProductsCatalogView.scala b/green-river/src/main/scala/consumer/elastic/mappings/ProductsCatalogView.scala index 3d5ded76d1..6126444410 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/ProductsCatalogView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/ProductsCatalogView.scala @@ -8,31 +8,31 @@ import consumer.elastic.AvroTransformer final case class ProductsCatalogView()(implicit ec: EC) extends AvroTransformer { def topic() = "products_catalog_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("slug", StringType).index("not_analyzed"), - field("context", StringType).index("not_analyzed"), - field("title", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("description", StringType).analyzer("autocomplete"), - field("salePrice", IntegerType).analyzer("autocomplete"), - field("retailPrice", IntegerType).analyzer("autocomplete"), - field("tags", StringType).index("not_analyzed"), - field("archivedAt", DateType).format(dateFormat), - field("skus", StringType).analyzer("upper_cased"), - field("albums").nested( - field("name", StringType).index("not_analyzed"), - field("images").nested( - field("alt", StringType).index("not_analyzed"), - field("src", StringType).index("not_analyzed"), - field("title", StringType).index("not_analyzed"), - field("baseUrl", StringType).index("not_analyzed") - ) - ), - field("taxonomies").nested( - field("taxons", StringType).analyzer("upper_cased"), - field("taxonomy", StringType).analyzer("upper_cased") + field("id", LongType), + field("slug", StringType).index("not_analyzed"), + field("context", StringType).index("not_analyzed"), + field("title", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("description", StringType).analyzer("autocomplete"), + field("salePrice", IntegerType).analyzer("autocomplete"), + field("retailPrice", IntegerType).analyzer("autocomplete"), + field("tags", StringType).index("not_analyzed"), + field("archivedAt", DateType).format(dateFormat), + field("skus", StringType).analyzer("upper_cased"), + field("albums").nested( + field("name", StringType).index("not_analyzed"), + field("images").nested( + field("alt", StringType).index("not_analyzed"), + field("src", StringType).index("not_analyzed"), + field("title", StringType).index("not_analyzed"), + field("baseUrl", StringType).index("not_analyzed") ) + ), + field("taxonomies").nested( + field("taxons", StringType).analyzer("upper_cased"), + field("taxonomy", StringType).analyzer("upper_cased") + ) ) override def nestedFields() = List("albums", "tags", "skus", "taxonomies") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/RegionsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/RegionsSearchView.scala index fcfb94d5fd..a0006f66b7 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/RegionsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/RegionsSearchView.scala @@ -10,9 +10,9 @@ import consumer.elastic.AvroTransformer final case class RegionsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "regions_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("name", StringType).analyzer("autocomplete"), - field("abbreviation", StringType).index("not_analyzed"), - field("countryId", IntegerType) + field("id", LongType), + field("name", StringType).analyzer("autocomplete"), + field("abbreviation", StringType).index("not_analyzed"), + field("countryId", IntegerType) ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/CartsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/CartsSearchView.scala index 570d4d64e4..206ddac3fc 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/CartsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/CartsSearchView.scala @@ -9,78 +9,78 @@ import consumer.elastic.mappings._ final case class CartsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "carts_search_view" def mapping() = esMapping(topic()).fields( - // Cart + // Cart + field("id", LongType), + field("scope", StringType).index("not_analyzed"), + field("referenceNumber", StringType).analyzer("upper_cased"), + field("createdAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat), + field("currency", StringType) index "not_analyzed", + // Totals + field("subTotal", IntegerType), + field("shippingTotal", IntegerType), + field("adjustmentsTotal", IntegerType), + field("taxesTotal", IntegerType), + field("grandTotal", IntegerType), + // Customer + field("customer").nested( field("id", LongType), - field("scope", StringType).index("not_analyzed"), + field("name", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("email", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("isBlacklisted", BooleanType), + field("joinedAt", DateType) format dateFormat, + field("revenue", IntegerType), + field("rank", IntegerType) + ), + // Line items + field("lineItemCount", IntegerType), + field("lineItems").nested( field("referenceNumber", StringType).analyzer("upper_cased"), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat), - field("currency", StringType) index "not_analyzed", - // Totals - field("subTotal", IntegerType), - field("shippingTotal", IntegerType), - field("adjustmentsTotal", IntegerType), - field("taxesTotal", IntegerType), - field("grandTotal", IntegerType), - // Customer - field("customer").nested( - field("id", LongType), - field("name", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("email", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("isBlacklisted", BooleanType), - field("joinedAt", DateType) format dateFormat, - field("revenue", IntegerType), - field("rank", IntegerType) - ), - // Line items - field("lineItemCount", IntegerType), - field("lineItems").nested( - field("referenceNumber", StringType).analyzer("upper_cased"), - field("state", StringType) index "not_analyzed", - field("sku", StringType) analyzer "upper_cased", - field("name", StringType) analyzer "autocomplete", - field("externalId", StringType) index "not_analyzed", - field("price", IntegerType) - ), - // Payments - field("payments").nested( - field("paymentMethodType", StringType) index "not_analyzed", - field("amount", IntegerType), - field("currency", StringType) index "not_analyzed" - ), - field("creditCardCount", IntegerType), - field("creditCardTotal", IntegerType), - field("giftCardCount", IntegerType), - field("giftCardTotal", IntegerType), - field("storeCreditCount", IntegerType), - field("storeCreditTotal", IntegerType), - // Shipments - field("shipmentCount", IntegerType), - field("shipments").nested( - field("state", StringType) index "not_analyzed", - field("shippingPrice", IntegerType), - field("adminDisplayName", StringType) analyzer "autocomplete", - field("storefrontDisplayName", StringType) analyzer "autocomplete" - ), - // Addresses - field("shippingAddressesCount", IntegerType), - address("shippingAddresses"), - field("billingAddressesCount", IntegerType), - address("billingAddresses"), - // Cart-specific - field("deletedAt", DateType) format dateFormat + field("state", StringType) index "not_analyzed", + field("sku", StringType) analyzer "upper_cased", + field("name", StringType) analyzer "autocomplete", + field("externalId", StringType) index "not_analyzed", + field("price", IntegerType) + ), + // Payments + field("payments").nested( + field("paymentMethodType", StringType) index "not_analyzed", + field("amount", IntegerType), + field("currency", StringType) index "not_analyzed" + ), + field("creditCardCount", IntegerType), + field("creditCardTotal", IntegerType), + field("giftCardCount", IntegerType), + field("giftCardTotal", IntegerType), + field("storeCreditCount", IntegerType), + field("storeCreditTotal", IntegerType), + // Shipments + field("shipmentCount", IntegerType), + field("shipments").nested( + field("state", StringType) index "not_analyzed", + field("shippingPrice", IntegerType), + field("adminDisplayName", StringType) analyzer "autocomplete", + field("storefrontDisplayName", StringType) analyzer "autocomplete" + ), + // Addresses + field("shippingAddressesCount", IntegerType), + address("shippingAddresses"), + field("billingAddressesCount", IntegerType), + address("billingAddresses"), + // Cart-specific + field("deletedAt", DateType) format dateFormat ) override def nestedFields() = List( - "customer", - "line_items", - "payments", - "shipments", - "shipping_addresses", - "billing_addresses" + "customer", + "line_items", + "payments", + "shipments", + "shipping_addresses", + "billing_addresses" ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/CouponCodesSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/CouponCodesSearchView.scala index 32ae4fefa2..3d42411324 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/CouponCodesSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/CouponCodesSearchView.scala @@ -9,12 +9,12 @@ import consumer.elastic.mappings.dateFormat final case class CouponCodesSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "coupon_codes_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("code", StringType).analyzer("upper_cased"), - field("couponId", IntegerType), - field("promotionId", IntegerType), - field("scope", StringType).index("not_analyzed"), - field("totalUsed", IntegerType), - field("createdAt", DateType).format(dateFormat) + field("id", LongType), + field("code", StringType).analyzer("upper_cased"), + field("couponId", IntegerType), + field("promotionId", IntegerType), + field("scope", StringType).index("not_analyzed"), + field("totalUsed", IntegerType), + field("createdAt", DateType).format(dateFormat) ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/CouponsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/CouponsSearchView.scala index 62596e82d2..f809d66920 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/CouponsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/CouponsSearchView.scala @@ -9,20 +9,20 @@ import consumer.elastic.mappings.dateFormat final case class CouponsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "coupons_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("promotionId", IntegerType), - field("context", StringType).index("not_analyzed"), - field("name", StringType).analyzer("autocomplete"), - field("codes", StringType).index("not_analyzed"), - field("storefrontName", StringType).analyzer("autocomplete"), - field("description", StringType).analyzer("autocomplete"), - field("activeFrom", DateType).format(dateFormat), - field("activeTo", DateType).format(dateFormat), - field("totalUsed", IntegerType), - field("maxUsesPerCode", IntegerType), - field("maxUsesPerCustomer", IntegerType), - field("createdAt", DateType).format(dateFormat), - field("archivedAt", DateType).format(dateFormat) + field("id", LongType), + field("promotionId", IntegerType), + field("context", StringType).index("not_analyzed"), + field("name", StringType).analyzer("autocomplete"), + field("codes", StringType).index("not_analyzed"), + field("storefrontName", StringType).analyzer("autocomplete"), + field("description", StringType).analyzer("autocomplete"), + field("activeFrom", DateType).format(dateFormat), + field("activeTo", DateType).format(dateFormat), + field("totalUsed", IntegerType), + field("maxUsesPerCode", IntegerType), + field("maxUsesPerCustomer", IntegerType), + field("createdAt", DateType).format(dateFormat), + field("archivedAt", DateType).format(dateFormat) ) override def nestedFields() = List("codes") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomerGroupsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomerGroupsSearchView.scala index e3042a63c1..4c9e2791e3 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomerGroupsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomerGroupsSearchView.scala @@ -9,13 +9,13 @@ import consumer.elastic.mappings._ case class CustomerGroupsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "customer_groups_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("name", StringType).analyzer("autocomplete"), - field("groupType", StringType).index("not_analyzed"), - field("customersCount", IntegerType), - field("scope", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat), - field("deletedAt", DateType).format(dateFormat) + field("id", LongType), + field("name", StringType).analyzer("autocomplete"), + field("groupType", StringType).index("not_analyzed"), + field("customersCount", IntegerType), + field("scope", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat), + field("deletedAt", DateType).format(dateFormat) ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomerItemsView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomerItemsView.scala index 5f8b46159f..da0a5d27f3 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomerItemsView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomerItemsView.scala @@ -9,21 +9,21 @@ import consumer.elastic.mappings.dateFormat final case class CustomerItemsView()(implicit ec: EC) extends AvroTransformer { def topic() = "customer_items_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("scope", StringType).index("not_analyzed"), - // Customer - field("customerId", IntegerType), - field("customerName", StringType).analyzer("autocomplete"), - field("customerEmail", StringType).analyzer("autocomplete"), - // SKU - field("skuCode", StringType).analyzer("upper_cased"), - field("skuTitle", StringType).analyzer("autocomplete"), - field("skuPrice", IntegerType), - // Order - field("orderReferenceNumber", StringType).analyzer("upper_cased"), - field("orderPlacedAt", DateType).format(dateFormat), - field("lineItemState", StringType).index("not_analyzed"), - // Save for later - field("savedForLaterAt", DateType).format(dateFormat) + field("id", LongType), + field("scope", StringType).index("not_analyzed"), + // Customer + field("customerId", IntegerType), + field("customerName", StringType).analyzer("autocomplete"), + field("customerEmail", StringType).analyzer("autocomplete"), + // SKU + field("skuCode", StringType).analyzer("upper_cased"), + field("skuTitle", StringType).analyzer("autocomplete"), + field("skuPrice", IntegerType), + // Order + field("orderReferenceNumber", StringType).analyzer("upper_cased"), + field("orderPlacedAt", DateType).format(dateFormat), + field("lineItemState", StringType).index("not_analyzed"), + // Save for later + field("savedForLaterAt", DateType).format(dateFormat) ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomersSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomersSearchView.scala index 3f792369b3..7a7f6726c9 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomersSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/CustomersSearchView.scala @@ -10,73 +10,73 @@ import consumer.elastic.mappings.dateFormat final case class CustomersSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "customers_search_view" def mapping() = esMapping(topic()).fields( - // Customer - field("id", LongType), - field("scope", StringType).index("not_analyzed"), - field("name", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("email", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("isDisabled", BooleanType), - field("isGuest", BooleanType), - field("isBlacklisted", BooleanType), - field("blacklistedBy", IntegerType), - field("blacklistedReason", StringType).analyzer("autocomplete"), - field("phoneNumber", StringType).index("not_analyzed"), - field("location", StringType).analyzer("autocomplete"), - field("joinedAt", DateType).format(dateFormat), - field("revenue", IntegerType), - field("rank", IntegerType), - // Cart - field("carts").nested( - field("customerId", IntegerType), - field("referenceNumber", StringType).analyzer("upper_cased"), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat), - field("subTotal", IntegerType), - field("shippingTotal", IntegerType), - field("adjustmentsTotal", IntegerType), - field("taxesTotal", IntegerType), - field("grandTotal", IntegerType), - field("itemsCount", IntegerType) - ), - // Orders - field("orderCount", IntegerType), - field("orders").nested( - field("customerId", IntegerType), - field("referenceNumber", StringType).analyzer("upper_cased"), - field("state", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat), - field("placedAt", DateType).format(dateFormat), - field("subTotal", IntegerType), - field("shippingTotal", IntegerType), - field("adjustmentsTotal", IntegerType), - field("taxesTotal", IntegerType), - field("grandTotal", IntegerType), - field("itemsCount", IntegerType) - ), - // Addresses - field("shippingAddressesCount", IntegerType), - address("shippingAddresses"), - field("billingAddressesCount", IntegerType), - address("billingAddresses"), - // Store credits - field("storeCreditTotal", IntegerType), - field("storeCreditCount", IntegerType), - // Revenue and rank - field("revenue", IntegerType), - field("rank", IntegerType), - // Groups - field("groups", StringType).index("not_analyzed") + // Customer + field("id", LongType), + field("scope", StringType).index("not_analyzed"), + field("name", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("email", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("isDisabled", BooleanType), + field("isGuest", BooleanType), + field("isBlacklisted", BooleanType), + field("blacklistedBy", IntegerType), + field("blacklistedReason", StringType).analyzer("autocomplete"), + field("phoneNumber", StringType).index("not_analyzed"), + field("location", StringType).analyzer("autocomplete"), + field("joinedAt", DateType).format(dateFormat), + field("revenue", IntegerType), + field("rank", IntegerType), + // Cart + field("carts").nested( + field("customerId", IntegerType), + field("referenceNumber", StringType).analyzer("upper_cased"), + field("createdAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat), + field("subTotal", IntegerType), + field("shippingTotal", IntegerType), + field("adjustmentsTotal", IntegerType), + field("taxesTotal", IntegerType), + field("grandTotal", IntegerType), + field("itemsCount", IntegerType) + ), + // Orders + field("orderCount", IntegerType), + field("orders").nested( + field("customerId", IntegerType), + field("referenceNumber", StringType).analyzer("upper_cased"), + field("state", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat), + field("placedAt", DateType).format(dateFormat), + field("subTotal", IntegerType), + field("shippingTotal", IntegerType), + field("adjustmentsTotal", IntegerType), + field("taxesTotal", IntegerType), + field("grandTotal", IntegerType), + field("itemsCount", IntegerType) + ), + // Addresses + field("shippingAddressesCount", IntegerType), + address("shippingAddresses"), + field("billingAddressesCount", IntegerType), + address("billingAddresses"), + // Store credits + field("storeCreditTotal", IntegerType), + field("storeCreditCount", IntegerType), + // Revenue and rank + field("revenue", IntegerType), + field("rank", IntegerType), + // Groups + field("groups", StringType).index("not_analyzed") ) override def nestedFields() = List( - "orders", - "carts", - "shipping_addresses", - "billing_addresses", - "groups" + "orders", + "carts", + "shipping_addresses", + "billing_addresses", + "groups" ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/FailedAuthorizationsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/FailedAuthorizationsSearchView.scala index d86d719470..7212086931 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/FailedAuthorizationsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/FailedAuthorizationsSearchView.scala @@ -9,29 +9,29 @@ import consumer.elastic.mappings.dateFormat final case class FailedAuthorizationsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "failed_authorizations_search_view" def mapping() = esMapping(topic()).fields( - // Credit Card Charge - field("id", LongType), - field("chargeId", StringType).analyzer("autocomplete"), - field("amount", IntegerType), - field("currency", StringType).index("not_analyzed"), - field("state", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat), - // Credit Card - field("holderName", StringType).analyzer("autocomplete"), - field("lastFour", IntegerType), - field("expMonth", IntegerType), - field("expYear", IntegerType), - field("brand", StringType).analyzer("autocomplete"), - // Billing Address - field("address1", StringType).analyzer("autocomplete"), - field("address2", StringType).analyzer("autocomplete"), - field("city", StringType).analyzer("autocomplete"), - field("zip", StringType).index("not_analyzed"), - field("region", StringType).analyzer("autocomplete"), - field("country", StringType).analyzer("autocomplete"), - field("continent", StringType).analyzer("autocomplete"), - // Order and Customer - field("orderReferenceNumber", StringType).analyzer("upper_cased"), - field("customerId", IntegerType) + // Credit Card Charge + field("id", LongType), + field("chargeId", StringType).analyzer("autocomplete"), + field("amount", IntegerType), + field("currency", StringType).index("not_analyzed"), + field("state", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat), + // Credit Card + field("holderName", StringType).analyzer("autocomplete"), + field("lastFour", IntegerType), + field("expMonth", IntegerType), + field("expYear", IntegerType), + field("brand", StringType).analyzer("autocomplete"), + // Billing Address + field("address1", StringType).analyzer("autocomplete"), + field("address2", StringType).analyzer("autocomplete"), + field("city", StringType).analyzer("autocomplete"), + field("zip", StringType).index("not_analyzed"), + field("region", StringType).analyzer("autocomplete"), + field("country", StringType).analyzer("autocomplete"), + field("continent", StringType).analyzer("autocomplete"), + // Order and Customer + field("orderReferenceNumber", StringType).analyzer("upper_cased"), + field("customerId", IntegerType) ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/GiftCardTransactionsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/GiftCardTransactionsSearchView.scala index 77b5549d0f..596abb853d 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/GiftCardTransactionsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/GiftCardTransactionsSearchView.scala @@ -9,31 +9,31 @@ import consumer.elastic.mappings.dateFormat final case class GiftCardTransactionsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "gift_card_transactions_view" def mapping() = esMapping(topic()).fields( - // Adjustment - field("id", LongType), - field("debit", IntegerType), - field("credit", IntegerType), - field("availableBalance", IntegerType), - field("state", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat), - // Gift Card - field("code", StringType).analyzer("upper_cased"), - field("originType", StringType).index("not_analyzed"), - field("currency", StringType).index("not_analyzed"), - field("giftCardCreatedAt", DateType).format(dateFormat), - field("scope", StringType).index("not_analyzed"), - // Order Payment - field("orderPayment").nested( - field("cordReferenceNumber", StringType).analyzer("upper_cased"), - field("orderCreatedAt", DateType).format(dateFormat), - field("orderPaymentCreatedAt", DateType).format(dateFormat) - ), - // Store Admins - field("storeAdmin").nested( - field("email", StringType).analyzer("autocomplete"), - field("name", StringType).analyzer("autocomplete"), - field("department", StringType).analyzer("autocomplete") - ) + // Adjustment + field("id", LongType), + field("debit", IntegerType), + field("credit", IntegerType), + field("availableBalance", IntegerType), + field("state", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat), + // Gift Card + field("code", StringType).analyzer("upper_cased"), + field("originType", StringType).index("not_analyzed"), + field("currency", StringType).index("not_analyzed"), + field("giftCardCreatedAt", DateType).format(dateFormat), + field("scope", StringType).index("not_analyzed"), + // Order Payment + field("orderPayment").nested( + field("cordReferenceNumber", StringType).analyzer("upper_cased"), + field("orderCreatedAt", DateType).format(dateFormat), + field("orderPaymentCreatedAt", DateType).format(dateFormat) + ), + // Store Admins + field("storeAdmin").nested( + field("email", StringType).analyzer("autocomplete"), + field("name", StringType).analyzer("autocomplete"), + field("department", StringType).analyzer("autocomplete") + ) ) override def nestedFields() = List("store_admin", "order_payment") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/GiftCardsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/GiftCardsSearchView.scala index fc3debd92c..0204df5bc8 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/GiftCardsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/GiftCardsSearchView.scala @@ -9,17 +9,17 @@ import consumer.elastic.mappings.dateFormat final case class GiftCardsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "gift_cards_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("code", StringType).analyzer("upper_cased"), - field("originType", StringType).index("not_analyzed"), - field("state", StringType).index("not_analyzed"), - field("currency", StringType).index("not_analyzed"), - field("originalBalance", IntegerType), - field("currentBalance", IntegerType), - field("availableBalance", IntegerType), - field("canceledAmount", IntegerType), - field("scope", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat) + field("id", LongType), + field("code", StringType).analyzer("upper_cased"), + field("originType", StringType).index("not_analyzed"), + field("state", StringType).index("not_analyzed"), + field("currency", StringType).index("not_analyzed"), + field("originalBalance", IntegerType), + field("currentBalance", IntegerType), + field("availableBalance", IntegerType), + field("canceledAmount", IntegerType), + field("scope", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat) ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/InventorySearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/InventorySearchView.scala index e1adc3976d..396ce7024d 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/InventorySearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/InventorySearchView.scala @@ -9,29 +9,29 @@ import consumer.elastic.mappings._ final case class InventorySearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "inventory_search_view" def mapping() = esMapping(topic()).fields( + field("id", LongType), + field("sku", StringType).analyzer("upper_cased"), + field("stockItem").nested( field("id", LongType), field("sku", StringType).analyzer("upper_cased"), - field("stockItem").nested( - field("id", LongType), - field("sku", StringType).analyzer("upper_cased"), - field("defaultUnitCost", IntegerType) - ), - field("stockLocation").nested( - field("id", LongType), - field("name", StringType).analyzer("autocomplete"), - field("type", StringType).index("not_analyzed") - ), - field("type", StringType).index("not_analyzed"), - field("onHand", IntegerType), - field("onHold", IntegerType), - field("reserved", IntegerType), - field("shipped", IntegerType), - field("afs", IntegerType), - field("afsCost", IntegerType), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat), - field("deletedAt", DateType).format(dateFormat), - field("scope", StringType).index("not_analyzed") + field("defaultUnitCost", IntegerType) + ), + field("stockLocation").nested( + field("id", LongType), + field("name", StringType).analyzer("autocomplete"), + field("type", StringType).index("not_analyzed") + ), + field("type", StringType).index("not_analyzed"), + field("onHand", IntegerType), + field("onHold", IntegerType), + field("reserved", IntegerType), + field("shipped", IntegerType), + field("afs", IntegerType), + field("afsCost", IntegerType), + field("createdAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat), + field("deletedAt", DateType).format(dateFormat), + field("scope", StringType).index("not_analyzed") ) override def nestedFields() = List("stock_item", "stock_location") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/InventoryTransactionSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/InventoryTransactionSearchView.scala index 357b47c002..62d270b881 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/InventoryTransactionSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/InventoryTransactionSearchView.scala @@ -9,16 +9,16 @@ import consumer.elastic.mappings.dateFormat final case class InventoryTransactionSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "inventory_transactions_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("sku", StringType).analyzer("upper_cased"), - field("type", StringType).index("not_analyzed"), - field("status", StringType).index("not_analyzed"), - field("stockLocationName", StringType).analyzer("autocomplete"), - field("quantityPrevious", IntegerType), - field("quantityNew", IntegerType), - field("quantityChange", IntegerType), - field("afsNew", IntegerType), - field("createdAt", DateType).format(dateFormat), - field("scope", StringType).index("not_analyzed") + field("id", LongType), + field("sku", StringType).analyzer("upper_cased"), + field("type", StringType).index("not_analyzed"), + field("status", StringType).index("not_analyzed"), + field("stockLocationName", StringType).analyzer("autocomplete"), + field("quantityPrevious", IntegerType), + field("quantityNew", IntegerType), + field("quantityChange", IntegerType), + field("afsNew", IntegerType), + field("createdAt", DateType).format(dateFormat), + field("scope", StringType).index("not_analyzed") ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/NotesSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/NotesSearchView.scala index 0ec2cce286..0d9f7e4724 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/NotesSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/NotesSearchView.scala @@ -9,71 +9,71 @@ import consumer.elastic.mappings.dateFormat final case class NotesSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "notes_search_view" def mapping() = esMapping(topic()).fields( - // Note - field("id", LongType), - field("scope", StringType).index("not_analyzed"), - field("referenceId", IntegerType), - field("referenceType", StringType).index("not_analyzed"), - field("body", StringType).analyzer("autocomplete"), - field("priority", StringType).index("not_analyzed"), + // Note + field("id", LongType), + field("scope", StringType).index("not_analyzed"), + field("referenceId", IntegerType), + field("referenceType", StringType).index("not_analyzed"), + field("body", StringType).analyzer("autocomplete"), + field("priority", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat), + field("deletedAt", DateType).format(dateFormat), + field("author").nested( + field("email", StringType).analyzer("autocomplete"), + field("name", StringType).analyzer("autocomplete"), + field("department", StringType).analyzer("autocomplete") + ), + field("order").nested( + field("accountId", IntegerType), + field("referenceNumber", StringType).analyzer("upper_cased"), + field("state", StringType).index("not_analyzed"), field("createdAt", DateType).format(dateFormat), - field("deletedAt", DateType).format(dateFormat), - field("author").nested( - field("email", StringType).analyzer("autocomplete"), - field("name", StringType).analyzer("autocomplete"), - field("department", StringType).analyzer("autocomplete") - ), - field("order").nested( - field("accountId", IntegerType), - field("referenceNumber", StringType).analyzer("upper_cased"), - field("state", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat), - field("placedAt", DateType).format(dateFormat), - field("subTotal", IntegerType), - field("shippingTotal", IntegerType), - field("adjustmentsTotal", IntegerType), - field("taxesTotal", IntegerType), - field("grandTotal", IntegerType), - field("itemsCount", IntegerType) - ), - field("customer").nested( - field("id", LongType), - field("name", StringType).analyzer("autocomplete"), - field("email", StringType).analyzer("autocomplete"), - field("isBlacklisted", BooleanType), - field("joinedAt", DateType).format(dateFormat) - ), - field("giftCard").nested( - field("code", StringType).analyzer("upper_cased"), - field("originType", StringType).index("not_analyzed"), - field("currency", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat) - ), - field("skuItem").nested( - field("id", LongType), - field("sku", StringType).analyzer("upper_cased"), - field("type", ObjectType), - field("attributes", ObjectType), - field("createdAt", DateType).format(dateFormat) - ), - field("product").nested( - field("id", LongType), - field("attributes", ObjectType), - field("variants", ObjectType), - field("createdAt", DateType).format(dateFormat) - ), - field("promotion").nested( - field("id", LongType), - field("applyType", StringType).index("not_analyzed"), - field("attributes", ObjectType), - field("createdAt", DateType).format(dateFormat) - ), - field("coupon").nested( - field("id", LongType), - field("promotion_id", IntegerType), - field("attributes", ObjectType), - field("createdAt", DateType).format(dateFormat) - ) + field("placedAt", DateType).format(dateFormat), + field("subTotal", IntegerType), + field("shippingTotal", IntegerType), + field("adjustmentsTotal", IntegerType), + field("taxesTotal", IntegerType), + field("grandTotal", IntegerType), + field("itemsCount", IntegerType) + ), + field("customer").nested( + field("id", LongType), + field("name", StringType).analyzer("autocomplete"), + field("email", StringType).analyzer("autocomplete"), + field("isBlacklisted", BooleanType), + field("joinedAt", DateType).format(dateFormat) + ), + field("giftCard").nested( + field("code", StringType).analyzer("upper_cased"), + field("originType", StringType).index("not_analyzed"), + field("currency", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat) + ), + field("skuItem").nested( + field("id", LongType), + field("sku", StringType).analyzer("upper_cased"), + field("type", ObjectType), + field("attributes", ObjectType), + field("createdAt", DateType).format(dateFormat) + ), + field("product").nested( + field("id", LongType), + field("attributes", ObjectType), + field("variants", ObjectType), + field("createdAt", DateType).format(dateFormat) + ), + field("promotion").nested( + field("id", LongType), + field("applyType", StringType).index("not_analyzed"), + field("attributes", ObjectType), + field("createdAt", DateType).format(dateFormat) + ), + field("coupon").nested( + field("id", LongType), + field("promotion_id", IntegerType), + field("attributes", ObjectType), + field("createdAt", DateType).format(dateFormat) + ) ) override def nestedFields() = diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/OrdersSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/OrdersSearchView.scala index 39a68a205a..5c3220ad86 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/OrdersSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/OrdersSearchView.scala @@ -9,99 +9,99 @@ import consumer.elastic.mappings._ final case class OrdersSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "orders_search_view" def mapping() = esMapping(topic()).fields( - // Order + // Order + field("id", LongType), + field("referenceNumber", StringType).analyzer("upper_cased"), + field("state", StringType).index("not_analyzed"), + field("scope", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat), + field("placedAt", DateType).format(dateFormat), + field("currency", StringType).index("not_analyzed"), + // Totals + field("subTotal", IntegerType), + field("shippingTotal", IntegerType), + field("adjustmentsTotal", IntegerType), + field("taxesTotal", IntegerType), + field("grandTotal", IntegerType), + // Customer + field("customer").nested( field("id", LongType), + field("name", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("email", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("isBlacklisted", BooleanType), + field("joinedAt", DateType).format(dateFormat), + field("revenue", IntegerType), + field("rank", IntegerType) + ), + // Line items + field("lineItemCount", IntegerType), + field("lineItems").nested( field("referenceNumber", StringType).analyzer("upper_cased"), field("state", StringType).index("not_analyzed"), - field("scope", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat), - field("placedAt", DateType).format(dateFormat), - field("currency", StringType).index("not_analyzed"), - // Totals - field("subTotal", IntegerType), - field("shippingTotal", IntegerType), - field("adjustmentsTotal", IntegerType), - field("taxesTotal", IntegerType), - field("grandTotal", IntegerType), - // Customer - field("customer").nested( - field("id", LongType), - field("name", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("email", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("isBlacklisted", BooleanType), - field("joinedAt", DateType).format(dateFormat), - field("revenue", IntegerType), - field("rank", IntegerType) - ), - // Line items - field("lineItemCount", IntegerType), - field("lineItems").nested( - field("referenceNumber", StringType).analyzer("upper_cased"), - field("state", StringType).index("not_analyzed"), - field("sku", StringType).analyzer("upper_cased"), - field("name", StringType).analyzer("autocomplete"), - field("price", IntegerType) - ), - // Payments - field("payments").nested( - field("paymentMethodType", StringType).index("not_analyzed"), - field("amount", IntegerType), - field("currency", StringType).index("not_analyzed") - ), - field("creditCardCount", IntegerType), - field("creditCardTotal", IntegerType), - field("giftCardCount", IntegerType), - field("giftCardTotal", IntegerType), - field("storeCreditCount", IntegerType), - field("storeCreditTotal", IntegerType), - // Shipments - field("shipmentCount", IntegerType), - field("shipments").nested( - field("state", StringType).index("not_analyzed"), - field("shippingPrice", IntegerType), - field("adminDisplayName", StringType).analyzer("autocomplete"), - field("storefrontDisplayName", StringType).analyzer("autocomplete") - ), - field("shippingMethod").nested( - field("id", LongType), - field("price", IntegerType), - field("shippingMethodId", IntegerType), - field("adminDisplayName", StringType).analyzer("autocomplete"), - field("storefrontDisplayName", StringType).analyzer("autocomplete") - ), - // Addresses - field("shippingAddressesCount", IntegerType), - address("shippingAddresses"), - field("billingAddressesCount", IntegerType), - address("billingAddresses"), - // Assignments - field("assignmentCount", IntegerType), - field("assignees").nested( - field("name", StringType).analyzer("autocomplete"), - field("assignedAt", DateType).format(dateFormat) - ), - // Returns - field("returns").nested( - field("referenceNumber", StringType).analyzer("upper_cased"), - field("state", StringType).index("not_analyzed"), - field("returnType", StringType).index("not_analyzed"), - field("placedAt", DateType).format(dateFormat) - ) + field("sku", StringType).analyzer("upper_cased"), + field("name", StringType).analyzer("autocomplete"), + field("price", IntegerType) + ), + // Payments + field("payments").nested( + field("paymentMethodType", StringType).index("not_analyzed"), + field("amount", IntegerType), + field("currency", StringType).index("not_analyzed") + ), + field("creditCardCount", IntegerType), + field("creditCardTotal", IntegerType), + field("giftCardCount", IntegerType), + field("giftCardTotal", IntegerType), + field("storeCreditCount", IntegerType), + field("storeCreditTotal", IntegerType), + // Shipments + field("shipmentCount", IntegerType), + field("shipments").nested( + field("state", StringType).index("not_analyzed"), + field("shippingPrice", IntegerType), + field("adminDisplayName", StringType).analyzer("autocomplete"), + field("storefrontDisplayName", StringType).analyzer("autocomplete") + ), + field("shippingMethod").nested( + field("id", LongType), + field("price", IntegerType), + field("shippingMethodId", IntegerType), + field("adminDisplayName", StringType).analyzer("autocomplete"), + field("storefrontDisplayName", StringType).analyzer("autocomplete") + ), + // Addresses + field("shippingAddressesCount", IntegerType), + address("shippingAddresses"), + field("billingAddressesCount", IntegerType), + address("billingAddresses"), + // Assignments + field("assignmentCount", IntegerType), + field("assignees").nested( + field("name", StringType).analyzer("autocomplete"), + field("assignedAt", DateType).format(dateFormat) + ), + // Returns + field("returns").nested( + field("referenceNumber", StringType).analyzer("upper_cased"), + field("state", StringType).index("not_analyzed"), + field("returnType", StringType).index("not_analyzed"), + field("placedAt", DateType).format(dateFormat) + ) ) override def nestedFields() = List( - "customer", - "line_items", - "payments", - "shipments", - "shipping_method", - "shipping_addresses", - "billing_addresses", - "assignees", - "returns" + "customer", + "line_items", + "payments", + "shipments", + "shipping_method", + "shipping_addresses", + "billing_addresses", + "assignees", + "returns" ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/ProductsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/ProductsSearchView.scala index 249e191641..a9bc8b841e 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/ProductsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/ProductsSearchView.scala @@ -9,35 +9,35 @@ import consumer.elastic.mappings.dateFormat final case class ProductsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "products_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("productId", IntegerType), - field("slug", StringType).index("not_analyzed"), - field("context", StringType).index("not_analyzed"), - field("scope", StringType).index("not_analyzed"), - field("title", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("description", StringType).analyzer("autocomplete"), - field("skus", StringType).analyzer("upper_cased"), - field("tags", StringType).index("not_analyzed"), - field("taxonomies", StringType).nested( - field("taxons", StringType).index("not_analyzed"), - field("taxonomy", StringType).index("not_analyzed") - ), - field("activeFrom", DateType).format(dateFormat), - field("activeTo", DateType).format(dateFormat), + field("id", LongType), + field("productId", IntegerType), + field("slug", StringType).index("not_analyzed"), + field("context", StringType).index("not_analyzed"), + field("scope", StringType).index("not_analyzed"), + field("title", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("description", StringType).analyzer("autocomplete"), + field("skus", StringType).analyzer("upper_cased"), + field("tags", StringType).index("not_analyzed"), + field("taxonomies", StringType).nested( + field("taxons", StringType).index("not_analyzed"), + field("taxonomy", StringType).index("not_analyzed") + ), + field("activeFrom", DateType).format(dateFormat), + field("activeTo", DateType).format(dateFormat), + field("archivedAt", DateType).format(dateFormat), + field("externalId", StringType).index("not_analyzed"), + field("albums").nested( + field("name", StringType).index("not_analyzed"), field("archivedAt", DateType).format(dateFormat), - field("externalId", StringType).index("not_analyzed"), - field("albums").nested( - field("name", StringType).index("not_analyzed"), - field("archivedAt", DateType).format(dateFormat), - field("images").nested( - field("alt", StringType).index("not_analyzed"), - field("src", StringType).index("not_analyzed"), - field("title", StringType).index("not_analyzed"), - field("baseUrl", StringType).index("not_analyzed") - ) + field("images").nested( + field("alt", StringType).index("not_analyzed"), + field("src", StringType).index("not_analyzed"), + field("title", StringType).index("not_analyzed"), + field("baseUrl", StringType).index("not_analyzed") ) + ) ) override def nestedFields() = List("albums", "skus", "tags", "taxonomies", "taxons") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/PromotionsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/PromotionsSearchView.scala index f3ac830f16..a4db57348c 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/PromotionsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/PromotionsSearchView.scala @@ -9,20 +9,20 @@ import consumer.elastic.mappings._ final case class PromotionsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "promotions_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("context", StringType).index("not_analyzed"), - field("scope", StringType).index("not_analyzed"), - field("applyType", StringType).index("not_analyzed"), - field("promotionName", StringType).analyzer("autocomplete"), - field("storefrontName", StringType).analyzer("autocomplete"), - field("description", StringType).analyzer("autocomplete"), - field("activeFrom", DateType).format(dateFormat), - field("activeTo", DateType).format(dateFormat), - field("totalUsed", IntegerType), - field("currentCarts", IntegerType), - field("createdAt", DateType).format(dateFormat), - field("discounts", IntegerType), - field("archivedAt", DateType).format(dateFormat) + field("id", LongType), + field("context", StringType).index("not_analyzed"), + field("scope", StringType).index("not_analyzed"), + field("applyType", StringType).index("not_analyzed"), + field("promotionName", StringType).analyzer("autocomplete"), + field("storefrontName", StringType).analyzer("autocomplete"), + field("description", StringType).analyzer("autocomplete"), + field("activeFrom", DateType).format(dateFormat), + field("activeTo", DateType).format(dateFormat), + field("totalUsed", IntegerType), + field("currentCarts", IntegerType), + field("createdAt", DateType).format(dateFormat), + field("discounts", IntegerType), + field("archivedAt", DateType).format(dateFormat) ) override def nestedFields() = List("discounts") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/SkuSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/SkuSearchView.scala index 41f7c9e8d3..103abacf19 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/SkuSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/SkuSearchView.scala @@ -9,18 +9,18 @@ import consumer.elastic.mappings.dateFormat final case class SkuSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "sku_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("skuCode", StringType).analyzer("upper_cased"), - field("context", StringType).index("not_analyzed"), - field("scope", StringType).index("not_analyzed"), - field("title", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("salePrice", IntegerType), - field("salePriceCurrency", StringType), - field("retailPrice", IntegerType), - field("retailPriceCurrency", StringType), - field("archivedAt", DateType).format(dateFormat), - field("externalId", StringType).index("not_analyzed") + field("id", LongType), + field("skuCode", StringType).analyzer("upper_cased"), + field("context", StringType).index("not_analyzed"), + field("scope", StringType).index("not_analyzed"), + field("title", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("salePrice", IntegerType), + field("salePriceCurrency", StringType), + field("retailPrice", IntegerType), + field("retailPriceCurrency", StringType), + field("archivedAt", DateType).format(dateFormat), + field("externalId", StringType).index("not_analyzed") ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreAdminsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreAdminsSearchView.scala index 874f0662f6..e7389975cd 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreAdminsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreAdminsSearchView.scala @@ -9,15 +9,15 @@ import consumer.elastic.mappings.dateFormat final case class StoreAdminsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "store_admins_search_view" def mapping() = esMapping(topic()).fields( - // Store Admin - field("id", LongType), - field("scope", StringType).index("not_analyzed"), - field("email", StringType).analyzer("autocomplete"), - field("name", StringType).analyzer("autocomplete"), - field("phoneNumber", StringType).index("not_analyzed"), - field("department", StringType).analyzer("autocomplete"), - field("state", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat) + // Store Admin + field("id", LongType), + field("scope", StringType).index("not_analyzed"), + field("email", StringType).analyzer("autocomplete"), + field("name", StringType).analyzer("autocomplete"), + field("phoneNumber", StringType).index("not_analyzed"), + field("department", StringType).analyzer("autocomplete"), + field("state", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat) ) override def nestedFields() = List("assignments") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreCreditTransactionsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreCreditTransactionsSearchView.scala index 2b6e1c2e98..dfe053c769 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreCreditTransactionsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreCreditTransactionsSearchView.scala @@ -9,31 +9,31 @@ import consumer.elastic.mappings.dateFormat final case class StoreCreditTransactionsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "store_credit_transactions_search_view" def mapping() = esMapping(topic()).fields( - // Adjustment - field("id", LongType), - field("debit", IntegerType), - field("availableBalance", IntegerType), - field("state", StringType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat), - // Store Credit - field("storeCreditId", IntegerType), - field("customerId", IntegerType), - field("originType", StringType).index("not_analyzed"), - field("currency", StringType).index("not_analyzed"), - field("storeCreditCreatedAt", DateType).format(dateFormat), - field("scope", StringType).index("not_analyzed"), - // Order Payment - field("orderPayment").nested( - field("cordReferenceNumber", StringType).analyzer("upper_cased"), - field("orderCreatedAt", DateType).format(dateFormat), - field("orderPaymentCreatedAt", DateType).format(dateFormat) - ), - // Store Admins - field("storeAdmin").nested( - field("email", StringType).analyzer("autocomplete"), - field("name", StringType).analyzer("autocomplete"), - field("department", StringType).analyzer("autocomplete") - ) + // Adjustment + field("id", LongType), + field("debit", IntegerType), + field("availableBalance", IntegerType), + field("state", StringType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat), + // Store Credit + field("storeCreditId", IntegerType), + field("customerId", IntegerType), + field("originType", StringType).index("not_analyzed"), + field("currency", StringType).index("not_analyzed"), + field("storeCreditCreatedAt", DateType).format(dateFormat), + field("scope", StringType).index("not_analyzed"), + // Order Payment + field("orderPayment").nested( + field("cordReferenceNumber", StringType).analyzer("upper_cased"), + field("orderCreatedAt", DateType).format(dateFormat), + field("orderPaymentCreatedAt", DateType).format(dateFormat) + ), + // Store Admins + field("storeAdmin").nested( + field("email", StringType).analyzer("autocomplete"), + field("name", StringType).analyzer("autocomplete"), + field("department", StringType).analyzer("autocomplete") + ) ) override def nestedFields() = List("store_admin", "order_payment") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreCreditsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreCreditsSearchView.scala index d87c88e88e..0c322fad99 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreCreditsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/StoreCreditsSearchView.scala @@ -9,24 +9,24 @@ import consumer.elastic.mappings.dateFormat final case class StoreCreditsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "store_credits_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("customerId", IntegerType), - field("originId", IntegerType), - field("originType", StringType).index("not_analyzed"), - field("state", StringType).index("not_analyzed"), - field("currency", StringType).index("not_analyzed"), - field("originalBalance", IntegerType), - field("currentBalance", IntegerType), - field("availableBalance", IntegerType), - field("canceledAmount", IntegerType), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat), - field("scope", StringType).index("not_analyzed"), - field("storeAdmin").nested( - field("email", StringType).analyzer("autocomplete"), - field("name", StringType).analyzer("autocomplete"), - field("department", StringType).analyzer("autocomplete") - ) + field("id", LongType), + field("customerId", IntegerType), + field("originId", IntegerType), + field("originType", StringType).index("not_analyzed"), + field("state", StringType).index("not_analyzed"), + field("currency", StringType).index("not_analyzed"), + field("originalBalance", IntegerType), + field("currentBalance", IntegerType), + field("availableBalance", IntegerType), + field("canceledAmount", IntegerType), + field("createdAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat), + field("scope", StringType).index("not_analyzed"), + field("storeAdmin").nested( + field("email", StringType).analyzer("autocomplete"), + field("name", StringType).analyzer("autocomplete"), + field("department", StringType).analyzer("autocomplete") + ) ) override def nestedFields() = List("store_admin") diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/TaxonomiesSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/TaxonomiesSearchView.scala index 3c9060f9c5..7936c39640 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/TaxonomiesSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/TaxonomiesSearchView.scala @@ -9,19 +9,19 @@ import consumer.elastic.mappings.dateFormat final case class TaxonomiesSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "taxonomies_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("taxonomyId", IntegerType), - field("name", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("context", StringType).index("not_analyzed"), - field("scope", StringType).index("not_analyzed"), - field("type", StringType).index("not_analyzed"), - field("valuesCount", IntegerType), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat), - field("activeFrom", DateType).format(dateFormat), - field("activeTo", DateType).format(dateFormat), - field("archivedAt", DateType).format(dateFormat) + field("id", LongType), + field("taxonomyId", IntegerType), + field("name", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("context", StringType).index("not_analyzed"), + field("scope", StringType).index("not_analyzed"), + field("type", StringType).index("not_analyzed"), + field("valuesCount", IntegerType), + field("createdAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat), + field("activeFrom", DateType).format(dateFormat), + field("activeTo", DateType).format(dateFormat), + field("archivedAt", DateType).format(dateFormat) ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/admin/TaxonsSearchView.scala b/green-river/src/main/scala/consumer/elastic/mappings/admin/TaxonsSearchView.scala index e408478834..00ea952229 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/admin/TaxonsSearchView.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/admin/TaxonsSearchView.scala @@ -9,20 +9,20 @@ import consumer.elastic.mappings.dateFormat final case class TaxonsSearchView()(implicit ec: EC) extends AvroTransformer { def topic() = "taxons_search_view" def mapping() = esMapping(topic()).fields( - field("id", LongType), - field("taxonomyId", IntegerType), - field("taxonId", IntegerType), - field("parentId", IntegerType), - field("name", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("context", StringType).index("not_analyzed"), - field("scope", StringType).index("not_analyzed"), - field("productsCount", IntegerType).index("not_analyzed"), - field("createdAt", DateType).format(dateFormat), - field("updatedAt", DateType).format(dateFormat), - field("activeFrom", DateType).format(dateFormat), - field("activeTo", DateType).format(dateFormat), - field("archivedAt", DateType).format(dateFormat) + field("id", LongType), + field("taxonomyId", IntegerType), + field("taxonId", IntegerType), + field("parentId", IntegerType), + field("name", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("context", StringType).index("not_analyzed"), + field("scope", StringType).index("not_analyzed"), + field("productsCount", IntegerType).index("not_analyzed"), + field("createdAt", DateType).format(dateFormat), + field("updatedAt", DateType).format(dateFormat), + field("activeFrom", DateType).format(dateFormat), + field("activeTo", DateType).format(dateFormat), + field("archivedAt", DateType).format(dateFormat) ) } diff --git a/green-river/src/main/scala/consumer/elastic/mappings/package.scala b/green-river/src/main/scala/consumer/elastic/mappings/package.scala index 5390ce14e8..2501a09aa4 100644 --- a/green-river/src/main/scala/consumer/elastic/mappings/package.scala +++ b/green-river/src/main/scala/consumer/elastic/mappings/package.scala @@ -12,42 +12,42 @@ package object mappings { } val autocompleteAnalyzer = CustomAnalyzerDefinition( - "autocomplete", - NGramTokenizer("autocomplete_tokenizer", - 3, - 20, - Seq("letter", "digit", "punctuation", "symbol", "whitespace")), - LowercaseTokenFilter + "autocomplete", + NGramTokenizer("autocomplete_tokenizer", + 3, + 20, + Seq("letter", "digit", "punctuation", "symbol", "whitespace")), + LowercaseTokenFilter ) val lowerCasedAnalyzer = CustomAnalyzerDefinition( - "lower_cased", - KeywordTokenizer("lower_cased_keyword_tokenizer"), - LowercaseTokenFilter + "lower_cased", + KeywordTokenizer("lower_cased_keyword_tokenizer"), + LowercaseTokenFilter ) val upperCasedAnalyzer = CustomAnalyzerDefinition( - "upper_cased", - KeywordTokenizer("upper_cased_keyword_tokenizer"), - UppercaseTokenFilter + "upper_cased", + KeywordTokenizer("upper_cased_keyword_tokenizer"), + UppercaseTokenFilter ) def address(name: String) = field(name).nested( - field("address1", StringType).analyzer("autocomplete"), - field("address2", StringType).analyzer("autocomplete"), - field("city", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("zip", StringType).index("not_analyzed"), - field("region", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("country", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("continent", StringType) - .analyzer("autocomplete") - .fields(field("raw", StringType).index("not_analyzed")), - field("currency", StringType).index("not_analyzed") + field("address1", StringType).analyzer("autocomplete"), + field("address2", StringType).analyzer("autocomplete"), + field("city", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("zip", StringType).index("not_analyzed"), + field("region", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("country", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("continent", StringType) + .analyzer("autocomplete") + .fields(field("raw", StringType).index("not_analyzed")), + field("currency", StringType).index("not_analyzed") ) } diff --git a/green-river/src/main/scala/consumer/package.scala b/green-river/src/main/scala/consumer/package.scala index 21ffca350d..7c7e0d1814 100644 --- a/green-river/src/main/scala/consumer/package.scala +++ b/green-river/src/main/scala/consumer/package.scala @@ -40,6 +40,7 @@ final case class PassthroughSource(json: String) extends DocumentSource * Used in processors when they want to indicate this document should be processed * again later by MultiTopicConsumer (re-seek to this offset again) */ -trait TryAgainLater { this: Throwable ⇒ } +trait TryAgainLater { this: Throwable ⇒ +} case class ErrorTryAgainLater(cause: String) extends Throwable with TryAgainLater diff --git a/green-river/src/main/scala/consumer/utils/HttpSupport.scala b/green-river/src/main/scala/consumer/utils/HttpSupport.scala index 5ea6956839..d1d8ff120e 100644 --- a/green-river/src/main/scala/consumer/utils/HttpSupport.scala +++ b/green-river/src/main/scala/consumer/utils/HttpSupport.scala @@ -52,7 +52,7 @@ case class Phoenix(conn: PhoenixConnectionInfo)(implicit ec: EC, ac: AS, mat: AM response ← postRequest(suffix, body, jwtToken) } yield response - private def getJwtToken: XorT[Future, Failures, String] = { + private def getJwtToken: XorT[Future, Failures, String] = cache.sync .get("jwtAuth") .fold { @@ -62,16 +62,16 @@ case class Phoenix(conn: PhoenixConnectionInfo)(implicit ec: EC, ac: AS, mat: AM _ ← XorT.right[Future, Failures, Unit](cache.put("jwtAuth")(jwtToken, Some(7.days))) } yield jwtToken }(XorT.pure[Future, Failures, String]) - } private def authenticate(): HttpResult = { val request = HttpRequest( - method = HttpMethods.POST, - uri = authUri, - entity = HttpEntity.Strict( - ContentTypes.`application/json`, - ByteString(authBodyTemplate.format(conn.user, conn.pass, conn.org)) - )) + method = HttpMethods.POST, + uri = authUri, + entity = HttpEntity.Strict( + ContentTypes.`application/json`, + ByteString(authBodyTemplate.format(conn.user, conn.pass, conn.org)) + ) + ) HttpResult.right(Http().singleRequest(request, settings = cp)) } @@ -91,8 +91,8 @@ case class Phoenix(conn: PhoenixConnectionInfo)(implicit ec: EC, ac: AS, mat: AM val request = HttpRequest(method = HttpMethods.POST, uri = fullUri(suffix), entity = HttpEntity.Strict( - ContentTypes.`application/json`, - ByteString(body) + ContentTypes.`application/json`, + ByteString(body) )).addHeader(RawHeader(authHeaderName, token)) HttpResult.right(Http().singleRequest(request, settings = cp)) diff --git a/green-river/src/main/scala/consumer/utils/JsonTransformers.scala b/green-river/src/main/scala/consumer/utils/JsonTransformers.scala index 581cf70a83..1f670d6595 100644 --- a/green-river/src/main/scala/consumer/utils/JsonTransformers.scala +++ b/green-river/src/main/scala/consumer/utils/JsonTransformers.scala @@ -1,19 +1,18 @@ package consumer.utils -import org.json4s.JsonAST.{JArray, JValue, JField, JString, JInt} +import org.json4s.JsonAST.{JArray, JField, JInt, JString, JValue} /** - * Helper functions to transform JSON. + * Helper functions to transform JSON. */ object JsonTransformers { def underscoreToCamel(s: String): String = "_([a-z])".r.replaceAllIn(s, _.group(1).toUpperCase) - def camelCase(input: JValue): JValue = { + def camelCase(input: JValue): JValue = input.transformField { case JField(name, anything) ⇒ (underscoreToCamel(name), anything) } - } def dateTimeToDateString(obj: JValue): JValue = { val date = for { @@ -25,24 +24,20 @@ object JsonTransformers { JInt(second) ← obj \ "second" JInt(micro) ← obj \ "micro" milliseconds = micro / 1000 - } yield - JString( - f"$year%04d-$month%02d-$day%02dT$hour%02d:$minute%02d:$second%02d.$milliseconds%03dZ") + } yield JString(f"$year%04d-$month%02d-$day%02dT$hour%02d:$minute%02d:$second%02d.$milliseconds%03dZ") if (date.isEmpty) obj else date.head } - def extractStringSeq(data: JValue, fieldName: String): Seq[String] = { + def extractStringSeq(data: JValue, fieldName: String): Seq[String] = data \ fieldName match { case JArray(list: List[JValue]) ⇒ list.collect { case JString(value) ⇒ value } case _ ⇒ Seq.empty } - } - def extractBigIntSeq(data: JValue, fieldName: String): Seq[String] = { + def extractBigIntSeq(data: JValue, fieldName: String): Seq[String] = data \ fieldName match { case JArray(list: List[JValue]) ⇒ list.collect { case JInt(value) ⇒ value.toString } case _ ⇒ Seq.empty } - } } diff --git a/phoenix-scala/build.sbt b/phoenix-scala/build.sbt index 189543913f..90bc06992c 100644 --- a/phoenix-scala/build.sbt +++ b/phoenix-scala/build.sbt @@ -21,28 +21,29 @@ lazy val phoenix = (project in file("phoenix")) }, (mainClass in Compile) := Some("phoenix.server.Main"), // TODO @anna move the rest of location settings to common when tests are moved into subprojects - scalaSource in Test := baseDirectory.value / "test" / "unit", - scalaSource in IT := baseDirectory.value / "test" / "integration", - scalaSource in ET := baseDirectory.value / "test" / "integration", - resourceDirectory in Test := baseDirectory.value / "test" / "resources", - resourceDirectory in IT := (resourceDirectory in Test).value, - resourceDirectory in ET := (resourceDirectory in Test).value, + scalaSource in Test := baseDirectory.value / "test" / "unit", + scalaSource in IT := baseDirectory.value / "test" / "integration", + scalaSource in ET := baseDirectory.value / "test" / "integration", + resourceDirectory in Test := baseDirectory.value / "test" / "resources", + resourceDirectory in IT := (resourceDirectory in Test).value, + resourceDirectory in ET := (resourceDirectory in Test).value, initialCommands in console := fromFile("project/console_init").getLines.mkString("\n"), initialCommands in (Compile, consoleQuick) := "", - test := Def.sequential(compile in Test, compile in IT, compile in ET, - test in Test, test in IT, test in ET).value, + test := Def + .sequential(compile in Test, compile in IT, compile in ET, test in Test, test in IT, test in ET) + .value, testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-oD"), javaOptions in Test ++= Seq("-Xmx2G", "-XX:+UseConcMarkSweepGC", "-Dphoenix.env=test"), parallelExecution in Compile := true, parallelExecution in Test := true, - parallelExecution in IT := false, - parallelExecution in ET := false, + parallelExecution in IT := false, + parallelExecution in ET := false, fork in Test := false, - fork in IT := true, /** FIXME: We couldn’t run ITs in parallel if we fork */ - fork in ET := true, + fork in IT := true, /** FIXME: We couldn’t run ITs in parallel if we fork */ + fork in ET := true, logBuffered in Test := false, - logBuffered in IT := false, - logBuffered in ET := false + logBuffered in IT := false, + logBuffered in ET := false ) lazy val root = (project in file(".")) @@ -63,7 +64,7 @@ lazy val seeder = (project in file("seeder")) libraryDependencies ++= Dependencies.gatling, cleanFiles += baseDirectory.value / "results", // we cannot fork and set javaOptions simply, as it causes some weird issue with db schema creation - initialize ~= (_ => System.setProperty("phoenix.env", "test" )), + initialize ~= (_ => System.setProperty("phoenix.env", "test")), fullClasspath in assembly := { // thanks sbt for that hacky way of excluding inter-project dependencies val phoenixClasses = (crossTarget in compile in phoenix).value.getAbsolutePath (fullClasspath in assembly).value.filterNot(_.data.getAbsolutePath.startsWith(phoenixClasses)) @@ -89,9 +90,9 @@ fullAssembly := Def.task().dependsOn(writeVersion in root, assembly in phoenix, // Injected seeds val seedCommand = " seeds.Seeds seed --seedAdmins" -seed := (runMain in Compile in seeder).partialInput(seedCommand).evaluated +seed := (runMain in Compile in seeder).partialInput(seedCommand).evaluated seedDemo := (runMain in Compile in seeder).partialInput(s"$seedCommand --seedDemo 1").evaluated // Gatling seeds -seedOneshot := (runMain in Compile in seeder).partialInput(" gatling.seeds.OneshotSeeds").evaluated +seedOneshot := (runMain in Compile in seeder).partialInput(" gatling.seeds.OneshotSeeds").evaluated seedContinuous := (runMain in Compile in seeder).partialInput(" gatling.seeds.ContinuousSeeds").evaluated diff --git a/phoenix-scala/core/app/core/db/ExPostgresDriver.scala b/phoenix-scala/core/app/core/db/ExPostgresDriver.scala index eceb81be4f..837e707f72 100644 --- a/phoenix-scala/core/app/core/db/ExPostgresDriver.scala +++ b/phoenix-scala/core/app/core/db/ExPostgresDriver.scala @@ -44,10 +44,9 @@ trait ExPostgresDriver new SimpleArrayJdbcType[String]("text").to(_.toList) implicit val json4sJsonArrayTypeMapper: DriverJdbcType[List[Json]] = - new AdvancedArrayJdbcType[Json]( - pgjson, - (s) ⇒ SimpleArrayUtils.fromString[Json](jsonMethods.parse(_))(s).orNull, - (v) ⇒ SimpleArrayUtils.mkString[Json](_.toString())(v)).to(_.toList) + new AdvancedArrayJdbcType[Json](pgjson, + (s) ⇒ SimpleArrayUtils.fromString[Json](jsonMethods.parse(_))(s).orNull, + (v) ⇒ SimpleArrayUtils.mkString[Json](_.toString())(v)).to(_.toList) } } diff --git a/phoenix-scala/core/app/core/db/FoxFailureException.scala b/phoenix-scala/core/app/core/db/FoxFailureException.scala index b4f3115888..e3e3d36aa2 100644 --- a/phoenix-scala/core/app/core/db/FoxFailureException.scala +++ b/phoenix-scala/core/app/core/db/FoxFailureException.scala @@ -2,5 +2,4 @@ package core.db import core.failures.Failures -case class FoxFailureException(failures: Failures) - extends Exception(failures.flatten.mkString("\n")) +case class FoxFailureException(failures: Failures) extends Exception(failures.flatten.mkString("\n")) diff --git a/phoenix-scala/core/app/core/db/FoxModel.scala b/phoenix-scala/core/app/core/db/FoxModel.scala index ce70d552df..892ec1e782 100644 --- a/phoenix-scala/core/app/core/db/FoxModel.scala +++ b/phoenix-scala/core/app/core/db/FoxModel.scala @@ -5,7 +5,7 @@ import cats.data.ValidatedNel import cats.implicits._ import core.failures.{Failure, Failures, GeneralFailure} import core.utils.Strings._ -import core.utils.{Validation, friendlyClassName} +import core.utils.{friendlyClassName, Validation} trait Identity[A] { self: A ⇒ type Id = Int @@ -30,7 +30,6 @@ trait FoxModel[M <: FoxModel[M]] extends Validation[M] with Identity[M] { self: def mustBeCreated: Either[Failures, M] = if (id == 0) - Either.left( - GeneralFailure(s"Refusing to update unsaved ${friendlyClassName(this)} model").single) + Either.left(GeneralFailure(s"Refusing to update unsaved ${friendlyClassName(this)} model").single) else Either.right(this) } diff --git a/phoenix-scala/core/app/core/db/FoxTableQuery.scala b/phoenix-scala/core/app/core/db/FoxTableQuery.scala index aba2a379e3..164468f848 100644 --- a/phoenix-scala/core/app/core/db/FoxTableQuery.scala +++ b/phoenix-scala/core/app/core/db/FoxTableQuery.scala @@ -42,8 +42,8 @@ abstract class FoxTableQuery[M <: FoxModel[M], T <: FoxTable[M]](construct: Tag def createAllReturningModels(unsaved: Iterable[M])(implicit ec: EC): DbResultT[Seq[M]] = for { - prepared ← * <~ beforeSaveBatch(unsaved) - returned ← * <~ wrapDbio(returningTable ++= prepared) + prepared ← * <~ beforeSaveBatch(unsaved) + returned ← * <~ wrapDbio(returningTable ++= prepared) } yield for ((m, r) ← prepared.zip(returned)) yield returningLens.set(m)(r) def create(unsaved: M)(implicit ec: EC): DbResultT[M] = @@ -93,8 +93,7 @@ abstract class FoxTableQuery[M <: FoxModel[M], T <: FoxTable[M]](construct: Tag implicit class EnrichedTableQuery(q: QuerySeq) { def deleteAll(implicit ec: EC): DbResultT[Int] = wrapDbio(q.delete) - def deleteAll[A](onSuccess: ⇒ DbResultT[A], onFailure: ⇒ DbResultT[A])( - implicit ec: EC): DbResultT[A] = { + def deleteAll[A](onSuccess: ⇒ DbResultT[A], onFailure: ⇒ DbResultT[A])(implicit ec: EC): DbResultT[A] = { val deleteResult = q.delete.dbresult.flatMap { case 0 ⇒ onFailure case _ ⇒ onSuccess diff --git a/phoenix-scala/core/app/core/db/SearchTerms.scala b/phoenix-scala/core/app/core/db/SearchTerms.scala index 67afe9a882..368ef53de8 100644 --- a/phoenix-scala/core/app/core/db/SearchTerms.scala +++ b/phoenix-scala/core/app/core/db/SearchTerms.scala @@ -21,15 +21,12 @@ trait SearchById[M <: FoxModel[M], T <: FoxTable[M]] { def mustFindById400(id: M#Id)(implicit ec: EC, db: DB): DbResultT[M] = mustFindById(id, notFound400K) - private def mustFindById(id: M#Id, notFoundFailure: M#Id ⇒ Failure = notFound404K)( - implicit ec: EC, - db: DB): DbResultT[M] = { - + private def mustFindById(id: M#Id, notFoundFailure: M#Id ⇒ Failure = notFound404K)(implicit ec: EC, + db: DB): DbResultT[M] = this.findOneById(id).dbresult.flatMap { case Some(model) ⇒ DbResultT.good(model) case None ⇒ DbResultT.failure(notFoundFailure(id)) } - } } trait SearchByRefNum[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T] { @@ -38,26 +35,23 @@ trait SearchByRefNum[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T def mustFindByRefNum(refNum: String, notFoundFailure: String ⇒ Failure = notFound404K)( implicit ec: EC, - db: DB): DbResultT[M] = { + db: DB): DbResultT[M] = findOneByRefNum(refNum).dbresult.flatMap { case Some(model) ⇒ DbResultT.good(model) case None ⇒ DbResultT.failure(notFoundFailure(refNum)) } - } } trait SearchByCode[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T] { def findOneByCode(code: String): DBIO[Option[M]] - def mustFindByCode(code: String, notFoundFailure: String ⇒ Failure = notFound404K)( - implicit ec: EC, - db: DB): DbResultT[M] = { + def mustFindByCode(code: String, notFoundFailure: String ⇒ Failure = notFound404K)(implicit ec: EC, + db: DB): DbResultT[M] = findOneByCode(code).dbresult.flatMap { case Some(model) ⇒ DbResultT.good(model) case None ⇒ DbResultT.failure(notFoundFailure(code)) } - } } trait SearchByIdAndName[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M, T] { @@ -66,10 +60,9 @@ trait SearchByIdAndName[M <: FoxModel[M], T <: FoxTable[M]] extends SearchById[M def mustFindByName(id: Int, name: String, notFoundFailure: String ⇒ Failure = notFound404K)( implicit ec: EC, - db: DB): DbResultT[M] = { + db: DB): DbResultT[M] = findOneByIdAndName(id, name).dbresult.flatMap { case Some(model) ⇒ DbResultT.good(model) case None ⇒ DbResultT.failure(notFoundFailure(name)) } - } } diff --git a/phoenix-scala/core/app/core/db/Star.scala b/phoenix-scala/core/app/core/db/Star.scala index 1a2df85551..2d0d42859f 100644 --- a/phoenix-scala/core/app/core/db/Star.scala +++ b/phoenix-scala/core/app/core/db/Star.scala @@ -22,8 +22,7 @@ object * { def <~[A](v: Either[Failures, A])(implicit ec: EC): DbResultT[A] = DbResultT.fromEither(v) - def <~[A](v: Future[Either[Failures, A]])(implicit M1: Monad[DBIO], - M2: Monad[Future]): DbResultT[A] = + def <~[A](v: Future[Either[Failures, A]])(implicit M1: Monad[DBIO], M2: Monad[Future]): DbResultT[A] = DbResultT.fromResult(Result.fromFEither(v)) def <~[A](v: Future[A])(implicit ec: EC): DbResultT[A] = diff --git a/phoenix-scala/core/app/core/db/UpdateReturning.scala b/phoenix-scala/core/app/core/db/UpdateReturning.scala index b3f3ba08da..c34b1ba640 100644 --- a/phoenix-scala/core/app/core/db/UpdateReturning.scala +++ b/phoenix-scala/core/app/core/db/UpdateReturning.scala @@ -23,20 +23,16 @@ import scala.util.matching.Regex object UpdateReturning { val columnRegex: Regex = "(\".*\")".r - implicit class UpdateReturningInvoker[E, U, C[_]](val updateQuery: Query[E, U, C]) - extends AnyVal { + implicit class UpdateReturningInvoker[E, U, C[_]](val updateQuery: Query[E, U, C]) extends AnyVal { - def updateReturningHead[A, F](returningQuery: Query[A, F, C], v: U)( - implicit ec: EC): DbResultT[F] = + def updateReturningHead[A, F](returningQuery: Query[A, F, C], v: U)(implicit ec: EC): DbResultT[F] = ExceptionWrapper.wrapDbio(updateReturning(returningQuery, v).head) - def updateReturningHeadOption[A, F]( - returningQuery: Query[A, F, C], - v: U, - notFoundFailure: Failure)(implicit ec: EC): DbResultT[F] = { + def updateReturningHeadOption[A, F](returningQuery: Query[A, F, C], v: U, notFoundFailure: Failure)( + implicit ec: EC): DbResultT[F] = { val returningResult = updateReturning(returningQuery, v) val withFailure = returningResult.headOption.dbresult.flatMap(res ⇒ - DbResultT.fromEither(Either.fromOption(res, notFoundFailure.single))) + DbResultT.fromEither(Either.fromOption(res, notFoundFailure.single))) ExceptionWrapper.wrapDbResultT(withFailure) } diff --git a/phoenix-scala/core/app/core/db/package.scala b/phoenix-scala/core/app/core/db/package.scala index 0129374b27..b3acfd16db 100644 --- a/phoenix-scala/core/app/core/db/package.scala +++ b/phoenix-scala/core/app/core/db/package.scala @@ -77,8 +77,7 @@ package object db { def flatMapEither[B](f: Either[Failures, A] ⇒ FoxyT[F, B])(implicit F: Monad[F]): FoxyT[F, B] = // TODO: remove me @michalrus fa.flatMap(a ⇒ f(Either.right(a))).handleErrorWith(failures ⇒ f(Either.left(failures))) - def mapEither[B](f: Either[Failures, A] ⇒ Either[Failures, B])( - implicit F: Monad[F]): FoxyT[F, B] = // TODO: remove me @michalrus + def mapEither[B](f: Either[Failures, A] ⇒ Either[Failures, B])(implicit F: Monad[F]): FoxyT[F, B] = // TODO: remove me @michalrus flatMapEither(xa ⇒ FoxyT[F].fromEither(f(xa))) def mapEitherRight[B](f: Either[Failures, A] ⇒ B)(implicit F: Monad[F]): FoxyT[F, B] = @@ -145,21 +144,22 @@ package object db { def fromId[A](fa: Foxy[A])(implicit F: Monad[F]): FoxyT[F, A] = fa.transformF(ga ⇒ EitherT(F.pure(ga.value))) - def failWithMatchedWarning(pf: PartialFunction[Failure, Boolean])( - implicit F: Monad[F]): FoxyT[F, Unit] = - StateT(s ⇒ - s.collect { - case MetaResponse.Warning(f) ⇒ f - }.find(pf.lift(_) == Some(true)) match { - case Some(f) ⇒ EitherT.left(F.pure(NonEmptyList(f, Nil))) - case _ ⇒ EitherT.right(F.pure((s, ()))) - }) + def failWithMatchedWarning(pf: PartialFunction[Failure, Boolean])(implicit F: Monad[F]): FoxyT[F, Unit] = + StateT( + s ⇒ + s.collect { + case MetaResponse.Warning(f) ⇒ f + } + .find(pf.lift(_) == Some(true)) match { + case Some(f) ⇒ EitherT.left(F.pure(NonEmptyList(f, Nil))) + case _ ⇒ EitherT.right(F.pure((s, ()))) + }) /** Just like ``sequence`` but—in case of a failure—unlawful, as it will join failures from all Foxies. */ def seqCollectFailures[L[_], A](lfa: L[FoxyT[F, A]])(implicit L: TraverseFilter[L], F: Monad[F]): FoxyT[F, L[A]] = L.map(lfa)(_.fold(Either.left(_), Either.right(_))).sequence.flatMap { xa ⇒ - val failures = L.collect(xa) { case Left(f) ⇒ f.toList }.toList.flatten + val failures = L.collect(xa) { case Left(f) ⇒ f.toList }.toList.flatten val values = L.collect(xa) { case Right(a) ⇒ a } NonEmptyList.fromList(failures).fold(FoxyT[F].pure(values))(FoxyT[F].failures(_)) } @@ -195,12 +195,9 @@ package object db { type FoxyTDBIO[A] = FoxyT[DBIO, A] /* replaces the old DbResultT */ object FoxyTDBIO extends FoxyTFunctions[DBIO] { - def fromResult[A](ga: FoxyT[Future, A])( - implicit F: Monad[Future], - G: Monad[DBIO]): FoxyT[DBIO, A] = // TODO: better name? @michalrus + def fromResult[A](ga: FoxyT[Future, A])(implicit F: Monad[Future], G: Monad[DBIO]): FoxyT[DBIO, A] = // TODO: better name? @michalrus // Don’t remove type annotation below, or the compiler will crash. 🙄 - ga.transformF(gga ⇒ - EitherT(DBIO.from(gga.value): DBIO[Either[Failures, (List[MetaResponse], A)]])) // TODO: use FunctionK for functor changes? Future[_] → DBIO[_] here + ga.transformF(gga ⇒ EitherT(DBIO.from(gga.value): DBIO[Either[Failures, (List[MetaResponse], A)]])) // TODO: use FunctionK for functor changes? Future[_] → DBIO[_] here } type DbResultT[A] = FoxyTDBIO[A] @@ -234,19 +231,18 @@ package object db { implicit class EnrichedDbResultT[A](dbResultT: DbResultT[A]) { def runTxn()(implicit ec: EC, db: DB): Result[A] = // FIXME: this should be doable without all this ceremony, supplying .transactionally.run to some standard function @michalrus dbResultT.transformF( - fsa ⇒ - EitherT( - fsa - // turn `left` into `DBIO.failed` to force transaction rollback - .fold(failures ⇒ DBIO.failed(FoxFailureException(failures)), - good ⇒ DBIO.successful(good)) - .flatMap(a ⇒ a) // flatten... - .transactionally - .run() // throws a FoxFailureException :/ - .map(Either.right) - .recover { // don't actually want an exception thrown, so wrap it back - case e: FoxFailureException ⇒ Either.left(e.failures) - })) + fsa ⇒ + EitherT( + fsa + // turn `left` into `DBIO.failed` to force transaction rollback + .fold(failures ⇒ DBIO.failed(FoxFailureException(failures)), good ⇒ DBIO.successful(good)) + .flatMap(a ⇒ a) // flatten... + .transactionally + .run() // throws a FoxFailureException :/ + .map(Either.right) + .recover { // don't actually want an exception thrown, so wrap it back + case e: FoxFailureException ⇒ Either.left(e.failures) + })) def runDBIO()(implicit ec: EC, db: DB): Result[A] = dbResultT.transformF(fa ⇒ EitherT(fa.value.run)) @@ -277,9 +273,8 @@ package object db { def id: Rep[M#Id] } - def appendForUpdate[A, B <: slick.dbio.NoStream](sql: SqlAction[A, B, Effect.Read]): DBIO[A] = { + def appendForUpdate[A, B <: slick.dbio.NoStream](sql: SqlAction[A, B, Effect.Read]): DBIO[A] = sql.overrideStatements(sql.statements.map(_ + " for update")) - } def lift[A](value: A): DBIO[A] = DBIO.successful(value) @@ -291,8 +286,7 @@ package object db { def doOrMeh(condition: Boolean, action: ⇒ DbResultT[_])(implicit ec: EC): DbResultT[Unit] = if (condition) action.meh else DbResultT.unit - def doOrGood[A](condition: Boolean, action: ⇒ DbResultT[A], good: ⇒ A)( - implicit ec: EC): DbResultT[A] = + def doOrGood[A](condition: Boolean, action: ⇒ DbResultT[A], good: ⇒ A)(implicit ec: EC): DbResultT[A] = if (condition) action else DbResultT.good(good) def doOrFail[A](condition: Boolean, action: ⇒ DbResultT[A], failure: ⇒ Failure)( @@ -342,20 +336,18 @@ package object db { implicit class EnrichedDBIOpt[R](val dbio: DBIO[Option[R]]) extends AnyVal { - def findOrCreate(r: DbResultT[R])(implicit ec: EC): DbResultT[R] = { + def findOrCreate(r: DbResultT[R])(implicit ec: EC): DbResultT[R] = dbio.dbresult.flatMap { case Some(model) ⇒ DbResultT.good(model) case None ⇒ r } - } // Last item in tuple determines if cart was created or not - def findOrCreateExtended(r: DbResultT[R])(implicit ec: EC): DbResultT[(R, FoundOrCreated)] = { + def findOrCreateExtended(r: DbResultT[R])(implicit ec: EC): DbResultT[(R, FoundOrCreated)] = dbio.dbresult.flatMap { case Some(model) ⇒ DbResultT.good((model, Found)) case _ ⇒ r.map(result ⇒ (result, Created)) } - } def mustFindOr(notFoundFailure: Failure)(implicit ec: EC): DbResultT[R] = dbio.dbresult.flatMap { diff --git a/phoenix-scala/core/app/core/failures.scala b/phoenix-scala/core/app/core/failures.scala index 1cb517fc3e..e66fa58634 100644 --- a/phoenix-scala/core/app/core/failures.scala +++ b/phoenix-scala/core/app/core/failures.scala @@ -37,18 +37,16 @@ object failures { } object NotFoundFailure404 { - def apply[A](a: A, searchKey: Any): NotFoundFailure404 = { + def apply[A](a: A, searchKey: Any): NotFoundFailure404 = NotFoundFailure404(s"${friendlyClassName(a)} with key=$searchKey not found") - } // TODO: get rid of this usage @michalrus def apply[A](a: A, searchTerm: String, searchKey: Any): NotFoundFailure404 = NotFoundFailure404(s"${friendlyClassName(a)} with key=$searchKey not found") // TODO: get rid of this usage @michalrus - def apply(className: String, searchTerm: String, searchKey: Any): NotFoundFailure404 = { + def apply(className: String, searchTerm: String, searchKey: Any): NotFoundFailure404 = NotFoundFailure404(s"$className with $searchTerm=$searchKey not found") - } } case class NotFoundFailure400(message: String) extends Failure { @@ -56,9 +54,8 @@ object failures { } object NotFoundFailure400 { - def apply[A](a: A, searchKey: Any): NotFoundFailure400 = { + def apply[A](a: A, searchKey: Any): NotFoundFailure400 = NotFoundFailure400(s"${friendlyClassName(a)} with key=$searchKey not found") - } } } diff --git a/phoenix-scala/core/app/core/utils/Money.scala b/phoenix-scala/core/app/core/utils/Money.scala index 62c37a7f10..4cef8d0797 100644 --- a/phoenix-scala/core/app/core/utils/Money.scala +++ b/phoenix-scala/core/app/core/utils/Money.scala @@ -44,7 +44,7 @@ object Money { * Json4s works by matching types against Any at runtime so we need to support these features. */ val jsonFormat = new CustomSerializer[Currency](format ⇒ - ({ + ({ case JString(str) ⇒ Currency(str.toUpperCase) }, { case c: Currency ⇒ JString(c.getCode) diff --git a/phoenix-scala/core/app/core/utils/Strings.scala b/phoenix-scala/core/app/core/utils/Strings.scala index e32ad79e87..bedad532c2 100644 --- a/phoenix-scala/core/app/core/utils/Strings.scala +++ b/phoenix-scala/core/app/core/utils/Strings.scala @@ -10,9 +10,10 @@ object Strings { def tableNameToCamel: String = s.underscoreToCamel.singularize def underscore: String = s.flatMap { - case c if c.isUpper ⇒ s"_${c.toLower}" - case c ⇒ s"$c" - }.stripPrefix("_") + case c if c.isUpper ⇒ s"_${c.toLower}" + case c ⇒ s"$c" + } + .stripPrefix("_") def prettify: String = s.split("(?=\\p{Upper})").mkString(" ") def quote(escapeChar: Char = '\\'): String = { val escaped = diff --git a/phoenix-scala/core/app/core/utils/Validation.scala b/phoenix-scala/core/app/core/utils/Validation.scala index d85295c695..78f4a7e298 100644 --- a/phoenix-scala/core/app/core/utils/Validation.scala +++ b/phoenix-scala/core/app/core/utils/Validation.scala @@ -2,7 +2,7 @@ package core.utils import java.time.LocalDateTime -import cats.data.Validated.{Invalid, Valid, invalidNel, valid} +import cats.data.Validated.{invalidNel, valid, Invalid, Valid} import cats.data.{NonEmptyList, Validated, ValidatedNel} import com.wix.accord import com.wix.accord.RuleViolation @@ -43,12 +43,10 @@ object Validation { if (expression) notEmpty(a, constraint) else valid({}) - def nullOrNotEmpty[A <: AnyRef <% HasEmpty](a: Option[A], - constraint: String): ValidatedNel[Failure, Unit] = { + def nullOrNotEmpty[A <: AnyRef <% HasEmpty](a: Option[A], constraint: String): ValidatedNel[Failure, Unit] = a.fold(ok) { s ⇒ notEmpty(s, constraint) } - } def emailish(maybeEmail: String, fieldName: String): ValidatedNel[Failure, Unit] = validExpr(maybeEmail.contains('@'), s"$fieldName must be an email") @@ -108,19 +106,13 @@ object Validation { } def matches(value: String, regex: Regex, constraint: String): ValidatedNel[Failure, Unit] = - toValidatedNel(constraint, - new MatchesRegex(regex.pattern, partialMatchAllowed = false).apply(value)) + toValidatedNel(constraint, new MatchesRegex(regex.pattern, partialMatchAllowed = false).apply(value)) def matches(value: String, regex: String, constraint: String): ValidatedNel[Failure, Unit] = - toValidatedNel(constraint, - new MatchesRegex(regex.r.pattern, partialMatchAllowed = false).apply(value)) + toValidatedNel(constraint, new MatchesRegex(regex.r.pattern, partialMatchAllowed = false).apply(value)) - def between(value: Int, - lowerBound: Int, - upperBound: Int, - constraint: String): ValidatedNel[Failure, Unit] = - toValidatedNel(constraint, - new InRangeInclusive[Int](lowerBound, upperBound, prefix).apply(value)) + def between(value: Int, lowerBound: Int, upperBound: Int, constraint: String): ValidatedNel[Failure, Unit] = + toValidatedNel(constraint, new InRangeInclusive[Int](lowerBound, upperBound, prefix).apply(value)) def isMonth(month: Int, constraint: String): ValidatedNel[Failure, Unit] = toValidatedNel(s"$constraint month", new InRangeInclusive[Int](1, 12, prefix).apply(month)) @@ -128,19 +120,13 @@ object Validation { def lesserThan[T: Numeric](value: T, limit: T, constraint: String): ValidatedNel[Failure, Unit] = toValidatedNel(constraint, new LesserThan[T](limit, prefix).apply(value)) - def lesserThanOrEqual[T: Numeric](value: T, - limit: T, - constraint: String): ValidatedNel[Failure, Unit] = + def lesserThanOrEqual[T: Numeric](value: T, limit: T, constraint: String): ValidatedNel[Failure, Unit] = toValidatedNel(constraint, new LesserThanOrEqual[T](limit, prefix).apply(value)) - def greaterThan[T: Numeric](value: T, - limit: T, - constraint: String): ValidatedNel[Failure, Unit] = + def greaterThan[T: Numeric](value: T, limit: T, constraint: String): ValidatedNel[Failure, Unit] = toValidatedNel(constraint, new GreaterThan[T](limit, prefix).apply(value)) - def greaterThanOrEqual[T: Numeric](value: T, - limit: T, - constraint: String): ValidatedNel[Failure, Unit] = + def greaterThanOrEqual[T: Numeric](value: T, limit: T, constraint: String): ValidatedNel[Failure, Unit] = toValidatedNel(constraint, new GreaterThanOrEqual[T](limit, prefix).apply(value)) private def toValidatedNel(constraint: String, r: accord.Result): ValidatedNel[Failure, Unit] = @@ -152,8 +138,7 @@ object Validation { } Validated.Invalid( - NonEmptyList(errors.headOption.getOrElse(GeneralFailure("unknown error")), - errors.tail)) + NonEmptyList(errors.headOption.getOrElse(GeneralFailure("unknown error")), errors.tail)) case accord.Success ⇒ valid({}) diff --git a/phoenix-scala/core/app/core/utils/time/JavaTimeSlickMapper.scala b/phoenix-scala/core/app/core/utils/time/JavaTimeSlickMapper.scala index 9e3c874fb8..0502e4f107 100644 --- a/phoenix-scala/core/app/core/utils/time/JavaTimeSlickMapper.scala +++ b/phoenix-scala/core/app/core/utils/time/JavaTimeSlickMapper.scala @@ -24,6 +24,6 @@ object JavaTimeSlickMapper { */ implicit def instantAndTimestampWithoutZone: BaseColumnType[time.Instant] = PostgresProfile.MappedColumnType.base[time.Instant, Timestamp]( - instant ⇒ Timestamp.valueOf(instant.atZone(UTC).toLocalDateTime), - timestamp ⇒ timestamp.toLocalDateTime.toInstant(ZoneOffset.UTC)) + instant ⇒ Timestamp.valueOf(instant.atZone(UTC).toLocalDateTime), + timestamp ⇒ timestamp.toLocalDateTime.toInstant(ZoneOffset.UTC)) } diff --git a/phoenix-scala/objectframework/app/objectframework/DbObjectUtils.scala b/phoenix-scala/objectframework/app/objectframework/DbObjectUtils.scala index 72059be28f..e3099015c4 100644 --- a/phoenix-scala/objectframework/app/objectframework/DbObjectUtils.scala +++ b/phoenix-scala/objectframework/app/objectframework/DbObjectUtils.scala @@ -1,6 +1,6 @@ package objectframework -import objectframework.models.{ObjectShadows, ObjectForms} +import objectframework.models.{ObjectForms, ObjectShadows} import slick.lifted.Rep import org.json4s.JValue import core.db.ExPostgresDriver.api._ @@ -12,13 +12,11 @@ object DbObjectUtils { def shadow: ObjectShadows // get illuminated value using database jsonb functions - def |→(key: String): Rep[JValue] = { + def |→(key: String): Rep[JValue] = form.attributes +> (shadow.attributes +> key +>> "ref") - } } - implicit class DbObjectIlluminated(val pair: (ObjectForms, ObjectShadows)) - extends DbFormAndShadow { + implicit class DbObjectIlluminated(val pair: (ObjectForms, ObjectShadows)) extends DbFormAndShadow { override def form: ObjectForms = pair._1 override def shadow: ObjectShadows = pair._2 } diff --git a/phoenix-scala/objectframework/app/objectframework/FormShadowGet.scala b/phoenix-scala/objectframework/app/objectframework/FormShadowGet.scala index 9ffc4e6dc9..194a05484c 100644 --- a/phoenix-scala/objectframework/app/objectframework/FormShadowGet.scala +++ b/phoenix-scala/objectframework/app/objectframework/FormShadowGet.scala @@ -15,34 +15,30 @@ object FormShadowGet { if (price.isEmpty) None else price.headOption } - def price(f: ObjectForm, s: ObjectShadow): Option[Price] = { + def price(f: ObjectForm, s: ObjectShadow): Option[Price] = ObjectUtils.get("salePrice", f, s) match { case JNothing ⇒ None case v ⇒ priceFromJson(v) } - } def priceAsLong(f: ObjectForm, s: ObjectShadow): Long = price(f, s).map { case (value, _) ⇒ value }.getOrElse(0) - def title(f: ObjectForm, s: ObjectShadow): Option[String] = { + def title(f: ObjectForm, s: ObjectShadow): Option[String] = ObjectUtils.get("title", f, s) match { case JString(title) ⇒ title.some case _ ⇒ None } - } - def externalId(f: ObjectForm, s: ObjectShadow): Option[String] = { + def externalId(f: ObjectForm, s: ObjectShadow): Option[String] = ObjectUtils.get("externalId", f, s) match { case JString(externalId) ⇒ externalId.some case _ ⇒ None } - } - def trackInventory(f: ObjectForm, s: ObjectShadow): Boolean = { + def trackInventory(f: ObjectForm, s: ObjectShadow): Boolean = ObjectUtils.get("trackInventory", f, s) match { case JBool(trackInventory) ⇒ trackInventory case _ ⇒ true } - } } diff --git a/phoenix-scala/objectframework/app/objectframework/IlluminateAlgorithm.scala b/phoenix-scala/objectframework/app/objectframework/IlluminateAlgorithm.scala index 46b3feb24c..9e94f6d10b 100644 --- a/phoenix-scala/objectframework/app/objectframework/IlluminateAlgorithm.scala +++ b/phoenix-scala/objectframework/app/objectframework/IlluminateAlgorithm.scala @@ -24,12 +24,11 @@ object IlluminateAlgorithm extends LazyLogging { case _ ⇒ JNothing } - private def getInternalAttributes(schema: ObjectFullSchema): Option[JObject] = { + private def getInternalAttributes(schema: ObjectFullSchema): Option[JObject] = schema.schema \ "properties" \ "attributes" match { case JObject(s) ⇒ Some(s) case _ ⇒ None } - } def validateObjectBySchema(schema: ObjectFullSchema, form: ObjectForm, shadow: ObjectShadow)( implicit ec: ExecutionContext): DbResultT[JValue] = { @@ -82,8 +81,7 @@ object IlluminateAlgorithm extends LazyLogging { JNothing } - def validateAttributes(formJson: JValue, shadowJson: JValue)( - implicit fmt: Formats): Seq[Failure] = + def validateAttributes(formJson: JValue, shadowJson: JValue)(implicit fmt: Formats): Seq[Failure] = (formJson, shadowJson) match { case (JObject(form), JObject(shadow)) ⇒ shadow.obj.flatMap { @@ -103,8 +101,7 @@ object IlluminateAlgorithm extends LazyLogging { Seq(FormAttributesAreEmpty, ShadowAttributesAreEmpty) } - def validateAttributesTypes(formJson: JValue, shadowJson: JValue)( - implicit fmt: Formats): Seq[Failure] = { + def validateAttributesTypes(formJson: JValue, shadowJson: JValue)(implicit fmt: Formats): Seq[Failure] = (formJson, shadowJson) match { case (JObject(form), JObject(shadow)) ⇒ shadow.obj.flatMap { @@ -118,7 +115,6 @@ object IlluminateAlgorithm extends LazyLogging { } case _ ⇒ Seq.empty[Failure] } - } private def validateAttributeType(attr: String, key: String, typed: JValue, form: JValue)( implicit fmt: Formats): Seq[Failure] = { diff --git a/phoenix-scala/objectframework/app/objectframework/ObjectFailures.scala b/phoenix-scala/objectframework/app/objectframework/ObjectFailures.scala index 8af9879f43..1ea04974a3 100644 --- a/phoenix-scala/objectframework/app/objectframework/ObjectFailures.scala +++ b/phoenix-scala/objectframework/app/objectframework/ObjectFailures.scala @@ -38,8 +38,7 @@ object ObjectFailures { override def description = "Shadow attributes are empty" } - case class LinkAtPositionCannotBeFound(clazz: Class[_], left: Int, position: Int) - extends Failure { + case class LinkAtPositionCannotBeFound(clazz: Class[_], left: Int, position: Int) extends Failure { override def description = s"No object link ${clazz.getSimpleName} with left id $left exists at position $position" } @@ -62,13 +61,11 @@ object ObjectFailures { case object ObjectHeadCannotBeFoundByFormId { def apply(tableName: String, formId: ObjectForm#Id, contextName: String): NotFoundFailure404 = - NotFoundFailure404( - s"Object '$tableName' with id $formId cannot be found in context '$contextName'") + NotFoundFailure404(s"Object '$tableName' with id $formId cannot be found in context '$contextName'") } case object ObjectHeadCannotBeFoundForContext { def apply(tableName: String, contextId: Int, formId: Int): NotFoundFailure404 = - NotFoundFailure404( - s"Object '$tableName' with id $formId cannot be found for context $contextId") + NotFoundFailure404(s"Object '$tableName' with id $formId cannot be found for context $contextId") } } diff --git a/phoenix-scala/objectframework/app/objectframework/ObjectUtils.scala b/phoenix-scala/objectframework/app/objectframework/ObjectUtils.scala index 6697337382..82d1675843 100644 --- a/phoenix-scala/objectframework/app/objectframework/ObjectUtils.scala +++ b/phoenix-scala/objectframework/app/objectframework/ObjectUtils.scala @@ -64,7 +64,7 @@ object ObjectUtils { } type KeyMap = Map[String, String] - def createForm(humanReadableForm: JValue, existingForm: JValue = JNothing): (KeyMap, JValue) = { + def createForm(humanReadableForm: JValue, existingForm: JValue = JNothing): (KeyMap, JValue) = humanReadableForm match { case JObject(o) ⇒ val zeroAccumObj = existingForm.merge(humanReadableForm) @@ -80,7 +80,6 @@ object ObjectUtils { case _ ⇒ (Map(), JNothing) } - } private[objectframework] def updateForm(oldForm: JValue, humanReadableUpdatedForm: JValue): (KeyMap, JValue) = { @@ -109,9 +108,7 @@ object ObjectUtils { } case class FormShadowAttributes(form: JValue, shadow: JValue) - private def updateFormAndShadow(oldForm: JValue, - newForm: JValue, - oldShadow: JValue): FormShadowAttributes = { + private def updateFormAndShadow(oldForm: JValue, newForm: JValue, oldShadow: JValue): FormShadowAttributes = { val (keyMap, updatedForm) = updateForm(oldForm, newForm) val updatedShadow = newShadow(oldShadow, keyMap) FormShadowAttributes(updatedForm, updatedShadow) @@ -129,12 +126,12 @@ object ObjectUtils { copy(form = form, shadow = shadow) } - def insert(formProto: ObjectForm, - shadowProto: ObjectShadow)(implicit ec: EC, fmt: Formats): DbResultT[InsertResult] = + def insert(formProto: ObjectForm, shadowProto: ObjectShadow)(implicit ec: EC, + fmt: Formats): DbResultT[InsertResult] = insert(formProto, shadowProto, None) - def insert(formAndShadow: FormAndShadow, - schema: Option[String])(implicit ec: EC, fmt: Formats): DbResultT[InsertResult] = + def insert(formAndShadow: FormAndShadow, schema: Option[String])(implicit ec: EC, + fmt: Formats): DbResultT[InsertResult] = insert(formProto = formAndShadow.form, shadowProto = formAndShadow.shadow, schema = schema) def insert(formProto: ObjectForm, shadowProto: ObjectShadow, schema: Option[String])( @@ -150,9 +147,7 @@ object ObjectUtils { optSchema ← * <~ ObjectSchemasManager.getSchemaByOptNameOrKind(schema, formProto.kind) form ← * <~ ObjectForms.create(formProto.copy(attributes = n.form)) shadow ← * <~ ObjectShadows.create( - shadowProto.copy(formId = form.id, - attributes = n.shadow, - jsonSchema = optSchema.map(_.name))) + shadowProto.copy(formId = form.id, attributes = n.shadow, jsonSchema = optSchema.map(_.name))) //Make sure form is correct and shadow links are correct _ ← * <~ optSchema.map { schema ⇒ IlluminateAlgorithm.validateObjectBySchema(schema, form, shadow) @@ -161,8 +156,7 @@ object ObjectUtils { } yield InsertResult(form, shadow, commit) } - def insertFullObject[H <: ObjectHead[H]](proto: FormAndShadow, - updateHead: (InsertResult) ⇒ DbResultT[H])( + def insertFullObject[H <: ObjectHead[H]](proto: FormAndShadow, updateHead: (InsertResult) ⇒ DbResultT[H])( implicit ec: EC, fmt: Formats): DbResultT[FullObject[H]] = for { @@ -170,8 +164,7 @@ object ObjectUtils { head ← * <~ updateHead(insert) } yield FullObject[H](head, insert.form, insert.shadow) - case class UpdateResult(form: ObjectForm, shadow: ObjectShadow, updated: Boolean) - extends FormAndShadow { + case class UpdateResult(form: ObjectForm, shadow: ObjectShadow, updated: Boolean) extends FormAndShadow { override def update(form: ObjectForm, shadow: ObjectShadow): FormAndShadow = copy(form = form, shadow = shadow) } @@ -186,72 +179,62 @@ object ObjectUtils { updateResult ← * <~ updateFormAndShadow(fullObject, formAttributes, shadowAttributes, force) maybeCommit ← * <~ ObjectUtils.commit(updateResult) committedObject ← * <~ (maybeCommit match { - case Some(commit) ⇒ - val newObject = fullObject - .copy[T](form = updateResult.form, shadow = updateResult.shadow) - updateHead(newObject, commit.id) - case _ ⇒ - DbResultT.good(fullObject) - }) + case Some(commit) ⇒ + val newObject = fullObject + .copy[T](form = updateResult.form, shadow = updateResult.shadow) + updateHead(newObject, commit.id) + case _ ⇒ + DbResultT.good(fullObject) + }) } yield committedObject private def updateFormAndShadow( oldFormAndShadow: FormAndShadow, formAttributes: JValue, shadowAttributes: JValue, - force: Boolean = false)(implicit ec: EC, db: DB, fmt: Formats): DbResultT[UpdateResult] = { + force: Boolean = false)(implicit ec: EC, db: DB, fmt: Formats): DbResultT[UpdateResult] = for { newAttributes ← * <~ ObjectUtils.updateFormAndShadow(oldFormAndShadow.form.attributes, formAttributes, shadowAttributes) - result ← * <~ updateIfDifferent(oldFormAndShadow, - newAttributes.form, - newAttributes.shadow, - force) + result ← * <~ updateIfDifferent(oldFormAndShadow, newAttributes.form, newAttributes.shadow, force) } yield result - } - def update( - formId: Int, - shadowId: Int, - formAttributes: JValue, - shadowAttributes: JValue, - force: Boolean = false)(implicit db: DB, ec: EC, fmt: Formats): DbResultT[UpdateResult] = + def update(formId: Int, + shadowId: Int, + formAttributes: JValue, + shadowAttributes: JValue, + force: Boolean = false)(implicit db: DB, ec: EC, fmt: Formats): DbResultT[UpdateResult] = for { oldForm ← * <~ ObjectForms.mustFindById404(formId) oldShadow ← * <~ ObjectShadows.mustFindById404(shadowId) - result ← * <~ updateFormAndShadow((oldForm, oldShadow), - formAttributes, - shadowAttributes, - force) + result ← * <~ updateFormAndShadow((oldForm, oldShadow), formAttributes, shadowAttributes, force) } yield result def commit(u: UpdateResult)(implicit ec: EC): DbResultT[Option[ObjectCommit]] = commit(u.form, u.shadow, u.updated) def commit(form: ObjectForm, shadow: ObjectShadow, doIt: Boolean)( - implicit ec: EC): DbResultT[Option[ObjectCommit]] = { + implicit ec: EC): DbResultT[Option[ObjectCommit]] = if (doIt) for { commit ← * <~ ObjectCommits.create(ObjectCommit(formId = form.id, shadowId = shadow.id)) } yield commit.some else DbResultT.pure(None) - } private def updateIfDifferent( old: FormAndShadow, newFormAttributes: JValue, newShadowAttributes: JValue, - force: Boolean = false)(implicit ec: EC, db: DB, fmt: Formats): DbResultT[UpdateResult] = { + force: Boolean = false)(implicit ec: EC, db: DB, fmt: Formats): DbResultT[UpdateResult] = if (old.shadow.attributes != newShadowAttributes || force) for { - form ← * <~ ObjectForms.update( - old.form, - old.form.copy(attributes = newFormAttributes, updatedAt = Instant.now)) + form ← * <~ ObjectForms.update(old.form, + old.form.copy(attributes = newFormAttributes, updatedAt = Instant.now)) shadow ← * <~ ObjectShadows.create( - ObjectShadow(formId = form.id, - attributes = newShadowAttributes, - jsonSchema = old.shadow.jsonSchema)) + ObjectShadow(formId = form.id, + attributes = newShadowAttributes, + jsonSchema = old.shadow.jsonSchema)) optSchema ← * <~ old.shadow.jsonSchema.map { schemaName ⇒ ObjectFullSchemas.mustFindByName404(schemaName) @@ -262,11 +245,9 @@ object ObjectUtils { _ ← * <~ validateShadow(form, shadow) } yield UpdateResult(form, shadow, updated = true) else DbResultT.pure(UpdateResult(old.form, old.shadow, updated = false)) - } - private def validateShadow(form: ObjectForm, shadow: ObjectShadow)( - implicit ec: EC, - fmt: Formats): DbResultT[Unit] = + private def validateShadow(form: ObjectForm, shadow: ObjectShadow)(implicit ec: EC, + fmt: Formats): DbResultT[Unit] = failIfErrors(IlluminateAlgorithm.validateAttributes(form.attributes, shadow.attributes)) def failIfErrors(errors: Seq[Failure])(implicit ec: EC): DbResultT[Unit] = errors match { diff --git a/phoenix-scala/objectframework/app/objectframework/models/FullObject.scala b/phoenix-scala/objectframework/app/objectframework/models/FullObject.scala index daa5f0968e..ce803fa900 100644 --- a/phoenix-scala/objectframework/app/objectframework/models/FullObject.scala +++ b/phoenix-scala/objectframework/app/objectframework/models/FullObject.scala @@ -59,10 +59,9 @@ object FormAndShadow { copy(form = form, shadow = shadow) } - def fromPayload(kind: String, attributes: Map[String, JValue]): FormAndShadow = { + def fromPayload(kind: String, attributes: Map[String, JValue]): FormAndShadow = FormAndShadowSimple(form = ObjectForm.fromPayload(kind, attributes), shadow = ObjectShadow.fromPayload(attributes)) - } } case class FullObject[A](model: A, form: ObjectForm, shadow: ObjectShadow) extends FormAndShadow { diff --git a/phoenix-scala/objectframework/app/objectframework/models/IlluminatedObject.scala b/phoenix-scala/objectframework/app/objectframework/models/IlluminatedObject.scala index 81d638c091..257f0d9986 100644 --- a/phoenix-scala/objectframework/app/objectframework/models/IlluminatedObject.scala +++ b/phoenix-scala/objectframework/app/objectframework/models/IlluminatedObject.scala @@ -8,7 +8,7 @@ case class IlluminatedContext(name: String, attributes: JValue) /** * An IlluminatedObject is what you get when you combine the product shadow and - * the product. + * the product. */ case class IlluminatedObject(id: Int = 0, attributes: JValue) extends Identity[IlluminatedObject] diff --git a/phoenix-scala/objectframework/app/objectframework/models/ObjectContext.scala b/phoenix-scala/objectframework/app/objectframework/models/ObjectContext.scala index fba591fc92..48b61c3d34 100644 --- a/phoenix-scala/objectframework/app/objectframework/models/ObjectContext.scala +++ b/phoenix-scala/objectframework/app/objectframework/models/ObjectContext.scala @@ -15,10 +15,7 @@ import shapeless._ * The context will be matched against a user context so that the storefront displays * the appropriate object information. */ -case class ObjectContext(id: Int = 0, - name: String, - attributes: JValue, - createdAt: Instant = Instant.now) +case class ObjectContext(id: Int = 0, name: String, attributes: JValue, createdAt: Instant = Instant.now) extends FoxModel[ObjectContext] with Validation[ObjectContext] diff --git a/phoenix-scala/objectframework/app/objectframework/models/ObjectHead.scala b/phoenix-scala/objectframework/app/objectframework/models/ObjectHead.scala index b737c4a9ba..bee26a6fc7 100644 --- a/phoenix-scala/objectframework/app/objectframework/models/ObjectHead.scala +++ b/phoenix-scala/objectframework/app/objectframework/models/ObjectHead.scala @@ -25,8 +25,7 @@ trait ObjectHead[M <: ObjectHead[M]] extends FoxModel[M] { self: M ⇒ * Abstract class to help define an object head object which points to the latest * version of some object in the context specified. */ -abstract class ObjectHeads[M <: ObjectHead[M]](tag: Tag, table: String) - extends FoxTable[M](tag, table) { +abstract class ObjectHeads[M <: ObjectHead[M]](tag: Tag, table: String) extends FoxTable[M](tag, table) { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def scope = column[LTree]("scope") @@ -47,14 +46,13 @@ abstract class ObjectHeads[M <: ObjectHead[M]](tag: Tag, table: String) abstract class ObjectHeadsQueries[M <: ObjectHead[M], T <: ObjectHeads[M]](construct: Tag ⇒ T) extends FoxTableQuery[M, T](construct) { - def mustFindByFormId404(formId: ObjectForm#Id)(implicit oc: ObjectContext, - ec: EC): DbResultT[M] = + def mustFindByFormId404(formId: ObjectForm#Id)(implicit oc: ObjectContext, ec: EC): DbResultT[M] = findOneByFormId(formId).mustFindOneOr( - ObjectHeadCannotBeFoundByFormId(baseTableRow.tableName, formId, oc.name)) + ObjectHeadCannotBeFoundByFormId(baseTableRow.tableName, formId, oc.name)) def mustFindByContextAndFormId404(contextId: Int, formId: Int)(implicit ec: EC): DbResultT[M] = findOneByContextAndFormId(contextId, formId).mustFindOneOr( - ObjectHeadCannotBeFoundForContext(baseTableRow.tableName, formId, contextId)) + ObjectHeadCannotBeFoundForContext(baseTableRow.tableName, formId, contextId)) def findOneByFormId(formId: Int)(implicit oc: ObjectContext): QuerySeq = filter(_.contextId === oc.id).filter(_.formId === formId) @@ -65,9 +63,7 @@ abstract class ObjectHeadsQueries[M <: ObjectHead[M], T <: ObjectHeads[M]](const def findOneByContextAndShadowId(contextId: Int, shadowId: Int): QuerySeq = filter(_.contextId === contextId).filter(_.shadowId === shadowId) - def updateHead(fullObject: FullObject[M], commitId: Int)( - implicit ec: EC): DbResultT[FullObject[M]] = - update(fullObject.model, - fullObject.model.withNewShadowAndCommit(fullObject.shadow.id, commitId)).map(updated ⇒ - fullObject.copy(model = updated)) + def updateHead(fullObject: FullObject[M], commitId: Int)(implicit ec: EC): DbResultT[FullObject[M]] = + update(fullObject.model, fullObject.model.withNewShadowAndCommit(fullObject.shadow.id, commitId)) + .map(updated ⇒ fullObject.copy(model = updated)) } diff --git a/phoenix-scala/objectframework/app/objectframework/models/ObjectHeadLinks.scala b/phoenix-scala/objectframework/app/objectframework/models/ObjectHeadLinks.scala index 45df672513..1fdbc98c28 100644 --- a/phoenix-scala/objectframework/app/objectframework/models/ObjectHeadLinks.scala +++ b/phoenix-scala/objectframework/app/objectframework/models/ObjectHeadLinks.scala @@ -51,19 +51,18 @@ object ObjectHeadLinks { def queryRightByLeft(left: L)(implicit ec: EC, db: DB): DbResultT[Seq[FullObject[R]]] = queryRightByLeftIdWithLink(left.id).map(_.map(_._1)) - def queryRightByLeftWithLinks(left: L)(implicit ec: EC, - db: DB): DbResultT[Seq[(FullObject[R], M)]] = + def queryRightByLeftWithLinks(left: L)(implicit ec: EC, db: DB): DbResultT[Seq[(FullObject[R], M)]] = queryRightByLeftIdWithLink(left.id) - private def queryRightByLeftIdWithLink( - leftId: Int)(implicit ec: EC, db: DB): DbResultT[Seq[(FullObject[R], M)]] = + private def queryRightByLeftIdWithLink(leftId: Int)(implicit ec: EC, + db: DB): DbResultT[Seq[(FullObject[R], M)]] = for { links ← * <~ filterLeftId(leftId).result linkedObjects ← * <~ links.map(link ⇒ queryLinkedObject(link)) } yield linkedObjects.zip(links) - private def queryLeftByRightIdWithLink( - rightId: Int)(implicit ec: EC, db: DB): DbResultT[Seq[(FullObject[L], M)]] = + private def queryLeftByRightIdWithLink(rightId: Int)(implicit ec: EC, + db: DB): DbResultT[Seq[(FullObject[L], M)]] = for { links ← * <~ filterRightId(rightId).result linkedObjects ← * <~ links.map(queryLeftLinkedObject) diff --git a/phoenix-scala/objectframework/app/objectframework/models/ObjectSchema.scala b/phoenix-scala/objectframework/app/objectframework/models/ObjectSchema.scala index d642c94520..a9f44672e4 100644 --- a/phoenix-scala/objectframework/app/objectframework/models/ObjectSchema.scala +++ b/phoenix-scala/objectframework/app/objectframework/models/ObjectSchema.scala @@ -88,9 +88,8 @@ object ObjectFullSchemas filter(_.name === name).one // test method - def getDefaultOrEmptySchemaForForm(form: ObjectForm)(implicit ec: EC): DBIO[ObjectFullSchema] = { + def getDefaultOrEmptySchemaForForm(form: ObjectForm)(implicit ec: EC): DBIO[ObjectFullSchema] = findOneByName(form.kind).map { o ⇒ o.getOrElse(ObjectFullSchema.emptySchema) } - } } diff --git a/phoenix-scala/objectframework/app/objectframework/models/OrderedLinks.scala b/phoenix-scala/objectframework/app/objectframework/models/OrderedLinks.scala index aceef0c6de..30727a0a43 100644 --- a/phoenix-scala/objectframework/app/objectframework/models/OrderedLinks.scala +++ b/phoenix-scala/objectframework/app/objectframework/models/OrderedLinks.scala @@ -43,8 +43,7 @@ abstract class OrderedObjectHeadLinkQueries[M <: OrderedObjectHeadLink[M], .mustFindOneOr(LinkCannotBeFound(baseTableRow.getClass, left.id, right.id)) replacedLink ← * <~ allLefts .filter(_.position === newPosition) - .mustFindOneOr( - LinkAtPositionCannotBeFound(baseTableRow.getClass, left.id, newPosition)) + .mustFindOneOr(LinkAtPositionCannotBeFound(baseTableRow.getClass, left.id, newPosition)) newLinks ← * <~ (if (link.position == newPosition) DbResultT.good((link, replacedLink)) else swapLinkPositions(link, replacedLink)) (updatedLink, _) = newLinks diff --git a/phoenix-scala/objectframework/app/objectframework/payloads/ObjectPayloads.scala b/phoenix-scala/objectframework/app/objectframework/payloads/ObjectPayloads.scala index 260e38764b..521589adb2 100644 --- a/phoenix-scala/objectframework/app/objectframework/payloads/ObjectPayloads.scala +++ b/phoenix-scala/objectframework/app/objectframework/payloads/ObjectPayloads.scala @@ -17,9 +17,8 @@ object ObjectPayloads { attributeName → (("type" → attributeType) ~ ("ref" → attributeName)) } - case class StringField(name: String, value: String) - extends TypedFieldBuilder(name, "string", value) - case class IntField(name: String, value: Int) extends TypedFieldBuilder(name, "int", value) + case class StringField(name: String, value: String) extends TypedFieldBuilder(name, "string", value) + case class IntField(name: String, value: Int) extends TypedFieldBuilder(name, "int", value) case class AttributesBuilder(attributes: FormShadowFieldBuilder*) { diff --git a/phoenix-scala/objectframework/app/objectframework/payloads/ObjectSchemaValidation.scala b/phoenix-scala/objectframework/app/objectframework/payloads/ObjectSchemaValidation.scala index ba2c13d407..3f3289b335 100644 --- a/phoenix-scala/objectframework/app/objectframework/payloads/ObjectSchemaValidation.scala +++ b/phoenix-scala/objectframework/app/objectframework/payloads/ObjectSchemaValidation.scala @@ -13,13 +13,11 @@ import scala.collection.JavaConverters._ object ObjectSchemaValidation { - trait SchemaValidation[M] { - this: M ⇒ + trait SchemaValidation[M] { this: M ⇒ def defaultSchemaName: String val schema: Option[String] = None - private def validatePayload(payload: M, jsonSchema: JValue)(implicit ec: EC, - fmt: Formats): DbResultT[M] = { + private def validatePayload(payload: M, jsonSchema: JValue)(implicit ec: EC, fmt: Formats): DbResultT[M] = { val jsonSchemaFactory = new JsonSchemaFactory val validator = jsonSchemaFactory.getSchema(asJsonNode(jsonSchema)) diff --git a/phoenix-scala/objectframework/app/objectframework/services/ObjectManager.scala b/phoenix-scala/objectframework/app/objectframework/services/ObjectManager.scala index 3655c1bc43..c219940c50 100644 --- a/phoenix-scala/objectframework/app/objectframework/services/ObjectManager.scala +++ b/phoenix-scala/objectframework/app/objectframework/services/ObjectManager.scala @@ -20,8 +20,7 @@ object ObjectManager { shadow ← * <~ ObjectShadows.mustFindById404(shadowId) } yield ObjectShadowResponse.build(shadow) - def getContextByName(name: String)(implicit ec: EC, - db: DB): DbResultT[ObjectContextResponse.Root] = + def getContextByName(name: String)(implicit ec: EC, db: DB): DbResultT[ObjectContextResponse.Root] = for { context ← * <~ mustFindByName404(name) } yield ObjectContextResponse.build(context) @@ -30,7 +29,7 @@ object ObjectManager { db: DB): DbResultT[ObjectContextResponse.Root] = for { context ← * <~ ObjectContexts.create( - ObjectContext(name = payload.name, attributes = payload.attributes)) + ObjectContext(name = payload.name, attributes = payload.attributes)) } yield ObjectContextResponse.build(context) def updateContextByName(name: String, payload: UpdateObjectContext)( @@ -38,9 +37,8 @@ object ObjectManager { db: DB): DbResultT[ObjectContextResponse.Root] = for { context ← * <~ mustFindByName404(name) - update ← * <~ ObjectContexts.update( - context, - context.copy(name = payload.name, attributes = payload.attributes)) + update ← * <~ ObjectContexts.update(context, + context.copy(name = payload.name, attributes = payload.attributes)) } yield ObjectContextResponse.build(update) def mustFindByName404(name: String)(implicit ec: EC): DbResultT[ObjectContext] = @@ -53,8 +51,8 @@ object ObjectManager { ObjectShadows.findOneById(id).mustFindOr(NotFoundFailure404(ObjectShadow, id)) // FIXME: functions should not be taking `M[A]`, `A` will do @michalrus - def getFullObject[T <: ObjectHead[T]]( - readHead: ⇒ DbResultT[T])(implicit ec: EC, db: DB): DbResultT[FullObject[T]] = + def getFullObject[T <: ObjectHead[T]](readHead: ⇒ DbResultT[T])(implicit ec: EC, + db: DB): DbResultT[FullObject[T]] = for { modelHead ← * <~ readHead form ← * <~ ObjectForms.mustFindById404(modelHead.formId) @@ -80,9 +78,7 @@ object ObjectManager { def buildFullObject(model: T) = for { - form ← * <~ getByIdOrFail(formsMap, - model.formId, - ObjectForms.notFound404K(model.formId).single) + form ← * <~ getByIdOrFail(formsMap, model.formId, ObjectForms.notFound404K(model.formId).single) shadow ← * <~ getByIdOrFail(shadowsMap, model.shadowId, diff --git a/phoenix-scala/objectframework/app/objectframework/services/ObjectSchemasManager.scala b/phoenix-scala/objectframework/app/objectframework/services/ObjectSchemasManager.scala index dec2a5f900..f147f76c4f 100644 --- a/phoenix-scala/objectframework/app/objectframework/services/ObjectSchemasManager.scala +++ b/phoenix-scala/objectframework/app/objectframework/services/ObjectSchemasManager.scala @@ -32,25 +32,22 @@ object ObjectSchemasManager { .mustFindOneOr(NotFoundFailure404(ObjectFullSchema, "empty")) def getSchemaByOptNameOrKind(schema: Option[String], kind: String)( - implicit ec: EC): DbResultT[Option[ObjectFullSchema]] = { + implicit ec: EC): DbResultT[Option[ObjectFullSchema]] = schema.fold { ObjectFullSchemas.filterByKind(kind).one } { schemaName ⇒ ObjectFullSchemas.findOneByName(schemaName) }.dbresult - } - def update(name: String, payload: UpdateObjectSchema)(implicit ec: EC, - db: DB): DbResultT[ObjectSchema] = + def update(name: String, payload: UpdateObjectSchema)(implicit ec: EC, db: DB): DbResultT[ObjectSchema] = for { objectSchema ← * <~ ObjectSchemas .findOneByName(name) .mustFindOr(NotFoundFailure404(ObjectSchema, name)) updated ← * <~ ObjectSchemas.update( - objectSchema, - objectSchema.copy(schema = payload.schema, - dependencies = - payload.dependencies.getOrElse(objectSchema.dependencies))) + objectSchema, + objectSchema.copy(schema = payload.schema, + dependencies = payload.dependencies.getOrElse(objectSchema.dependencies))) } yield updated } diff --git a/phoenix-scala/phoenix/app/phoenix/facades/ImageFacade.scala b/phoenix-scala/phoenix/app/phoenix/facades/ImageFacade.scala index e443c69254..8243b725fc 100644 --- a/phoenix-scala/phoenix/app/phoenix/facades/ImageFacade.scala +++ b/phoenix-scala/phoenix/app/phoenix/facades/ImageFacade.scala @@ -42,9 +42,8 @@ object ImageFacade extends ImageHelpers { trait ImageUploader[T] { case class S3Path(dir: String, fileName: String) { - def absPath(): String = { + def absPath(): String = s"$dir/$fileName" - } } object S3Path { @@ -63,13 +62,12 @@ object ImageFacade extends ImageHelpers { } } - def uploadImages(imageSource: T, contextName: String)( - implicit ec: EC, - db: DB, - au: AU, - am: Mat, - sys: ActorSystem, - apis: Apis): DbResultT[Seq[ImagePayload]] = + def uploadImages(imageSource: T, contextName: String)(implicit ec: EC, + db: DB, + au: AU, + am: Mat, + sys: ActorSystem, + apis: Apis): DbResultT[Seq[ImagePayload]] = for { context ← * <~ ObjectManager.mustFindByName404(contextName) result ← * <~ uploadImagesR(imageSource, context, album = None) @@ -101,13 +99,13 @@ object ImageFacade extends ImageHelpers { implicit object ImagePayloadUploader extends ImageUploader[ImagePayload] { - def shouldBeValidImage(imageData: ByteBuffer): Either[Failures, Unit] = { - guessContentType(imageData).map { contentType ⇒ - if (allowedImageTypes.contains(contentType)) Either.right({}) - else Either.left(UnsupportedImageType(contentType).single) - }.getOrElse(Either.left(UnknownImageType.single)) - - } + def shouldBeValidImage(imageData: ByteBuffer): Either[Failures, Unit] = + guessContentType(imageData) + .map { contentType ⇒ + if (allowedImageTypes.contains(contentType)) Either.right({}) + else Either.left(UnsupportedImageType(contentType).single) + } + .getOrElse(Either.left(UnknownImageType.single)) def shouldBeValidUrl(url: String): Either[Failures, Uri] = { val uri = Uri(url) @@ -121,8 +119,7 @@ object ImageFacade extends ImageHelpers { au: AU, am: Mat, sys: ActorSystem, - apis: Apis): DbResultT[Seq[ImagePayload]] = { - + apis: Apis): DbResultT[Seq[ImagePayload]] = for { url ← * <~ shouldBeValidUrl(payload.src) imageData ← * <~ fetchImageData(url) @@ -137,7 +134,6 @@ object ImageFacade extends ImageHelpers { payloads ← * <~ attachImageTo(newPayload, context, maybeAlbum) } yield payloads.map(imageToPayload) - } } implicit object MultipartUploader extends ImageUploader[Multipart.FormData] { @@ -151,12 +147,11 @@ object ImageFacade extends ImageHelpers { } private def uploadPathToS3(filePath: java.nio.file.Path, - s3Path: S3Path)(implicit ec: EC, am: Mat, apis: Apis) = { + s3Path: S3Path)(implicit ec: EC, am: Mat, apis: Apis) = for { url ← apis.amazon.uploadFileF(s3Path.absPath, filePath.toFile) _ = Files.deleteIfExists(filePath) } yield ImageUploaded(url = url, fileName = s3Path.fileName) - } def uploadImagesR(formData: Multipart.FormData, context: OC, maybeAlbum: Option[Album])( implicit ec: EC, @@ -172,11 +167,10 @@ object ImageFacade extends ImageHelpers { .mapAsyncUnordered(4) { part ⇒ for { filePathE ← getFileFromRequest(part.entity.dataBytes) - filePath ← filePathE.fold( - _ ⇒ Future.failed[Path](ImageFacadeException(ErrorReceivingImage)), - Future.successful) - fileName ← part.filename.fold(Future.failed[String](ImageFacadeException( - ImageFilenameNotFoundInPayload)))(Future.successful) + filePath ← filePathE.fold(_ ⇒ Future.failed[Path](ImageFacadeException(ErrorReceivingImage)), + Future.successful) + fileName ← part.filename.fold(Future.failed[String]( + ImageFacadeException(ImageFilenameNotFoundInPayload)))(Future.successful) } yield (filePath, fileName) } .mapAsyncUnordered(4) { @@ -185,9 +179,8 @@ object ImageFacade extends ImageHelpers { uploadPathToS3(filePath, s3path) } .map { srcInfo ⇒ - val payload = ImagePayload(src = srcInfo.url, - title = srcInfo.fileName.some, - alt = srcInfo.fileName.some) + val payload = + ImagePayload(src = srcInfo.url, title = srcInfo.fileName.some, alt = srcInfo.fileName.some) attachImageTo(payload, context, maybeAlbum).map(_.map(imageToPayload)) @@ -241,23 +234,17 @@ object ImageFacade extends ImageHelpers { au: AU, am: Mat, sys: ActorSystem, - apis: Apis): DbResultT[AlbumRoot] = { - + apis: Apis): DbResultT[AlbumRoot] = uploadImagesToAlbum[ImagePayload](albumId, contextName, payload) - } - def uploadImagesFromMultipartToAlbum(albumId: Int, - contextName: String, - formData: Multipart.FormData)( + def uploadImagesFromMultipartToAlbum(albumId: Int, contextName: String, formData: Multipart.FormData)( implicit ec: EC, db: DB, au: AU, am: Mat, sys: ActorSystem, - apis: Apis): DbResultT[AlbumRoot] = { - + apis: Apis): DbResultT[AlbumRoot] = uploadImagesToAlbum[Multipart.FormData](albumId, contextName, formData) - } def uploadImagesFromMultiPart(contextName: String, formData: Multipart.FormData)( implicit ec: EC, @@ -265,18 +252,14 @@ object ImageFacade extends ImageHelpers { au: AU, am: Mat, sys: ActorSystem, - apis: Apis): DbResultT[Seq[ImagePayload]] = { - + apis: Apis): DbResultT[Seq[ImagePayload]] = ImageUploader.MultipartUploader.uploadImages(formData, contextName) - } // - endpoints - def attachImageToAlbum(album: Album, payload: ImagePayload)( - implicit ec: EC, - db: DB, - au: AU, - oc: OC): DbResultT[Seq[FullObject[Image]]] = + def attachImageToAlbum( + album: Album, + payload: ImagePayload)(implicit ec: EC, db: DB, au: AU, oc: OC): DbResultT[Seq[FullObject[Image]]] = for { existingImages ← * <~ AlbumImageLinks.queryRightByLeft(album) newPayloads = existingImages.map(imageToPayload) :+ payload @@ -316,16 +299,15 @@ trait ImageHelpers extends LazyLogging { protected def extractFileNameFromUri(uri: Uri): String = { @tailrec - def latestSegment(path: Uri.Path): Option[String] = { + def latestSegment(path: Uri.Path): Option[String] = path match { case Uri.Path.Slash(tail) ⇒ latestSegment(tail) case Uri.Path.Segment(head, _) ⇒ Some(head) case Uri.Path.Empty ⇒ None } - } val revPath = uri.path.reverse - latestSegment(revPath).getOrElse(s"${generateUuid}.jpg") + latestSegment(revPath).getOrElse(s"$generateUuid.jpg") } def fetchImageData(uri: Uri)(implicit ec: EC, sys: ActorSystem, am: Mat): Result[ByteBuffer] = { @@ -335,22 +317,23 @@ trait ImageHelpers extends LazyLogging { Either.right[Failures, ByteBuffer](body.asByteBuffer) } case HttpResponse(code, _, _, _) ⇒ - Future.successful( - Either.left[Failures, ByteBuffer](ImageFetchFailed(code.intValue()).single)) + Future.successful(Either.left[Failures, ByteBuffer](ImageFetchFailed(code.intValue()).single)) } Result.fromFEither(r) } private def saveByteBuffer(b: ByteBuffer): Either[Failures, Path] = - Either.catchNonFatal { - val path = Files.createTempFile("s3tmp", ".img") - val ch = FileChannel.open(path, java.nio.file.StandardOpenOption.WRITE) - ch.write(b) - ch.force(false) - ch.close() - path - }.leftMap(ImageTemporarySaveFailed(_).single) + Either + .catchNonFatal { + val path = Files.createTempFile("s3tmp", ".img") + val ch = FileChannel.open(path, java.nio.file.StandardOpenOption.WRITE) + ch.write(b) + ch.force(false) + ch.close() + path + } + .leftMap(ImageTemporarySaveFailed(_).single) protected def saveBufferAndThen[R](b: ByteBuffer)(block: Path ⇒ DbResultT[R])( implicit ec: EC): DbResultT[R] = @@ -367,11 +350,10 @@ trait ImageHelpers extends LazyLogging { new utils.io.ByteBufferInputStream(buffer) } - protected def guessContentType(byteBuffer: ByteBuffer): Option[String] = { + protected def guessContentType(byteBuffer: ByteBuffer): Option[String] = Try { // can return null or throw exception Option(URLConnection.guessContentTypeFromStream(asInputStream(byteBuffer))) }.toOption.flatten - } } diff --git a/phoenix-scala/phoenix/app/phoenix/facades/NotificationFacade.scala b/phoenix-scala/phoenix/app/phoenix/facades/NotificationFacade.scala index 5e22fb10fa..c4d6a918de 100644 --- a/phoenix-scala/phoenix/app/phoenix/facades/NotificationFacade.scala +++ b/phoenix-scala/phoenix/app/phoenix/facades/NotificationFacade.scala @@ -29,12 +29,11 @@ object NotificationFacade extends LazyLogging { val retriesToFindListenerActor = 5 implicit val akkaTimeout: akka.util.Timeout = akka.util.Timeout(500.millisecond) - def streamByAdminId(adminId: Int)( - implicit au: AU, - ec: EC, - db: DB, - mat: Mat, - system: ActorSystem): Future[Source[EventStreamElement, Any]] = { + def streamByAdminId(adminId: Int)(implicit au: AU, + ec: EC, + db: DB, + mat: Mat, + system: ActorSystem): Future[Source[EventStreamElement, Any]] = Users.findOneByAccountId(adminId).run().flatMap { case Some(admin) ⇒ newNotifications(adminId).map { newNotificator ⇒ @@ -44,7 +43,6 @@ object NotificationFacade extends LazyLogging { case None ⇒ Future.successful(Source.single(SSE(s"Error! User with account id=$adminId not found"))) } - } private def subscribeToDbListenerActor(adminId: Int, retries: Int)( implicit ec: EC, @@ -61,8 +59,8 @@ object NotificationFacade extends LazyLogging { case _ ⇒ try { val ref = system.actorOf( - akka.actor.Props(new NotificationListener(adminId, (msg, ref) ⇒ ref ! SSE(msg))), - listenerActorName + akka.actor.Props(new NotificationListener(adminId, (msg, ref) ⇒ ref ! SSE(msg))), + listenerActorName ) Future.successful(ref) } catch { @@ -76,13 +74,15 @@ object NotificationFacade extends LazyLogging { adminId: Int)(implicit ec: EC, mat: Mat, system: ActorSystem): Future[Source[SSE, Any]] = { val listenerFutureRef = subscribeToDbListenerActor(adminId, retriesToFindListenerActor) - listenerFutureRef.flatMap { ref ⇒ - (ref ? NotificationListener.NewClientConnected).mapTo[ActorRef] + listenerFutureRef + .flatMap { ref ⇒ + (ref ? NotificationListener.NewClientConnected).mapTo[ActorRef] - }.map { childRef ⇒ - val ssePublisher = ActorPublisher[SSE](childRef) - Source.fromPublisher(ssePublisher) - } + } + .map { childRef ⇒ + val ssePublisher = ActorPublisher[SSE](childRef) + Source.fromPublisher(ssePublisher) + } } private def oldNotifications(adminId: Int)(implicit au: AU, db: DB): Source[SSE, Any] = { diff --git a/phoenix-scala/phoenix/app/phoenix/failures/ArchiveFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/ArchiveFailures.scala index bbe3e14bcb..69ddef5b93 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/ArchiveFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/ArchiveFailures.scala @@ -8,10 +8,9 @@ object ArchiveFailures { case class LinkInactiveSkuFailure(description: String) extends Failure object LinkInactiveSkuFailure { - def apply[T](target: T, targetId: Any, code: String): LinkInactiveSkuFailure = { + def apply[T](target: T, targetId: Any, code: String): LinkInactiveSkuFailure = LinkInactiveSkuFailure( - s"Cannot attach inactive sku with code $code to ${friendlyClassName(target)} with id $targetId") - } + s"Cannot attach inactive sku with code $code to ${friendlyClassName(target)} with id $targetId") } case class AddImagesToArchivedAlbumFailure(albumId: Int) extends Failure { diff --git a/phoenix-scala/phoenix/app/phoenix/failures/AssignmentFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/AssignmentFailures.scala index f24aaf79bf..2b94e79a69 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/AssignmentFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/AssignmentFailures.scala @@ -13,7 +13,7 @@ object AssignmentFailures { def apply[A](a: A, searchKey: Any, storeAdminId: Int): AlreadyAssignedFailure = { val model = friendlyClassName(a) AlreadyAssignedFailure( - s"storeAdmin with id=$storeAdminId is already assigned to $model with key=$searchKey") + s"storeAdmin with id=$storeAdminId is already assigned to $model with key=$searchKey") } } @@ -24,8 +24,7 @@ object AssignmentFailures { object NotAssignedFailure { def apply[A](a: A, searchKey: Any, storeAdminId: Int): NotAssignedFailure = { val model = friendlyClassName(a) - NotAssignedFailure( - s"storeAdmin with id=$storeAdminId is not assigned to $model with key=$searchKey") + NotAssignedFailure(s"storeAdmin with id=$storeAdminId is not assigned to $model with key=$searchKey") } } @@ -36,8 +35,7 @@ object AssignmentFailures { object AssigneeNotFoundFailure { def apply[A](a: A, searchKey: Any, assigneeId: Int): AssigneeNotFoundFailure = { val model = friendlyClassName(a) - AssigneeNotFoundFailure( - s"storeAdmin with id=$assigneeId is not assigned to $model with key=$searchKey") + AssigneeNotFoundFailure(s"storeAdmin with id=$assigneeId is not assigned to $model with key=$searchKey") } } } diff --git a/phoenix-scala/phoenix/app/phoenix/failures/CategoryFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/CategoryFailures.scala index 7dea72d6de..b14efd624a 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/CategoryFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/CategoryFailures.scala @@ -12,7 +12,7 @@ object CategoryFailures { object CategoryNotFoundForContext { def apply(categoryId: Int, categoryContextId: Int) = NotFoundFailure404( - s"Category with id=$categoryId with category context $categoryContextId cannot be found") + s"Category with id=$categoryId with category context $categoryContextId cannot be found") } object CategoryFormNotFound { diff --git a/phoenix-scala/phoenix/app/phoenix/failures/CouponFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/CouponFailures.scala index 92dd778772..5dd489414f 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/CouponFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/CouponFailures.scala @@ -34,7 +34,7 @@ object CouponFailures { } case class CouponCodeLengthIsTooSmall(prefix: String, quantity: Int) extends Failure { - val minSize = CouponCodes.charactersGivenQuantity(quantity) + prefix.length + val minSize = CouponCodes.charactersGivenQuantity(quantity) + prefix.length override def description = s"Coupon code character length must be at least $minSize" } @@ -45,8 +45,7 @@ object CouponFailures { object CouponNotFoundForContext { def apply(couponId: Int, contextName: String) = - NotFoundFailure404( - s"Coupon with id=$couponId with coupon context $contextName cannot be found") + NotFoundFailure404(s"Coupon with id=$couponId with coupon context $contextName cannot be found") } object CouponNotFoundForDefaultContext { @@ -76,16 +75,15 @@ object CouponFailures { case class CouponUsageRulesAreEmpty(couponCode: String) extends Failure { override def description = - s"Coupon usage rules are not set for coupon with code: '${couponCode}'" + s"Coupon usage rules are not set for coupon with code: '$couponCode'" } case class CouponCodeCannotBeUsedAnymore(couponCode: String) extends Failure { - override def description = s"Coupon code '${couponCode}' cannot be used anymore" + override def description = s"Coupon code '$couponCode' cannot be used anymore" } - case class CouponCodeCannotBeUsedByCustomerAnymore(couponCode: String, accountId: Int) - extends Failure { + case class CouponCodeCannotBeUsedByCustomerAnymore(couponCode: String, accountId: Int) extends Failure { override def description = - s"Coupon code '${couponCode}' cannot be used by this customer ${accountId} anymore" + s"Coupon code '$couponCode' cannot be used by this customer $accountId anymore" } } diff --git a/phoenix-scala/phoenix/app/phoenix/failures/CustomerGroupFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/CustomerGroupFailures.scala index 2085bc2438..7eba52e692 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/CustomerGroupFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/CustomerGroupFailures.scala @@ -5,9 +5,7 @@ import phoenix.models.customer.CustomerGroup.GroupType object CustomerGroupFailures { - case class CustomerGroupTypeIsWrong(groupId: Int, - realGroupType: GroupType, - expected: Set[GroupType]) + case class CustomerGroupTypeIsWrong(groupId: Int, realGroupType: GroupType, expected: Set[GroupType]) extends Failure { override def description = s"Customer group with id $groupId has $realGroupType type but is expected to have ${expected.mkString(",")}" diff --git a/phoenix-scala/phoenix/app/phoenix/failures/DiscountCompilerFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/DiscountCompilerFailures.scala index a7ae702f7c..6b88822c5e 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/DiscountCompilerFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/DiscountCompilerFailures.scala @@ -48,7 +48,7 @@ object DiscountCompilerFailures { case class QualifierAttributesExtractionFailure(qualifierType: QualifierType, cause: String) extends Failure { override def description = - s"failed to compile qualifier ${show(qualifierType)}, couldn't extract attributes: ${cause}" + s"failed to compile qualifier ${show(qualifierType)}, couldn't extract attributes: $cause" } case class QualifierNotImplementedFailure(qualifierType: QualifierType) extends Failure { @@ -66,10 +66,9 @@ object DiscountCompilerFailures { } /* Offer Compiler */ - case class OfferAttributesExtractionFailure(offerType: OfferType, cause: String) - extends Failure { + case class OfferAttributesExtractionFailure(offerType: OfferType, cause: String) extends Failure { override def description = - s"failed to compile offer ${OfferType.show(offerType)}, couldn't extract attributes: ${cause}" + s"failed to compile offer ${OfferType.show(offerType)}, couldn't extract attributes: $cause" } case class OfferNotImplementedFailure(offerType: OfferType) extends Failure { @@ -82,9 +81,7 @@ object DiscountCompilerFailures { } /* Rejections */ - case class QualifierRejectionFailure[T <: Qualifier](qualifier: T, - input: DiscountInput, - reason: String) + case class QualifierRejectionFailure[T <: Qualifier](qualifier: T, input: DiscountInput, reason: String) extends Failure { val qName = friendlyClassName(qualifier) override def description = diff --git a/phoenix-scala/phoenix/app/phoenix/failures/DiscountFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/DiscountFailures.scala index 4b3c9ce670..77b56f721c 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/DiscountFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/DiscountFailures.scala @@ -16,7 +16,7 @@ object DiscountFailures { object DiscountNotFoundForContext { def apply(discountId: Int, discountContextId: Int) = NotFoundFailure404( - s"Discount with id=$discountId with discount context $discountContextId cannot be found") + s"Discount with id=$discountId with discount context $discountContextId cannot be found") } case class DiscountShadowHasInvalidAttribute(key: String, value: String) extends Failure { diff --git a/phoenix-scala/phoenix/app/phoenix/failures/Failure.scala b/phoenix-scala/phoenix/app/phoenix/failures/Failure.scala index df4d18bfaa..e19b3a4edb 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/Failure.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/Failure.scala @@ -13,18 +13,13 @@ case class StateTransitionNotAllowed(message: String) extends Failure { } object StateTransitionNotAllowed { - def apply[A](a: A, - fromState: String, - toState: String, - searchKey: Any): StateTransitionNotAllowed = { + def apply[A](a: A, fromState: String, toState: String, searchKey: Any): StateTransitionNotAllowed = StateTransitionNotAllowed( - s"Transition from $fromState to $toState is not allowed for ${friendlyClassName(a)} " + - s"with key=$searchKey") - } + s"Transition from $fromState to $toState is not allowed for ${friendlyClassName(a)} " + + s"with key=$searchKey") - def apply(from: Order.State, to: Order.State, refNum: String): StateTransitionNotAllowed = { + def apply(from: Order.State, to: Order.State, refNum: String): StateTransitionNotAllowed = apply(Order, from.toString, to.toString, refNum) - } } case class NotificationTrailNotFound400(adminId: Int) extends Failure { diff --git a/phoenix-scala/phoenix/app/phoenix/failures/OrderFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/OrderFailures.scala index 7cdbb5a36c..b4fa717cc4 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/OrderFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/OrderFailures.scala @@ -44,6 +44,6 @@ object OrderFailures { } case class OrderLineItemNotFound(refNum: String) extends Failure { - override def description = s"Order line item with referenceNumber=${refNum} not found" + override def description = s"Order line item with referenceNumber=$refNum not found" } } diff --git a/phoenix-scala/phoenix/app/phoenix/failures/ProductFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/ProductFailures.scala index 0687348ed6..1d45ce1cfd 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/ProductFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/ProductFailures.scala @@ -48,18 +48,16 @@ object ProductFailures { object ProductNotFoundForContext { def apply(productId: Int, productContextId: Int) = - NotFoundFailure404( - s"Product with id=$productId with product context $productContextId cannot be found") + NotFoundFailure404(s"Product with id=$productId with product context $productContextId cannot be found") def apply(slug: String, productContextId: Int) = - NotFoundFailure404( - s"Product with slug=$slug with product context $productContextId cannot be found") + NotFoundFailure404(s"Product with slug=$slug with product context $productContextId cannot be found") } object ProductFormNotFoundForContext { def apply(formId: Int, productContextId: Int) = NotFoundFailure404( - s"Product form with id=$formId with product context $productContextId cannot be found") + s"Product form with id=$formId with product context $productContextId cannot be found") } object NoAlbumsFoundForProduct { diff --git a/phoenix-scala/phoenix/app/phoenix/failures/PromotionFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/PromotionFailures.scala index 95ecd10170..9c907e461a 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/PromotionFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/PromotionFailures.scala @@ -20,7 +20,7 @@ object PromotionFailures { object PromotionNotFoundForContext { def apply(promotionId: Int, contextName: String) = NotFoundFailure404( - s"Promotion with id=$promotionId with promotion context $contextName cannot be found") + s"Promotion with id=$promotionId with promotion context $contextName cannot be found") } case object PromotionIsNotActive extends Failure { diff --git a/phoenix-scala/phoenix/app/phoenix/failures/ReturnFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/ReturnFailures.scala index 4fe1da84d1..02b20e6cce 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/ReturnFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/ReturnFailures.scala @@ -25,14 +25,12 @@ object ReturnFailures { NotFoundFailure400(s"${friendlyClassName(m)} payment not found") } - case class ReturnShippingCostExceeded(refNum: String, amount: Long, maxAmount: Long) - extends Failure { + case class ReturnShippingCostExceeded(refNum: String, amount: Long, maxAmount: Long) extends Failure { def description: String = s"Returned shipping cost ($amount) cannot be greater than $maxAmount for return $refNum" } - case class ReturnSkuItemQuantityExceeded(refNum: String, quantity: Int, maxQuantity: Int) - extends Failure { + case class ReturnSkuItemQuantityExceeded(refNum: String, quantity: Int, maxQuantity: Int) extends Failure { def description: String = s"Returned sku line item quantity ($quantity) cannot be greater than $maxQuantity for return $refNum" } @@ -42,23 +40,19 @@ object ReturnFailures { s"Returned payment ($amount) cannot be greater than $maxAmount for return $refNum" } - case class ReturnCcPaymentExceeded(refNum: String, amount: Long, maxAmount: Long) - extends Failure { + case class ReturnCcPaymentExceeded(refNum: String, amount: Long, maxAmount: Long) extends Failure { def description: String = s"Returned credit card payment ($amount) cannot be greater than $maxAmount for return $refNum" } - case class ReturnCcPaymentCurrencyMismatch(refNum: String, - expected: Currency, - actual: List[Currency]) + case class ReturnCcPaymentCurrencyMismatch(refNum: String, expected: Currency, actual: List[Currency]) extends Failure { def description: String = "Cannot have return for order with more than one currency. " + s"Expected $expected, but got: ${actual.mkString(", ")}" } - case class ReturnCcPaymentViolation(refNum: String, issued: Long, allowed: Long) - extends Failure { + case class ReturnCcPaymentViolation(refNum: String, issued: Long, allowed: Long) extends Failure { def description: String = s"Issued credit card payment ($issued) is different than $allowed for return $refNum" } diff --git a/phoenix-scala/phoenix/app/phoenix/failures/TreeFailures.scala b/phoenix-scala/phoenix/app/phoenix/failures/TreeFailures.scala index 807c67c86e..ff0d925703 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/TreeFailures.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/TreeFailures.scala @@ -16,11 +16,10 @@ object TreeFailures { def apply(treeName: String, context: String, nodeIndex: Int) = NotFoundFailure404( - s"Tree node with index=$nodeIndex in tree $treeName and context $context cannot be found") + s"Tree node with index=$nodeIndex in tree $treeName and context $context cannot be found") def apply(treeName: String, context: String, path: String) = - NotFoundFailure404( - s"Tree node with path=$path in tree $treeName and context $context cannot be found") + NotFoundFailure404(s"Tree node with path=$path in tree $treeName and context $context cannot be found") } object TreeNotFound { diff --git a/phoenix-scala/phoenix/app/phoenix/failures/Util.scala b/phoenix-scala/phoenix/app/phoenix/failures/Util.scala index 1ca4e968fa..14cb354c3d 100644 --- a/phoenix-scala/phoenix/app/phoenix/failures/Util.scala +++ b/phoenix-scala/phoenix/app/phoenix/failures/Util.scala @@ -9,8 +9,6 @@ object Util { Failures(requested.diff(available).map(NotFoundFailure404(modelType, _)): _*) /* Diff lists of model identifiers to produce a list of warnings for absent models */ - def diffToFlatFailures[A, B](requested: Seq[A], - available: Seq[A], - modelType: B): Option[List[String]] = + def diffToFlatFailures[A, B](requested: Seq[A], available: Seq[A], modelType: B): Option[List[String]] = diffToFailures(requested, available, modelType).map(_.flatten) } diff --git a/phoenix-scala/phoenix/app/phoenix/libs/oauth/google.scala b/phoenix-scala/phoenix/app/phoenix/libs/oauth/google.scala index 1af30ed30f..bb27ff71de 100644 --- a/phoenix-scala/phoenix/app/phoenix/libs/oauth/google.scala +++ b/phoenix-scala/phoenix/app/phoenix/libs/oauth/google.scala @@ -18,9 +18,8 @@ case class GoogleOauthOptions( hostedDomain: Option[String] = None ) extends OauthClientOptions { - override def buildExtraAuthParams: Map[String, String] = { + override def buildExtraAuthParams: Map[String, String] = Map.empty[String, String].+?("hd", hostedDomain).+("access_type" → accessType) - } } trait GoogleProvider extends OauthProvider { @@ -31,7 +30,7 @@ trait GoogleProvider extends OauthProvider { def userInfo(accessToken: String)(implicit ec: EC): EitherT[Future, Throwable, UserInfo] = eitherTryFuture { - val req = request(oauthInfoUrl).GET.addHeader("Authorization", s"Bearer ${accessToken}") + val req = request(oauthInfoUrl).GET.addHeader("Authorization", s"Bearer $accessToken") Http(req OK as.json4s.Json).map(_.extract[UserInfo]) } } diff --git a/phoenix-scala/phoenix/app/phoenix/libs/oauth/oauthv2.scala b/phoenix-scala/phoenix/app/phoenix/libs/oauth/oauthv2.scala index 85a1614c34..4fe3ef8fe5 100644 --- a/phoenix-scala/phoenix/app/phoenix/libs/oauth/oauthv2.scala +++ b/phoenix-scala/phoenix/app/phoenix/libs/oauth/oauthv2.scala @@ -27,28 +27,29 @@ trait OauthClientOptions { abstract class Oauth(oauthOptions: OauthClientOptions) extends OauthProvider { val authorizationParams = Map( - "client_id" → oauthOptions.clientId, - "redirect_uri" → oauthOptions.redirectUri, - "response_type" → "code" + "client_id" → oauthOptions.clientId, + "redirect_uri" → oauthOptions.redirectUri, + "response_type" → "code" ) /* "Returns the OAuth authorization url." */ - def authorizationUri(scope: Seq[String]): String = { + def authorizationUri(scope: Seq[String]): String = // TODO: add state request(oauthAuthorizationUrl) .< ((LastSeenNotification.apply _).tupled, - LastSeenNotification.unapply) + LastSeenNotification.unapply) def account = foreignKey(Accounts.tableName, accountId, Accounts)(_.id) } object LastSeenNotifications - extends FoxTableQuery[LastSeenNotification, LastSeenNotifications]( - new LastSeenNotifications(_)) + extends FoxTableQuery[LastSeenNotification, LastSeenNotifications](new LastSeenNotifications(_)) with ReturningId[LastSeenNotification, LastSeenNotifications] { val returningLens: Lens[LastSeenNotification, Int] = lens[LastSeenNotification].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/Note.scala b/phoenix-scala/phoenix/app/phoenix/models/Note.scala index 336ad27eb0..ac3c0c805e 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/Note.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/Note.scala @@ -30,11 +30,10 @@ case class Note(id: Int = 0, import Validation._ - override def validate: ValidatedNel[Failure, Note] = { + override def validate: ValidatedNel[Failure, Note] = (notEmpty(body, "body") |@| lesserThanOrEqual(body.length, 1000, "bodySize")).map { case _ ⇒ this } - } } object Note { diff --git a/phoenix-scala/phoenix/app/phoenix/models/NotificationSubscription.scala b/phoenix-scala/phoenix/app/phoenix/models/NotificationSubscription.scala index 754571ebbf..b4dd6afd24 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/NotificationSubscription.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/NotificationSubscription.scala @@ -45,7 +45,7 @@ class NotificationSubscriptions(tag: Tag) def * = (id, adminId, dimensionId, objectId, createdAt, reason) <> ((NotificationSubscription.apply _).tupled, - NotificationSubscription.unapply) + NotificationSubscription.unapply) def dimension = foreignKey(Dimensions.tableName, dimensionId, Dimensions)(_.id) def admin = foreignKey(Users.tableName, adminId, Users)(_.accountId) @@ -53,7 +53,7 @@ class NotificationSubscriptions(tag: Tag) object NotificationSubscriptions extends FoxTableQuery[NotificationSubscription, NotificationSubscriptions]( - new NotificationSubscriptions(_)) + new NotificationSubscriptions(_)) with ReturningId[NotificationSubscription, NotificationSubscriptions] { val returningLens: Lens[NotificationSubscription, Int] = lens[NotificationSubscription].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/Notifications.scala b/phoenix-scala/phoenix/app/phoenix/models/Notifications.scala index 73e62c4bd8..66b8ca08cc 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/Notifications.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/Notifications.scala @@ -31,7 +31,7 @@ class Notifications(tag: Tag) extends FoxTable[Notification](tag, "notifications def * = (id, scope, accountId, dimensionId, objectId, activity, createdAt) <> ((Notification.apply _).tupled, - Notification.unapply) + Notification.unapply) def account = foreignKey(Accounts.tableName, accountId, Accounts)(_.id) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/Reason.scala b/phoenix-scala/phoenix/app/phoenix/models/Reason.scala index 647bcdefc5..d5b32aeafd 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/Reason.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/Reason.scala @@ -24,11 +24,10 @@ case class Reason(id: Int = 0, import Validation._ - override def validate: ValidatedNel[Failure, Reason] = { + override def validate: ValidatedNel[Failure, Reason] = (notEmpty(body, "body") |@| lesserThanOrEqual(body.length, 255, "bodySize")).map { case _ ⇒ this } - } def isSubReason: Boolean = parentId.isDefined } @@ -63,9 +62,7 @@ class Reasons(tag: Tag) extends FoxTable[Reason](tag, "reasons") { def author = foreignKey(Users.tableName, storeAdminId, Users)(_.accountId) } -object Reasons - extends FoxTableQuery[Reason, Reasons](new Reasons(_)) - with ReturningId[Reason, Reasons] { +object Reasons extends FoxTableQuery[Reason, Reasons](new Reasons(_)) with ReturningId[Reason, Reasons] { val returningLens: Lens[Reason, Int] = lens[Reason].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/SaveForLater.scala b/phoenix-scala/phoenix/app/phoenix/models/SaveForLater.scala index fe78f2412a..0a16469d17 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/SaveForLater.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/SaveForLater.scala @@ -7,10 +7,7 @@ import phoenix.models.account._ import shapeless._ import slick.jdbc.PostgresProfile.api._ -case class SaveForLater(id: Int = 0, - accountId: Int = 0, - skuId: Int, - createdAt: Instant = Instant.now) +case class SaveForLater(id: Int = 0, accountId: Int = 0, skuId: Int, createdAt: Instant = Instant.now) extends FoxModel[SaveForLater] {} object SaveForLater {} diff --git a/phoenix-scala/phoenix/app/phoenix/models/account/Account.scala b/phoenix-scala/phoenix/app/phoenix/models/account/Account.scala index f8dda1f94e..3c69190b5f 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/account/Account.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/account/Account.scala @@ -36,7 +36,6 @@ object Accounts val returningLens: Lens[Account, Int] = lens[Account].id - def findByIdAndRatchet(id: Int, ratchet: Int): DBIO[Option[Account]] = { + def findByIdAndRatchet(id: Int, ratchet: Int): DBIO[Option[Account]] = filter(_.id === id).filter(_.ratchet === ratchet).one - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/account/AccountAccessMethod.scala b/phoenix-scala/phoenix/app/phoenix/models/account/AccountAccessMethod.scala index 35cbd1b2dd..ff3f744ab2 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/account/AccountAccessMethod.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/account/AccountAccessMethod.scala @@ -22,13 +22,11 @@ case class AccountAccessMethod(id: Int = 0, deletedAt: Option[Instant] = None) extends FoxModel[AccountAccessMethod] { - def updatePassword(newPassword: String): AccountAccessMethod = { + def updatePassword(newPassword: String): AccountAccessMethod = this.copy(hashedPassword = algorithm.hasher.generateHash(newPassword), updatedAt = Instant.now) - } - def checkPassword(password: String): Boolean = { + def checkPassword(password: String): Boolean = algorithm.hasher.checkHash(password, hashedPassword) - } } object AccountAccessMethod extends LazyLogging { @@ -57,8 +55,7 @@ object AccountAccessMethod extends LazyLogging { algorithm = algorithm) } -class AccountAccessMethods(tag: Tag) - extends FoxTable[AccountAccessMethod](tag, "account_access_methods") { +class AccountAccessMethods(tag: Tag) extends FoxTable[AccountAccessMethod](tag, "account_access_methods") { import AccountAccessMethods.PasswordAlgorithmColumn @@ -80,13 +77,14 @@ object AccountAccessMethods with ReturningId[AccountAccessMethod, AccountAccessMethods] with SearchById[AccountAccessMethod, AccountAccessMethods] { - implicit lazy val PasswordAlgorithmColumn: JdbcType[HashAlgorithm] with BaseTypedType[ - HashAlgorithm] = { - MappedColumnType.base[HashAlgorithm, Int](c ⇒ c.code, { - case HashPasswords.SCrypt.code ⇒ HashPasswords.SCrypt - case HashPasswords.PlainText.code ⇒ HashPasswords.PlainText - case j ⇒ HashPasswords.UnknownAlgorithm(j) - }) + implicit lazy val PasswordAlgorithmColumn: JdbcType[HashAlgorithm] with BaseTypedType[HashAlgorithm] = { + MappedColumnType.base[HashAlgorithm, Int]( + c ⇒ c.code, { + case HashPasswords.SCrypt.code ⇒ HashPasswords.SCrypt + case HashPasswords.PlainText.code ⇒ HashPasswords.PlainText + case j ⇒ HashPasswords.UnknownAlgorithm(j) + } + ) } val returningLens: Lens[AccountAccessMethod, Int] = lens[AccountAccessMethod].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/account/AccountOrganization.scala b/phoenix-scala/phoenix/app/phoenix/models/account/AccountOrganization.scala index 2b6384f653..07163a13fd 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/account/AccountOrganization.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/account/AccountOrganization.scala @@ -7,8 +7,7 @@ import slick.jdbc.PostgresProfile.api._ case class AccountOrganization(id: Int = 0, accountId: Int, organizationId: Int) extends FoxModel[AccountOrganization] -class AccountOrganizations(tag: Tag) - extends FoxTable[AccountOrganization](tag, "account_organizations") { +class AccountOrganizations(tag: Tag) extends FoxTable[AccountOrganization](tag, "account_organizations") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def accountId = column[Int]("account_id") def organizationId = column[Int]("organization_id") diff --git a/phoenix-scala/phoenix/app/phoenix/models/account/Organization.scala b/phoenix-scala/phoenix/app/phoenix/models/account/Organization.scala index ee2f28e7f0..400a9ef1d3 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/account/Organization.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/account/Organization.scala @@ -36,17 +36,14 @@ object Organizations val returningLens: Lens[Organization, Int] = lens[Organization].id - def findByName(name: String): DBIO[Option[Organization]] = { + def findByName(name: String): DBIO[Option[Organization]] = filter(_.name === name).one - } - def findByScopeId(scopeId: Int): DBIO[Option[Organization]] = { + def findByScopeId(scopeId: Int): DBIO[Option[Organization]] = filter(_.scopeId === scopeId).one - } - def findByNameInScope(name: String, scopeId: Int): DBIO[Option[Organization]] = { + def findByNameInScope(name: String, scopeId: Int): DBIO[Option[Organization]] = filter(_.name === name).filter(_.scopeId === scopeId).one - } def filterByIdAndScope(id: Int, scopeId: Int): QuerySeq = filter(_.id === id).filter(_.scopeId === scopeId) diff --git a/phoenix-scala/phoenix/app/phoenix/models/account/RolePermission.scala b/phoenix-scala/phoenix/app/phoenix/models/account/RolePermission.scala index db7d5a82f1..5cd9dbb187 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/account/RolePermission.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/account/RolePermission.scala @@ -4,8 +4,7 @@ import core.db._ import shapeless._ import slick.jdbc.PostgresProfile.api._ -case class RolePermission(id: Int = 0, roleId: Int, permissionId: Int) - extends FoxModel[RolePermission] +case class RolePermission(id: Int = 0, roleId: Int, permissionId: Int) extends FoxModel[RolePermission] class RolePermissions(tag: Tag) extends FoxTable[RolePermission](tag, "role_permissions") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) diff --git a/phoenix-scala/phoenix/app/phoenix/models/account/Scope.scala b/phoenix-scala/phoenix/app/phoenix/models/account/Scope.scala index 2f707ea137..1b49ba6211 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/account/Scope.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/account/Scope.scala @@ -22,15 +22,13 @@ object Scope { def current(implicit au: AU): LTree = LTree(au.token.scope) - def resolveOverride(maybeSubscope: Option[String] = None)(implicit ec: EC, - au: AU): DbResultT[LTree] = + def resolveOverride(maybeSubscope: Option[String] = None)(implicit ec: EC, au: AU): DbResultT[LTree] = overwrite(au.token.scope, maybeSubscope) def overwrite(scope: String, maybeSubscope: Option[String])(implicit ec: EC): DbResultT[LTree] = DbResultT.fromEither(scopeOrSubscope(scope, maybeSubscope)).map(LTree(_)) - private def scopeOrSubscope(scope: String, - maybeSubscope: Option[String]): Either[Failures, String] = + private def scopeOrSubscope(scope: String, maybeSubscope: Option[String]): Either[Failures, String] = maybeSubscope match { case _ if scope.isEmpty ⇒ Either.left(EmptyScope.single) case Some(subscope) ⇒ validateSubscope(scope, subscope) diff --git a/phoenix-scala/phoenix/app/phoenix/models/account/User.scala b/phoenix-scala/phoenix/app/phoenix/models/account/User.scala index 3616180064..c5ff0adf1c 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/account/User.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/account/User.scala @@ -35,30 +35,26 @@ case class User(id: Int = 0, case _ ⇒ Either.left(UserMustHaveCredentials.single) } - def mustNotBeBlacklisted: Either[Failures, User] = { + def mustNotBeBlacklisted: Either[Failures, User] = if (isBlacklisted) Either.left(UserIsBlacklisted(accountId).single) else Either.right(this) - } - def mustNotBeMigrated: Either[Failures, User] = { + def mustNotBeMigrated: Either[Failures, User] = if (isMigrated) Either.left(UserIsMigrated(id).single) else Either.right(this) - } - override def validate: ValidatedNel[Failure, User] = { + override def validate: ValidatedNel[Failure, User] = (nameValid |@| emailValid).map { case _ ⇒ this } - } private def nameValid = if (name.isEmpty) Validated.Valid(this) else - (notEmpty(name, "name") |@| notEmpty(name.getOrElse(""), "name") |@| matches( - name.getOrElse(""), - User.namePattern, - "name")).map { + (notEmpty(name, "name") |@| notEmpty(name.getOrElse(""), "name") |@| matches(name.getOrElse(""), + User.namePattern, + "name")).map { case _ ⇒ this } @@ -114,17 +110,15 @@ object Users extends FoxTableQuery[User, Users](new Users(_)) with ReturningId[U val returningLens: Lens[User, Int] = lens[User].id - def findByEmail(email: String): QuerySeq = { + def findByEmail(email: String): QuerySeq = filter(_.email === email) - } - def findNonGuestByEmail(email: String): QuerySeq = { + def findNonGuestByEmail(email: String): QuerySeq = findByEmail(email) .joinLeft(CustomersData) .on(_.accountId === _.accountId) .filterNot { case (_, data) ⇒ data.map(_.isGuest).getOrElse(false) } - .map { case (user, _) ⇒ user } - } + .map { case (user, _) ⇒ user } def activeUserByEmail(email: Option[String]): QuerySeq = filter(c ⇒ c.email === email && !c.isBlacklisted && !c.isDisabled) @@ -132,9 +126,8 @@ object Users extends FoxTableQuery[User, Users](new Users(_)) with ReturningId[U def mustfindOneByEmail(email: String)(implicit ec: EC): DbResultT[User] = findByEmail(email).mustFindOneOr(NotFoundFailure404(User, email)) - def otherUserByEmail(email: String, accountId: Int): QuerySeq = { + def otherUserByEmail(email: String, accountId: Int): QuerySeq = filter(c ⇒ c.email === email && c.accountId =!= accountId && !c.isBlacklisted && !c.isDisabled) - } def findOneByAccountId(accountId: Int): DBIO[Option[User]] = filter(_.accountId === accountId).result.headOption @@ -145,8 +138,7 @@ object Users extends FoxTableQuery[User, Users](new Users(_)) with ReturningId[U def createEmailMustBeUnique(email: String)(implicit ec: EC): DbResultT[Unit] = findNonGuestByEmail(email).one.mustNotFindOr(UserEmailNotUnique) - def updateEmailMustBeUnique(maybeEmail: Option[String], accountId: Int)( - implicit ec: EC): DbResultT[Unit] = + def updateEmailMustBeUnique(maybeEmail: Option[String], accountId: Int)(implicit ec: EC): DbResultT[Unit] = maybeEmail match { case Some(email) ⇒ otherUserByEmail(email, accountId).one.mustNotFindOr(UserEmailNotUnique) diff --git a/phoenix-scala/phoenix/app/phoenix/models/account/UserPasswordReset.scala b/phoenix-scala/phoenix/app/phoenix/models/account/UserPasswordReset.scala index f28ac62ee3..069235f478 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/account/UserPasswordReset.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/account/UserPasswordReset.scala @@ -40,15 +40,13 @@ object UserPasswordReset { implicit val stateColumnType: JdbcType[State] with BaseTypedType[State] = State.slickColumn - def optionFromUser(user: User): Option[UserPasswordReset] = { + def optionFromUser(user: User): Option[UserPasswordReset] = user.email.map { email ⇒ UserPasswordReset(accountId = user.accountId, code = generateUuid, email = email) } - } } -class UserPasswordResets(tag: Tag) - extends FoxTable[UserPasswordReset](tag, "user_password_resets") { +class UserPasswordResets(tag: Tag) extends FoxTable[UserPasswordReset](tag, "user_password_resets") { import UserPasswordReset._ @@ -62,7 +60,7 @@ class UserPasswordResets(tag: Tag) def * = (id, accountId, email, state, code, activatedAt, createdAt) <> ((UserPasswordReset.apply _).tupled, - UserPasswordReset.unapply) + UserPasswordReset.unapply) } object UserPasswordResets diff --git a/phoenix-scala/phoenix/app/phoenix/models/activity/Activity.scala b/phoenix-scala/phoenix/app/phoenix/models/activity/Activity.scala index 47845b3989..0ce3a56636 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/activity/Activity.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/activity/Activity.scala @@ -31,8 +31,8 @@ object ActivityContext { implicit val ActivityContextColumn: JdbcType[ActivityContext] with BaseTypedType[ActivityContext] = { implicit val formats = JsonFormatters.phoenixFormats MappedColumnType.base[ActivityContext, Json]( - c ⇒ Extraction.decompose(c), - j ⇒ j.extract[ActivityContext] + c ⇒ Extraction.decompose(c), + j ⇒ j.extract[ActivityContext] ) } } @@ -146,18 +146,21 @@ object Activities extends LazyLogging { ec: EC): Unit = { val msg = new ProducerRecord[GenericData.Record, GenericData.Record](topic, key, record) - activityContext.producer.send(msg, new Callback { - // we force logging to be done in `ec` execution context - // instead of a kafka background thread that executes callbacks - def onCompletion(metadata: RecordMetadata, exception: Exception): Unit = Future { - if (metadata ne null) - logger.info( + activityContext.producer.send( + msg, + new Callback { + // we force logging to be done in `ec` execution context + // instead of a kafka background thread that executes callbacks + def onCompletion(metadata: RecordMetadata, exception: Exception): Unit = Future { + if (metadata ne null) + logger.info( s"Kafka Activity ${a.activityType} by ${activityContext.ctx.userType} ${activityContext.ctx.userId} SUCCESS") - else - logger.error( + else + logger.error( s"Kafka Activity ${a.activityType} by ${activityContext.ctx.userType} ${activityContext.ctx.userId} FAILURE", exception) + } } - }) + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/activity/Dimension.scala b/phoenix-scala/phoenix/app/phoenix/models/activity/Dimension.scala index 4c56aa25cf..50a1a9afab 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/activity/Dimension.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/activity/Dimension.scala @@ -11,7 +11,7 @@ import slick.lifted.Tag /** * An activity dimension has a set of activity trails. It is used as a logical grouping - * of trails by some 'kind' of activity. A particular activity can be in multiple dimensions + * of trails by some 'kind' of activity. A particular activity can be in multiple dimensions * at a time. */ case class Dimension(id: Int = 0, name: String, description: String) @@ -20,9 +20,8 @@ case class Dimension(id: Int = 0, name: String, description: String) val nameRegex = """([a-zA-Z0-9-_]*)""".r - override def validate: ValidatedNel[Failure, Dimension] = { + override def validate: ValidatedNel[Failure, Dimension] = matches(name, nameRegex, "name").map { case _ ⇒ this } - } } object Dimension { diff --git a/phoenix-scala/phoenix/app/phoenix/models/admin/AdminData.scala b/phoenix-scala/phoenix/app/phoenix/models/admin/AdminData.scala index 56e7ba9e18..00cf301239 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/admin/AdminData.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/admin/AdminData.scala @@ -29,9 +29,9 @@ case class AdminData(id: Int = 0, def stateLens = lens[AdminData].state val fsm: Map[State, Set[State]] = Map( - Invited → Set(Active, Inactive, Archived), - Active → Set(Inactive, Archived), - Inactive → Set(Active, Archived) + Invited → Set(Active, Inactive, Archived), + Active → Set(Inactive, Archived), + Inactive → Set(Active, Archived) ) private val canLoginWithStates = Set(Active, Invited) diff --git a/phoenix-scala/phoenix/app/phoenix/models/auth/Credentials.scala b/phoenix-scala/phoenix/app/phoenix/models/auth/Credentials.scala index bdeb02d074..cdd90c712a 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/auth/Credentials.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/auth/Credentials.scala @@ -15,10 +15,12 @@ object Credentials { def mustVerifyJWTCredentials(cred: Option[HttpCredentials], or: Failures): Either[Failures, JWTCredentials] = - cred.flatMap { - // assume it's JWT - // passing scheme as argument where we expect token is not a typo - case GenericHttpCredentials(scheme, token, params) ⇒ Some(JWTCredentials(scheme)) - case _ ⇒ None - }.toEither(or) + cred + .flatMap { + // assume it's JWT + // passing scheme as argument where we expect token is not a typo + case GenericHttpCredentials(scheme, token, params) ⇒ Some(JWTCredentials(scheme)) + case _ ⇒ None + } + .toEither(or) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/auth/Token.scala b/phoenix-scala/phoenix/app/phoenix/models/auth/Token.scala index 3641cc4d71..6d1e1e72a6 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/auth/Token.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/auth/Token.scala @@ -25,14 +25,13 @@ object Keys { case class KeyLoadException(cause: Throwable) extends Exception - private def loadKeyAsStream(fileName: String): InputStream = { + private def loadKeyAsStream(fileName: String): InputStream = config.auth.keysLocation match { case FoxConfig.KeysLocation.Jar ⇒ getClass.getResourceAsStream(fileName) case FoxConfig.KeysLocation.File ⇒ new FileInputStream(fileName) } - } def loadPrivateKey: Try[PrivateKey] = Try { val fileName = config.auth.privateKey @@ -75,9 +74,8 @@ sealed trait Token extends Product { val ratchet: Int def encode: Either[Failures, String] = Token.encode(this) - def hasRole(test: String): Boolean = { + def hasRole(test: String): Boolean = roles.contains(test) - } def hasClaim(test: String, actions: List[String]): Boolean = { var matches = false; @@ -91,9 +89,8 @@ sealed trait Token extends Product { object Token { implicit val formats = DefaultFormats - val algorithmConstraints = new AlgorithmConstraints( - AlgorithmConstraints.ConstraintType.WHITELIST, - config.auth.keyAlgorithm) + val algorithmConstraints = + new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, config.auth.keyAlgorithm) import collection.JavaConversions.seqAsJavaList @@ -134,7 +131,7 @@ object Token { encodeJWTClaims(claims) } - def encodeJWTClaims(claims: JwtClaims): Either[Failures, String] = { + def encodeJWTClaims(claims: JwtClaims): Either[Failures, String] = Keys.authPrivateKey.map { privateKey ⇒ val jws = new JsonWebSignature jws.setPayload(claims.toJson) @@ -142,9 +139,8 @@ object Token { jws.setAlgorithmHeaderValue(config.auth.keyAlgorithm) jws.getCompactSerialization } - } - def fromString(rawToken: String, kind: Identity.IdentityKind): Either[Failures, Token] = { + def fromString(rawToken: String, kind: Identity.IdentityKind): Either[Failures, Token] = Keys.authPublicKey.flatMap { publicKey ⇒ val builder = new JwtConsumerBuilder() .setRequireExpirationTime() @@ -166,7 +162,6 @@ object Token { Either.left(AuthFailed(e.getMessage).single) } } - } } case class UserToken(id: Int, diff --git a/phoenix-scala/phoenix/app/phoenix/models/category/IlluminatedCategory.scala b/phoenix-scala/phoenix/app/phoenix/models/category/IlluminatedCategory.scala index 3279c1390a..6c48b69ef7 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/category/IlluminatedCategory.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/category/IlluminatedCategory.scala @@ -6,7 +6,7 @@ import phoenix.utils.aliases._ /** * An IlluminatedCategory is what you get when you combine the category shadow and - * the form. + * the form. */ case class IlluminatedCategory(id: Int, context: IlluminatedContext, attributes: Json) diff --git a/phoenix-scala/phoenix/app/phoenix/models/category/package.scala b/phoenix-scala/phoenix/app/phoenix/models/category/package.scala index 267219f6ef..0ebe56ab18 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/category/package.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/category/package.scala @@ -4,8 +4,5 @@ import objectframework.models.{ObjectContext, ObjectForm, ObjectShadow} package object category { - case class CategoryFull(context: ObjectContext, - category: Category, - form: ObjectForm, - shadow: ObjectShadow) + case class CategoryFull(context: ObjectContext, category: Category, form: ObjectForm, shadow: ObjectShadow) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala index 9d5b43752a..c5e59e88cf 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/AmazonOrder.scala @@ -26,18 +26,20 @@ case class AmazonOrder(id: Int, object AmazonOrder { def build(payload: CreateAmazonOrderPayload, accountId: Int)(implicit ec: EC): AmazonOrder = - AmazonOrder(id = 0, - amazonOrderId = payload.amazonOrderId, - orderTotal = payload.orderTotal, - paymentMethodDetail = payload.paymentMethodDetail, - orderType = payload.orderType, - currency = payload.currency, - orderStatus = payload.orderStatus, - purchaseDate = payload.purchaseDate, - scope = payload.scope, - accountId = accountId, - createdAt = Instant.now, - updatedAt = Instant.now) + AmazonOrder( + id = 0, + amazonOrderId = payload.amazonOrderId, + orderTotal = payload.orderTotal, + paymentMethodDetail = payload.paymentMethodDetail, + orderType = payload.orderType, + currency = payload.currency, + orderStatus = payload.orderStatus, + purchaseDate = payload.purchaseDate, + scope = payload.scope, + accountId = accountId, + createdAt = Instant.now, + updatedAt = Instant.now + ) } object AmazonOrders @@ -50,8 +52,7 @@ object AmazonOrders filter(_.amazonOrderId === amazonOrderId).one def mustFindOneOr(amazonOrderId: String)(implicit ec: EC): DbResultT[AmazonOrder] = - findOneByAmazonOrderId(amazonOrderId).mustFindOr( - NotFoundFailure404(AmazonOrder, amazonOrderId)) + findOneByAmazonOrderId(amazonOrderId).mustFindOr(NotFoundFailure404(AmazonOrder, amazonOrderId)) } class AmazonOrders(tag: Tag) extends FoxTable[AmazonOrder](tag, "amazon_orders") { diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/Cord.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/Cord.scala index 098783b703..85bca04848 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/Cord.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/Cord.scala @@ -4,8 +4,7 @@ import core.db._ import shapeless._ import slick.jdbc.PostgresProfile.api._ -case class Cord(id: Int = 0, referenceNumber: String = "", isCart: Boolean = true) - extends FoxModel[Cord] +case class Cord(id: Int = 0, referenceNumber: String = "", isCart: Boolean = true) extends FoxModel[Cord] object Cord { def cordRefNumRegex = """([a-zA-Z0-9-_]*)""".r diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/Order.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/Order.scala index 105b8951f6..a55e0bfeab 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/Order.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/Order.scala @@ -48,14 +48,14 @@ case class Order(id: Int = 0, import Order._ val fsm: Map[State, Set[State]] = Map( - FraudHold → - Set(ManualHold, RemorseHold, FulfillmentStarted, Canceled), - RemorseHold → - Set(FraudHold, ManualHold, FulfillmentStarted, Canceled), - ManualHold → - Set(FraudHold, RemorseHold, FulfillmentStarted, Canceled), - FulfillmentStarted → - Set(Shipped, Canceled) + FraudHold → + Set(ManualHold, RemorseHold, FulfillmentStarted, Canceled), + RemorseHold → + Set(FraudHold, ManualHold, FulfillmentStarted, Canceled), + ManualHold → + Set(FraudHold, RemorseHold, FulfillmentStarted, Canceled), + FulfillmentStarted → + Set(Shipped, Canceled) ) // If order is not in RemorseHold, remorsePeriodEnd should be None, but extra check wouldn't hurt @@ -72,7 +72,7 @@ case class Order(id: Int = 0, } object Order { - sealed trait State extends Product with Serializable + sealed trait State extends Product with Serializable case object FraudHold extends State case object RemorseHold extends State case object ManualHold extends State @@ -128,14 +128,13 @@ object Orders with ReturningTableQuery[Order, Orders] with SearchByRefNum[Order, Orders] { - def createFromCart( - cart: Cart, - subScope: Option[String])(implicit ec: EC, db: DB, ctx: OC, au: AU): DbResultT[Order] = + def createFromCart(cart: Cart, + subScope: Option[String])(implicit ec: EC, db: DB, ctx: OC, au: AU): DbResultT[Order] = createFromCart(cart, ctx.id, subScope) - def createFromCart(cart: Cart, - contextId: Int, - subScope: Option[String])(implicit ec: EC, db: DB, au: AU): DbResultT[Order] = + def createFromCart(cart: Cart, contextId: Int, subScope: Option[String])(implicit ec: EC, + db: DB, + au: AU): DbResultT[Order] = for { scope ← * <~ Scope.resolveOverride(subScope) @@ -145,23 +144,24 @@ object Orders lineItems ← * <~ prepareOrderLineItemsFromCart(cart, contextId) order ← * <~ Orders.create( - Order(referenceNumber = cart.referenceNumber, - accountId = cart.accountId, - scope = scope, - currency = cart.currency, - subTotal = cart.subTotal, - shippingTotal = cart.shippingTotal, - adjustmentsTotal = cart.adjustmentsTotal, - taxesTotal = cart.taxesTotal, - grandTotal = cart.grandTotal, - contextId = contextId)) + Order( + referenceNumber = cart.referenceNumber, + accountId = cart.accountId, + scope = scope, + currency = cart.currency, + subTotal = cart.subTotal, + shippingTotal = cart.shippingTotal, + adjustmentsTotal = cart.adjustmentsTotal, + taxesTotal = cart.taxesTotal, + grandTotal = cart.grandTotal, + contextId = contextId + )) _ ← * <~ OrderLineItems.createAll(lineItems) } yield order - def prepareOrderLineItemsFromCart(cart: Cart, contextId: Int)( - implicit ec: EC, - db: DB): DbResultT[Seq[OrderLineItem]] = { + def prepareOrderLineItemsFromCart(cart: Cart, contextId: Int)(implicit ec: EC, + db: DB): DbResultT[Seq[OrderLineItem]] = { val uniqueSkuIdsInCart = CartLineItems.byCordRef(cart.referenceNumber).groupBy(_.skuId).map { case (skuId, q) ⇒ skuId } @@ -177,12 +177,14 @@ object Orders lineItems ← * <~ CartLineItems.byCordRef(cart.referenceNumber).result orderLineItems ← * <~ lineItems.map { cli ⇒ val sku = skuMaps.get(cli.skuId).get - OrderLineItem(cordRef = cart.referenceNumber, - referenceNumber = cli.referenceNumber, - skuId = sku.id, - skuShadowId = sku.shadowId, - state = OrderLineItem.Pending, - attributes = cli.attributes) + OrderLineItem( + cordRef = cart.referenceNumber, + referenceNumber = cli.referenceNumber, + skuId = sku.id, + skuShadowId = sku.shadowId, + state = OrderLineItem.Pending, + attributes = cli.attributes + ) } } yield orderLineItems } @@ -209,7 +211,8 @@ object Orders type PackedRet = (Rep[Int], Rep[String], Rep[Option[Instant]]) private val rootLens = lens[Order] - val returningLens: Lens[Order, (Int, String, Option[Instant])] = rootLens.id ~ rootLens.referenceNumber ~ rootLens.remorsePeriodEnd + val returningLens + : Lens[Order, (Int, String, Option[Instant])] = rootLens.id ~ rootLens.referenceNumber ~ rootLens.remorsePeriodEnd override val returningQuery = map { o ⇒ (o.id, o.referenceNumber, o.remorsePeriodEnd) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/OrderPayment.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/OrderPayment.scala index 3ffdcb206c..60a6ce13cc 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/OrderPayment.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/OrderPayment.scala @@ -53,15 +53,11 @@ case class OrderPayment(id: Int = 0, } } -case class StripeOrderPayment(stripeChargeId: String, - amount: Long, - currency: Currency = Currency.USD) +case class StripeOrderPayment(stripeChargeId: String, amount: Long, currency: Currency = Currency.USD) object OrderPayment { def fromStripeCustomer(stripeCustomer: StripeCustomer, cart: Cart): OrderPayment = - OrderPayment(cordRef = cart.refNum, - paymentMethodId = 1, - paymentMethodType = PaymentMethod.CreditCard) + OrderPayment(cordRef = cart.refNum, paymentMethodId = 1, paymentMethodType = PaymentMethod.CreditCard) def build(method: PaymentMethod): OrderPayment = method match { case gc: GiftCard ⇒ @@ -86,7 +82,7 @@ class OrderPayments(tag: Tag) extends FoxTable[OrderPayment](tag, "order_payment def * = (id, cordRef, amount, currency, paymentMethodId, paymentMethodType) <> ((OrderPayment.apply _).tupled, - OrderPayment.unapply) + OrderPayment.unapply) def order = foreignKey(Carts.tableName, cordRef, Carts)(_.referenceNumber) def creditCard = foreignKey(CreditCards.tableName, paymentMethodId, CreditCards)(_.id) @@ -133,8 +129,7 @@ object OrderPayments def findAllExternalPayments(cordRef: String): QuerySeq = findAllByCordRef(cordRef).externalPayments - def findAllStripeCharges( - cordRef: Rep[String]): Query[Rep[StripeOrderPayment], StripeOrderPayment, Seq] = { + def findAllStripeCharges(cordRef: Rep[String]): Query[Rep[StripeOrderPayment], StripeOrderPayment, Seq] = { def ccCharges = filter(_.cordRef === cordRef).join(CreditCardCharges).on(_.paymentMethodId === _.id).map { case (_, charge) ⇒ diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/OrderPromotion.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/OrderPromotion.scala index 8b27b0ecaa..b9656fe135 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/OrderPromotion.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/OrderPromotion.scala @@ -22,9 +22,7 @@ final case class OrderPromotion(id: Int = 0, object OrderPromotion { def buildAuto(cart: Cart, promo: Promotion): OrderPromotion = - OrderPromotion(cordRef = cart.refNum, - promotionShadowId = promo.shadowId, - applyType = Promotion.Auto) + OrderPromotion(cordRef = cart.refNum, promotionShadowId = promo.shadowId, applyType = Promotion.Auto) def buildCoupon(cart: Cart, promo: Promotion, code: CouponCode): OrderPromotion = OrderPromotion(cordRef = cart.refNum, @@ -43,7 +41,7 @@ class OrderPromotions(tag: Tag) extends FoxTable[OrderPromotion](tag, "order_pro def * = (id, cordRef, promotionShadowId, applyType, couponCodeId, createdAt) <> ((OrderPromotion.apply _).tupled, - OrderPromotion.unapply) + OrderPromotion.unapply) def order = foreignKey(Carts.tableName, cordRef, Carts)(_.referenceNumber) def promotionShadow = foreignKey(ObjectShadows.tableName, promotionShadowId, ObjectShadows)(_.id) diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/OrderShippingAddress.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/OrderShippingAddress.scala index 6d801bade0..7866ee50ea 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/OrderShippingAddress.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/OrderShippingAddress.scala @@ -34,27 +34,28 @@ case class OrderShippingAddress(id: Int = 0, object OrderShippingAddress { def buildFromAddress(address: Address): OrderShippingAddress = // FIXME: Add Address#id to OrderShippingAddress? @michalrus - OrderShippingAddress(regionId = address.regionId, - name = address.name, - address1 = address.address1, - address2 = address.address2, - city = address.city, - zip = address.zip, - phoneNumber = address.phoneNumber) - - def fromPatchPayload(a: OrderShippingAddress, p: UpdateAddressPayload) = { OrderShippingAddress( - id = a.id, - cordRef = a.cordRef, - regionId = p.regionId.getOrElse(a.regionId), - name = p.name.getOrElse(a.name), - address1 = p.address1.getOrElse(a.address1), - address2 = p.address2.fold(a.address2)(Some(_)), - city = p.city.getOrElse(a.city), - zip = p.zip.getOrElse(a.zip), - phoneNumber = p.phoneNumber.fold(a.phoneNumber)(Some(_)) + regionId = address.regionId, + name = address.name, + address1 = address.address1, + address2 = address.address2, + city = address.city, + zip = address.zip, + phoneNumber = address.phoneNumber + ) + + def fromPatchPayload(a: OrderShippingAddress, p: UpdateAddressPayload) = + OrderShippingAddress( + id = a.id, + cordRef = a.cordRef, + regionId = p.regionId.getOrElse(a.regionId), + name = p.name.getOrElse(a.name), + address1 = p.address1.getOrElse(a.address1), + address2 = p.address2.fold(a.address2)(Some(_)), + city = p.city.getOrElse(a.city), + zip = p.zip.getOrElse(a.zip), + phoneNumber = p.phoneNumber.fold(a.phoneNumber)(Some(_)) ) - } } class OrderShippingAddresses(tag: Tag) @@ -79,16 +80,14 @@ class OrderShippingAddresses(tag: Tag) } object OrderShippingAddresses - extends FoxTableQuery[OrderShippingAddress, OrderShippingAddresses]( - new OrderShippingAddresses(_)) + extends FoxTableQuery[OrderShippingAddress, OrderShippingAddresses](new OrderShippingAddresses(_)) with ReturningId[OrderShippingAddress, OrderShippingAddresses] { val returningLens: Lens[OrderShippingAddress, Int] = lens[OrderShippingAddress].id import scope._ - def copyFromAddress(address: Address, cordRef: String)( - implicit ec: EC): DbResultT[OrderShippingAddress] = + def copyFromAddress(address: Address, cordRef: String)(implicit ec: EC): DbResultT[OrderShippingAddress] = create(OrderShippingAddress.buildFromAddress(address).copy(cordRef = cordRef)) def findByOrderRef(cordRef: String): QuerySeq = diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/OrderShippingMethod.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/OrderShippingMethod.scala index 02c74dbe6c..35016ef19c 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/OrderShippingMethod.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/OrderShippingMethod.scala @@ -13,8 +13,7 @@ object OrderShippingMethod { OrderShippingMethod(cordRef = cordRef, shippingMethodId = method.id, price = method.price) } -class OrderShippingMethods(tag: Tag) - extends FoxTable[OrderShippingMethod](tag, "order_shipping_methods") { +class OrderShippingMethods(tag: Tag) extends FoxTable[OrderShippingMethod](tag, "order_shipping_methods") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def cordRef = column[String]("cord_ref") def shippingMethodId = column[Int]("shipping_method_id") diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/lineitems/CartLineItemAdjustment.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/lineitems/CartLineItemAdjustment.scala index 3bc1d5b131..715405adb0 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/lineitems/CartLineItemAdjustment.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/lineitems/CartLineItemAdjustment.scala @@ -45,11 +45,13 @@ object CartLineItemAdjustment { case object Combinator extends AdjustmentType def fromOfferResult(offerResult: OfferResult) = - CartLineItemAdjustment(cordRef = offerResult.discountInput.cartRefNum, - promotionShadowId = offerResult.discountInput.promotionShadowId, - adjustmentType = adjustmentTypeByOffer(offerResult.offerType), - subtract = offerResult.subtract, - lineItemRefNum = offerResult.lineItemRefNum) + CartLineItemAdjustment( + cordRef = offerResult.discountInput.cartRefNum, + promotionShadowId = offerResult.discountInput.promotionShadowId, + adjustmentType = adjustmentTypeByOffer(offerResult.offerType), + subtract = offerResult.subtract, + lineItemRefNum = offerResult.lineItemRefNum + ) def adjustmentTypeByOffer(offerType: OfferType): AdjustmentType = offerType match { case ItemPercentOff | ItemAmountOff ⇒ LineItemAdjustment @@ -64,13 +66,12 @@ object CartLineItemAdjustment { def types = sealerate.values[AdjustmentType] } - implicit val adjustmentTypeColumnType: JdbcType[AdjustmentType] with BaseTypedType[ - AdjustmentType] = AdjustmentType.slickColumn + implicit val adjustmentTypeColumnType: JdbcType[AdjustmentType] with BaseTypedType[AdjustmentType] = + AdjustmentType.slickColumn } object CartLineItemAdjustments - extends FoxTableQuery[CartLineItemAdjustment, CartLineItemAdjustments]( - new CartLineItemAdjustments(_)) + extends FoxTableQuery[CartLineItemAdjustment, CartLineItemAdjustments](new CartLineItemAdjustments(_)) with ReturningId[CartLineItemAdjustment, CartLineItemAdjustments] { val returningLens: Lens[CartLineItemAdjustment, Int] = lens[CartLineItemAdjustment].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/cord/lineitems/OrderLineItem.scala b/phoenix-scala/phoenix/app/phoenix/models/cord/lineitems/OrderLineItem.scala index 12a5c96a33..588edd8f06 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/cord/lineitems/OrderLineItem.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/cord/lineitems/OrderLineItem.scala @@ -68,14 +68,14 @@ case class OrderLineItem(id: Int = 0, super.transitionModel(newModel) val fsm: Map[State, Set[State]] = Map( - OLI.Cart → - Set(Pending, PreOrdered, BackOrdered, Canceled), - Pending → - Set(Shipped, Canceled), - PreOrdered → - Set(Shipped, Canceled), - BackOrdered → - Set(Shipped, Canceled) + OLI.Cart → + Set(Pending, PreOrdered, BackOrdered, Canceled), + Pending → + Set(Shipped, Canceled), + PreOrdered → + Set(Shipped, Canceled), + BackOrdered → + Set(Shipped, Canceled) ) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/coupon/Coupon.scala b/phoenix-scala/phoenix/app/phoenix/models/coupon/Coupon.scala index f26b018204..0866f52d0c 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/coupon/Coupon.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/coupon/Coupon.scala @@ -40,21 +40,10 @@ class Coupons(tag: Tag) extends ObjectHeads[Coupon](tag, "coupons") { def promotionId = column[Int]("promotion_id") def * = - (id, - scope, - promotionId, - contextId, - shadowId, - formId, - commitId, - updatedAt, - createdAt, - archivedAt) <> ((Coupon.apply _).tupled, Coupon.unapply) + (id, scope, promotionId, contextId, shadowId, formId, commitId, updatedAt, createdAt, archivedAt) <> ((Coupon.apply _).tupled, Coupon.unapply) } -object Coupons - extends ObjectHeadsQueries[Coupon, Coupons](new Coupons(_)) - with ReturningId[Coupon, Coupons] { +object Coupons extends ObjectHeadsQueries[Coupon, Coupons](new Coupons(_)) with ReturningId[Coupon, Coupons] { val returningLens: Lens[Coupon, Int] = lens[Coupon].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/coupon/CouponCode.scala b/phoenix-scala/phoenix/app/phoenix/models/coupon/CouponCode.scala index 1a36ac2028..2e24942885 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/coupon/CouponCode.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/coupon/CouponCode.scala @@ -13,10 +13,7 @@ import scala.util.Random * A coupon code is a way to reference a coupon from the outside world. * Multiple codes may point to the same coupon. */ -case class CouponCode(id: Int = 0, - code: String, - couponFormId: Int, - createdAt: Instant = Instant.now) +case class CouponCode(id: Int = 0, code: String, couponFormId: Int, createdAt: Instant = Instant.now) extends FoxModel[CouponCode] class CouponCodes(tag: Tag) extends FoxTable[CouponCode](tag, "coupon_codes") { @@ -51,10 +48,7 @@ object CouponCodes requestedLimit >= prefixSize + minSuffixSize } - def generateCodes(prefix: String, - codeCharacterLength: Int, - quantity: Int, - attempt: Int = 0): Seq[String] = { + def generateCodes(prefix: String, codeCharacterLength: Int, quantity: Int, attempt: Int = 0): Seq[String] = { require(quantity > 0) val minNumericLength = charactersGivenQuantity(quantity) @@ -110,15 +104,12 @@ object CouponCodes collectCodes() } - private def generateCode(prefix: String, - number: Int, - largestNum: Int, - numericLength: Int): String = { + private def generateCode(prefix: String, number: Int, largestNum: Int, numericLength: Int): String = { require(numericLength >= 0) require(largestNum >= 0) require(number <= largestNum) val num = s"%0${numericLength}d".format(number) - s"${prefix}${num}" + s"$prefix$num" } private val rootLens = lens[CouponCode] diff --git a/phoenix-scala/phoenix/app/phoenix/models/coupon/CouponCustomerUsage.scala b/phoenix-scala/phoenix/app/phoenix/models/coupon/CouponCustomerUsage.scala index 5e2382cb62..8ce8a7f030 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/coupon/CouponCustomerUsage.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/coupon/CouponCustomerUsage.scala @@ -17,8 +17,7 @@ final case class CouponCustomerUsage(id: Int = 0, createdAt: Instant = Instant.now) extends FoxModel[CouponCustomerUsage] -class CouponCustomerUsages(tag: Tag) - extends FoxTable[CouponCustomerUsage](tag, "coupon_customer_usages") { +class CouponCustomerUsages(tag: Tag) extends FoxTable[CouponCustomerUsage](tag, "coupon_customer_usages") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def couponFormId = column[Int]("coupon_form_id") diff --git a/phoenix-scala/phoenix/app/phoenix/models/coupon/IlluminatedCoupon.scala b/phoenix-scala/phoenix/app/phoenix/models/coupon/IlluminatedCoupon.scala index 8b25513f62..5fcb933b30 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/coupon/IlluminatedCoupon.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/coupon/IlluminatedCoupon.scala @@ -16,10 +16,7 @@ import phoenix.utils.aliases._ * An IlluminatedCoupon is what you get when you combine the coupon shadow and * the form. */ -case class IlluminatedCoupon(id: Int, - context: IlluminatedContext, - attributes: Json, - promotion: Int) { +case class IlluminatedCoupon(id: Int, context: IlluminatedContext, attributes: Json, promotion: Int) { implicit val formats = JsonFormatters.phoenixFormats @@ -76,12 +73,11 @@ object IlluminatedCoupon { def illuminate(context: ObjectContext, coupon: Coupon, form: ObjectForm, - shadow: ObjectShadow): IlluminatedCoupon = { - - IlluminatedCoupon(id = coupon.formId, - promotion = coupon.promotionId, - context = IlluminatedContext(context.name, context.attributes), - attributes = - IlluminateAlgorithm.projectAttributes(form.attributes, shadow.attributes)) - } + shadow: ObjectShadow): IlluminatedCoupon = + IlluminatedCoupon( + id = coupon.formId, + promotion = coupon.promotionId, + context = IlluminatedContext(context.name, context.attributes), + attributes = IlluminateAlgorithm.projectAttributes(form.attributes, shadow.attributes) + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerData.scala b/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerData.scala index 91d2f7d79f..7f72f23a96 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerData.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerData.scala @@ -32,7 +32,7 @@ class CustomersData(tag: Tag) extends FoxTable[CustomerData](tag, "customer_data def * = (id, userId, scope, accountId, isGuest, createdAt, updatedAt, deletedAt) <> ((CustomerData.apply _).tupled, - CustomerData.unapply) + CustomerData.unapply) } object CustomersData @@ -50,15 +50,10 @@ object CustomersData * - billingRegion comes from default creditCard of customer * - rank is calculated as percentile from net revenue */ - def withRegionsAndRank: Query[(CustomersData, - Rep[Option[Regions]], - Rep[Option[Regions]], - Rep[Option[CustomersRanks]]), - (CustomerData, - Option[Region], - Option[Region], - Option[CustomerRank]), - Seq] = { + def withRegionsAndRank + : Query[(CustomersData, Rep[Option[Regions]], Rep[Option[Regions]], Rep[Option[CustomersRanks]]), + (CustomerData, Option[Region], Option[Region], Option[CustomerRank]), + Seq] = { val customerWithShipRegion = for { ((c, a), r) ← query @@ -91,9 +86,8 @@ object CustomersData } } - def findGuests(email: String): DBIO[Option[CustomerData]] = { + def findGuests(email: String): DBIO[Option[CustomerData]] = filter(_.isGuest === true).one - } def findOneByAccountId(accountId: Int): DBIO[Option[CustomerData]] = filter(_.accountId === accountId).result.headOption diff --git a/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroup.scala b/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroup.scala index 37814210e6..d04f09df38 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroup.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroup.scala @@ -31,19 +31,15 @@ case class CustomerGroup(id: Int = 0, deletedAt: Option[Instant] = None) extends FoxModel[CustomerGroup] { - def mustBeOfType(expected: GroupType): Either[Failures, CustomerGroup] = { + def mustBeOfType(expected: GroupType): Either[Failures, CustomerGroup] = if (groupType == expected) Either.right(this) else Either.left(CustomerGroupTypeIsWrong(id, groupType, Set(expected)).single) - } - def mustNotBeOfType(expectedNot: GroupType): Either[Failures, CustomerGroup] = { + def mustNotBeOfType(expectedNot: GroupType): Either[Failures, CustomerGroup] = if (groupType != expectedNot) Either.right(this) else Either.left( - CustomerGroupTypeIsWrong(id, - groupType, - CustomerGroup.types.filterNot(_ == expectedNot).toSet).single) - } + CustomerGroupTypeIsWrong(id, groupType, CustomerGroup.types.filterNot(_ == expectedNot).toSet).single) } @@ -64,14 +60,16 @@ object CustomerGroup { GroupType.slickColumn def fromPayloadAndAdmin(p: CustomerGroupPayload, adminId: Int, scope: LTree): CustomerGroup = - CustomerGroup(id = 0, - scope = scope, - createdBy = adminId, - name = p.name, - customersCount = p.customersCount, - clientState = p.clientState, - elasticRequest = p.elasticRequest, - groupType = p.groupType) + CustomerGroup( + id = 0, + scope = scope, + createdBy = adminId, + name = p.name, + customersCount = p.customersCount, + clientState = p.clientState, + elasticRequest = p.elasticRequest, + groupType = p.groupType + ) } class CustomerGroups(tag: Tag) extends FoxTable[CustomerGroup](tag, "customer_groups") { diff --git a/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroupMember.scala b/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroupMember.scala index f4ef179d97..1961dff640 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroupMember.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroupMember.scala @@ -13,8 +13,7 @@ case class CustomerGroupMember(id: Int = 0, createdAt: Instant = Instant.now) extends FoxModel[CustomerGroupMember] -class CustomerGroupMembers(tag: Tag) - extends FoxTable[CustomerGroupMember](tag, "customer_group_members") { +class CustomerGroupMembers(tag: Tag) extends FoxTable[CustomerGroupMember](tag, "customer_group_members") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def groupId = column[Int]("group_id") diff --git a/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroupTemplate.scala b/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroupTemplate.scala index 540d37cbfc..f75629f14f 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroupTemplate.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/customer/CustomerGroupTemplate.scala @@ -6,10 +6,7 @@ import slick.lifted.Tag import core.db.ExPostgresDriver.api._ import core.db._ -case class CustomerGroupTemplate(id: Int = 0, - name: String, - clientState: Json, - elasticRequest: Json) +case class CustomerGroupTemplate(id: Int = 0, name: String, clientState: Json, elasticRequest: Json) extends FoxModel[CustomerGroupTemplate] class CustomerGroupTemplates(tag: Tag) @@ -25,8 +22,7 @@ class CustomerGroupTemplates(tag: Tag) } object CustomerGroupTemplates - extends FoxTableQuery[CustomerGroupTemplate, CustomerGroupTemplates]( - new CustomerGroupTemplates(_)) + extends FoxTableQuery[CustomerGroupTemplate, CustomerGroupTemplates](new CustomerGroupTemplates(_)) with ReturningId[CustomerGroupTemplate, CustomerGroupTemplates] { val returningLens: Lens[CustomerGroupTemplate, Int] = lens[CustomerGroupTemplate].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/customer/GroupTemplateInstance.scala b/phoenix-scala/phoenix/app/phoenix/models/customer/GroupTemplateInstance.scala index ccf0320b99..565521e8ec 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/customer/GroupTemplateInstance.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/customer/GroupTemplateInstance.scala @@ -27,8 +27,7 @@ class GroupTemplateInstances(tag: Tag) } object GroupTemplateInstances - extends FoxTableQuery[GroupTemplateInstance, GroupTemplateInstances]( - new GroupTemplateInstances(_)) + extends FoxTableQuery[GroupTemplateInstance, GroupTemplateInstances](new GroupTemplateInstances(_)) with ReturningId[GroupTemplateInstance, GroupTemplateInstances] { def findByScope(scope: LTree): QuerySeq = filter(_.scope === scope) diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/Discount.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/Discount.scala index 3fd7473a35..86255aabac 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/Discount.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/Discount.scala @@ -17,13 +17,13 @@ object Discount { * A Discount allows the customer to help sell a product by providing an incentive * such as price reductions. The discount is composed of three parts. * - * 1. Merchandising + * 1. Merchandising * 2. Qualifier * 3. Offer * * The qualifier and offer are stored as attributes in the discount object and * are stored as a JSON representation of the AST for the Discount Algebra. - * + * * The algebra is used to define the qualifier predicate and offer function. * used by the discount engine to modify an order by creating line item adjustments. */ @@ -47,7 +47,7 @@ class Discounts(tag: Tag) extends ObjectHeads[Discount](tag, "discounts") { def * = (id, scope, contextId, shadowId, formId, commitId, updatedAt, createdAt, archivedAt) <> ((Discount.apply _).tupled, - Discount.unapply) + Discount.unapply) } object Discounts diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/DiscountHelpers.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/DiscountHelpers.scala index 107949a55a..cfb1560252 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/DiscountHelpers.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/DiscountHelpers.scala @@ -6,11 +6,9 @@ import phoenix.utils.aliases._ object DiscountHelpers { - def offer(form: ObjectForm, shadow: ObjectShadow): Json = { + def offer(form: ObjectForm, shadow: ObjectShadow): Json = ObjectUtils.get("offer", form, shadow) - } - def qualifier(form: ObjectForm, shadow: ObjectShadow): Json = { + def qualifier(form: ObjectForm, shadow: ObjectShadow): Json = ObjectUtils.get("qualifier", form, shadow) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/DiscountValidator.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/DiscountValidator.scala index eaead67273..89cb69c2e7 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/DiscountValidator.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/DiscountValidator.scala @@ -17,10 +17,9 @@ object DiscountValidator { def validate(fs: FormAndShadow)(implicit ec: EC): DbResultT[Unit] = for { - failures ← * <~ IlluminateAlgorithm.validateAttributes(fs.form.attributes, - fs.shadow.attributes) - _ ← * <~ failIfFailures(failures) - _ ← * <~ QualifierAstCompiler(qualifier(fs.form, fs.shadow)).compile() - _ ← * <~ OfferAstCompiler(offer(fs.form, fs.shadow)).compile() + failures ← * <~ IlluminateAlgorithm.validateAttributes(fs.form.attributes, fs.shadow.attributes) + _ ← * <~ failIfFailures(failures) + _ ← * <~ QualifierAstCompiler(qualifier(fs.form, fs.shadow)).compile() + _ ← * <~ OfferAstCompiler(offer(fs.form, fs.shadow)).compile() } yield None } diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/IlluminatedDiscount.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/IlluminatedDiscount.scala index 52d2fa3516..b81b4eeffb 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/IlluminatedDiscount.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/IlluminatedDiscount.scala @@ -6,7 +6,7 @@ import phoenix.utils.aliases._ /** * An IlluminatedDiscount is what you get when you combine the discount shadow and - * the form. + * the form. */ case class IlluminatedDiscount(id: Int, context: Option[IlluminatedContext], attributes: Json) @@ -14,11 +14,10 @@ object IlluminatedDiscount { def illuminate(context: Option[ObjectContext] = None, form: ObjectForm, - shadow: ObjectShadow): IlluminatedDiscount = { - + shadow: ObjectShadow): IlluminatedDiscount = IlluminatedDiscount( - id = form.id, //Id points to form since that is constant across contexts - context = context.map(c ⇒ IlluminatedContext(c.name, c.attributes)), - attributes = IlluminateAlgorithm.projectAttributes(form.attributes, shadow.attributes)) - } + id = form.id, //Id points to form since that is constant across contexts + context = context.map(c ⇒ IlluminatedContext(c.name, c.attributes)), + attributes = IlluminateAlgorithm.projectAttributes(form.attributes, shadow.attributes) + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/SearchReference.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/SearchReference.scala index fd42ec0410..7122281066 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/SearchReference.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/SearchReference.scala @@ -51,16 +51,14 @@ sealed trait SearchReference[T] { trait SearchBuckets extends SearchReference[Buckets] { def pureResult(implicit ec: EC): Result[Buckets] = pureBuckets - def esSearch(searchView: SearchView, query: Json, refs: Seq[String])( - implicit apis: Apis): Future[Buckets] = + def esSearch(searchView: SearchView, query: Json, refs: Seq[String])(implicit apis: Apis): Future[Buckets] = apis.elasticSearch.checkBuckets(searchView, query, fieldName, refs) } trait SearchMetrics extends SearchReference[Long] { def pureResult(implicit ec: EC): Result[Long] = pureMetrics - def esSearch(searchView: SearchView, query: Json, refs: Seq[String])( - implicit apis: Apis): Future[Long] = + def esSearch(searchView: SearchView, query: Json, refs: Seq[String])(implicit apis: Apis): Future[Long] = apis.elasticSearch.checkMetrics(searchView, query, fieldName, refs) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/offers/ItemsAmountOffer.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/offers/ItemsAmountOffer.scala index d332021674..d62794a732 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/offers/ItemsAmountOffer.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/offers/ItemsAmountOffer.scala @@ -26,14 +26,13 @@ case class ItemsAmountOffer(discount: Long, search: Seq[ProductSearch]) either match { case Right(buckets) ⇒ val matchedFormIds = buckets.filter(_.docCount > 0).map(_.key) - val offerResults = input.lineItems.filter { data ⇒ - matchedFormIds.contains(data.productId.toString) - }.map { data ⇒ - OfferResult(input, - subtract(data.price, discount), - data.lineItemReferenceNumber.some, - offerType) - } + val offerResults = input.lineItems + .filter { data ⇒ + matchedFormIds.contains(data.productId.toString) + } + .map { data ⇒ + OfferResult(input, subtract(data.price, discount), data.lineItemReferenceNumber.some, offerType) + } Either.right(offerResults) case _ ⇒ pureEither() diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/offers/ItemsPercentOffer.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/offers/ItemsPercentOffer.scala index e18999b96a..c8f6aeaadb 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/offers/ItemsPercentOffer.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/offers/ItemsPercentOffer.scala @@ -26,14 +26,13 @@ case class ItemsPercentOffer(discount: Long, search: Seq[ProductSearch]) either match { case Right(buckets) ⇒ val matchedFormIds = buckets.filter(_.docCount > 0).map(_.key) - val offerResults = input.lineItems.filter { data ⇒ - matchedFormIds.contains(data.productId.toString) - }.map { data ⇒ - OfferResult(input, - subtract(data.price, discount), - data.lineItemReferenceNumber.some, - offerType) - } + val offerResults = input.lineItems + .filter { data ⇒ + matchedFormIds.contains(data.productId.toString) + } + .map { data ⇒ + OfferResult(input, subtract(data.price, discount), data.lineItemReferenceNumber.some, offerType) + } Either.right(offerResults) case _ ⇒ pureEither() diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/offers/Offer.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/offers/Offer.scala index 774758becc..88aaa60c22 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/offers/Offer.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/offers/Offer.scala @@ -72,13 +72,10 @@ trait SetOffer { trait ItemsOffer { - def matchEither(input: DiscountInput)(either: Either[Failures, Buckets]) - : Either[Failures, Seq[OfferResult]] // FIXME: why use matchEither instead of .map, if *never* do anything with Left? @michalrus + def matchEither(input: DiscountInput)(either: Either[Failures, Buckets]): Either[Failures, Seq[OfferResult]] // FIXME: why use matchEither instead of .map, if *never* do anything with Left? @michalrus - def adjustInner(input: DiscountInput)(search: Seq[ProductSearch])( - implicit db: DB, - ec: EC, - apis: Apis): Result[Seq[OfferResult]] = { + def adjustInner(input: DiscountInput)( + search: Seq[ProductSearch])(implicit db: DB, ec: EC, apis: Apis): Result[Seq[OfferResult]] = { val inAnyOf = search.map(_.query(input).mapEither(matchEither(input))) Result.onlySuccessful(inAnyOf.toList).map(_.headOption.getOrElse(Seq.empty)) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/offers/SetPriceOffer.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/offers/SetPriceOffer.scala index c2ceece250..2528104662 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/offers/SetPriceOffer.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/offers/SetPriceOffer.scala @@ -20,8 +20,7 @@ case class SetPriceOffer(setPrice: Long, numUnits: Int, search: Seq[ProductSearc def adjust(input: DiscountInput)(implicit db: DB, ec: EC, apis: Apis): Result[Seq[OfferResult]] = if (setPrice > 0 && numUnits < 100) adjustInner(input)(search) else pureResult() - def matchEither(input: DiscountInput)( - xor: Either[Failures, Buckets]): Either[Failures, Seq[OfferResult]] = + def matchEither(input: DiscountInput)(xor: Either[Failures, Buckets]): Either[Failures, Seq[OfferResult]] = xor match { case Right(buckets) ⇒ val matchedFormIds = buckets.filter(_.docCount > 0).map(_.key) @@ -29,10 +28,7 @@ case class SetPriceOffer(setPrice: Long, numUnits: Int, search: Seq[ProductSearc .filter(data ⇒ matchedFormIds.contains(data.productId.toString)) .take(numUnits) .map { data ⇒ - OfferResult(input, - subtract(data.price, setPrice), - data.lineItemReferenceNumber.some, - offerType) + OfferResult(input, subtract(data.price, setPrice), data.lineItemReferenceNumber.some, offerType) } Either.right(adjustments) diff --git a/phoenix-scala/phoenix/app/phoenix/models/discount/qualifiers/ItemsAnyQualifier.scala b/phoenix-scala/phoenix/app/phoenix/models/discount/qualifiers/ItemsAnyQualifier.scala index c2bdfe7fdc..7667a77fc1 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/discount/qualifiers/ItemsAnyQualifier.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/discount/qualifiers/ItemsAnyQualifier.scala @@ -19,12 +19,12 @@ case class ItemsAnyQualifier(search: Seq[ProductSearch]) def check(input: DiscountInput)(implicit db: DB, ec: EC, apis: Apis, au: AU): Result[Unit] = checkInner(input)(search) - def matchEither(input: DiscountInput)( - either: Either[Failures, Buckets]): Either[Failures, Unit] = either match { - case Right(buckets) ⇒ - val bucketDocCount = buckets.map(_.docCount).sum - if (bucketDocCount > 0) Either.right(Unit) else Either.left(SearchFailure.single) - case _ ⇒ - Either.left(SearchFailure.single) - } + def matchEither(input: DiscountInput)(either: Either[Failures, Buckets]): Either[Failures, Unit] = + either match { + case Right(buckets) ⇒ + val bucketDocCount = buckets.map(_.docCount).sum + if (bucketDocCount > 0) Either.right(Unit) else Either.left(SearchFailure.single) + case _ ⇒ + Either.left(SearchFailure.single) + } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/image/Album.scala b/phoenix-scala/phoenix/app/phoenix/models/image/Album.scala index cbe0fc4fef..a85045ca5a 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/image/Album.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/image/Album.scala @@ -34,10 +34,9 @@ case class Album(id: Int = 0, def withNewShadowAndCommit(shadowId: Int, commitId: Int): Album = this.copy(shadowId = shadowId, commitId = commitId) - def mustNotBeArchived: Either[Failures, Album] = { + def mustNotBeArchived: Either[Failures, Album] = if (archivedAt.isEmpty) Either.right(this) else Either.left(AddImagesToArchivedAlbumFailure(id).single) - } } class Albums(tag: Tag) extends ObjectHeads[Album](tag, "albums") { diff --git a/phoenix-scala/phoenix/app/phoenix/models/image/AlbumImagesLink.scala b/phoenix-scala/phoenix/app/phoenix/models/image/AlbumImagesLink.scala index 369c4c288c..2342d50214 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/image/AlbumImagesLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/image/AlbumImagesLink.scala @@ -19,8 +19,7 @@ case class AlbumImageLink(id: Int = 0, override def withPosition(newPosition: Id): AlbumImageLink = copy(position = newPosition) } -class AlbumImageLinks(tag: Tag) - extends OrderedObjectHeadLinks[AlbumImageLink](tag, "album_image_links") { +class AlbumImageLinks(tag: Tag) extends OrderedObjectHeadLinks[AlbumImageLink](tag, "album_image_links") { def * = (id, leftId, rightId, position, createdAt, updatedAt, archivedAt) <> ((AlbumImageLink.apply _).tupled, AlbumImageLink.unapply) @@ -31,9 +30,9 @@ class AlbumImageLinks(tag: Tag) object AlbumImageLinks extends OrderedObjectHeadLinkQueries[AlbumImageLink, AlbumImageLinks, Album, Image]( - new AlbumImageLinks(_), - Albums, - Images) + new AlbumImageLinks(_), + Albums, + Images) with ReturningId[AlbumImageLink, AlbumImageLinks] { val returningLens: Lens[AlbumImageLink, Int] = lens[AlbumImageLink].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/inventory/IlluminatedSku.scala b/phoenix-scala/phoenix/app/phoenix/models/inventory/IlluminatedSku.scala index ef2e71dbaa..d88ab2233d 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/inventory/IlluminatedSku.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/inventory/IlluminatedSku.scala @@ -10,7 +10,7 @@ import phoenix.utils.aliases._ /** * An IlluminatedSku is what you get when you combine the sku shadow and - * the sku. + * the sku. */ case class IlluminatedSku(id: Int, code: String, @@ -29,10 +29,12 @@ object IlluminatedSku { val formAttrs = sku.form.attributes val shadowAttrs = sku.shadow.attributes - IlluminatedSku(id = sku.form.id, - code = model.code, - archivedAt = model.archivedAt, - context = IlluminatedContext(context.name, context.attributes), - attributes = IlluminateAlgorithm.projectAttributes(formAttrs, shadowAttrs)) + IlluminatedSku( + id = sku.form.id, + code = model.code, + archivedAt = model.archivedAt, + context = IlluminatedContext(context.name, context.attributes), + attributes = IlluminateAlgorithm.projectAttributes(formAttrs, shadowAttrs) + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/inventory/Sku.scala b/phoenix-scala/phoenix/app/phoenix/models/inventory/Sku.scala index dd7c6acec7..fbde8ab7bc 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/inventory/Sku.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/inventory/Sku.scala @@ -40,10 +40,9 @@ case class Sku(id: Int = 0, def withNewShadowAndCommit(shadowId: Int, commitId: Int): Sku = this.copy(shadowId = shadowId, commitId = commitId) - def mustNotBeArchived[T](target: T, targetId: Any): Either[Failures, Sku] = { + def mustNotBeArchived[T](target: T, targetId: Any): Either[Failures, Sku] = if (archivedAt.isEmpty) Either.right(this) else Either.left(LinkInactiveSkuFailure(target, targetId, code).single) - } def mustNotBePresentInCarts(implicit ec: EC, db: DB): DbResultT[Unit] = for { diff --git a/phoenix-scala/phoenix/app/phoenix/models/inventory/SkuValidator.scala b/phoenix-scala/phoenix/app/phoenix/models/inventory/SkuValidator.scala index 33bd4e1121..c31ddbd3f2 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/inventory/SkuValidator.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/inventory/SkuValidator.scala @@ -13,7 +13,6 @@ object SkuValidator { implicit val formats: Formats = JsonFormatters.phoenixFormats - def validate(form: ObjectForm, shadow: ObjectShadow): Seq[Failure] = { + def validate(form: ObjectForm, shadow: ObjectShadow): Seq[Failure] = IlluminateAlgorithm.validateAttributes(form.attributes, shadow.attributes) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/location/Address.scala b/phoenix-scala/phoenix/app/phoenix/models/location/Address.scala index e671e0fb01..670500b844 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/location/Address.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/location/Address.scala @@ -63,14 +63,16 @@ object Address { phoneNumber = osa.phoneNumber) def fromCreditCard(cc: CreditCard): Address = - Address(accountId = 0, - regionId = cc.address.regionId, - name = cc.address.name, - address1 = cc.address.address1, - address2 = cc.address.address2, - city = cc.address.city, - zip = cc.address.zip, - phoneNumber = cc.address.phoneNumber) + Address( + accountId = 0, + regionId = cc.address.regionId, + name = cc.address.name, + address1 = cc.address.address1, + address2 = cc.address.address2, + city = cc.address.city, + zip = cc.address.zip, + phoneNumber = cc.address.phoneNumber + ) } class Addresses(tag: Tag) extends FoxTable[Address](tag, "addresses") { @@ -87,17 +89,7 @@ class Addresses(tag: Tag) extends FoxTable[Address](tag, "addresses") { def deletedAt = column[Option[Instant]]("deleted_at") def * = - (id, - accountId, - regionId, - name, - address1, - address2, - city, - zip, - isDefaultShipping, - phoneNumber, - deletedAt) <> ((Address.apply _).tupled, Address.unapply) + (id, accountId, regionId, name, address1, address2, city, zip, isDefaultShipping, phoneNumber, deletedAt) <> ((Address.apply _).tupled, Address.unapply) def region = foreignKey(Regions.tableName, regionId, Regions)(_.id) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/location/Country.scala b/phoenix-scala/phoenix/app/phoenix/models/location/Country.scala index 843cda83d1..02a15c3694 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/location/Country.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/location/Country.scala @@ -37,17 +37,7 @@ class Countries(tag: Tag) extends FoxTable[Country](tag, "countries") { def isBillable = column[Boolean]("is_billable") def * = - (id, - name, - alpha2, - alpha3, - code, - continent, - currency, - languages, - usesPostalCode, - isShippable, - isBillable) <> ((Country.apply _).tupled, Country.unapply) + (id, name, alpha2, alpha3, code, continent, currency, languages, usesPostalCode, isShippable, isBillable) <> ((Country.apply _).tupled, Country.unapply) } object Countries @@ -57,6 +47,5 @@ object Countries // Query for both 2- and 3-lettered code for convenience @aafa def findByCode(code: String): QuerySeq = - filter( - c ⇒ c.alpha2.toUpperCase === code.toUpperCase || c.alpha3.toUpperCase === code.toUpperCase) + filter(c ⇒ c.alpha2.toUpperCase === code.toUpperCase || c.alpha3.toUpperCase === code.toUpperCase) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/location/Region.scala b/phoenix-scala/phoenix/app/phoenix/models/location/Region.scala index 2f7212bdc4..52e26018de 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/location/Region.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/location/Region.scala @@ -28,9 +28,7 @@ class Regions(tag: Tag) extends FoxTable[Region](tag, "regions") { def country = foreignKey(Countries.tableName, countryId, Countries)(_.id) } -object Regions - extends FoxTableQuery[Region, Regions](new Regions(_)) - with ReturningId[Region, Regions] { +object Regions extends FoxTableQuery[Region, Regions](new Regions(_)) with ReturningId[Region, Regions] { val returningLens: Lens[Region, Int] = lens[Region].id def findOneByShortName(regionShortName: String) = diff --git a/phoenix-scala/phoenix/app/phoenix/models/objects/ProductAlbumLink.scala b/phoenix-scala/phoenix/app/phoenix/models/objects/ProductAlbumLink.scala index bea210dda6..7351c51140 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/objects/ProductAlbumLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/objects/ProductAlbumLink.scala @@ -33,9 +33,9 @@ class ProductAlbumLinks(tag: Tag) object ProductAlbumLinks extends OrderedObjectHeadLinkQueries[ProductAlbumLink, ProductAlbumLinks, Product, Album]( - new ProductAlbumLinks(_), - Products, - Albums) + new ProductAlbumLinks(_), + Products, + Albums) with ReturningId[ProductAlbumLink, ProductAlbumLinks] { val returningLens: Lens[ProductAlbumLink, Int] = lens[ProductAlbumLink].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/objects/ProductSkuLink.scala b/phoenix-scala/phoenix/app/phoenix/models/objects/ProductSkuLink.scala index 4b8fbb7d1b..7e5a6242d3 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/objects/ProductSkuLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/objects/ProductSkuLink.scala @@ -28,10 +28,9 @@ class ProductSkuLinks(tag: Tag) extends ObjectHeadLinks[ProductSkuLink](tag, "pr } object ProductSkuLinks - extends ObjectHeadLinkQueries[ProductSkuLink, ProductSkuLinks, Product, Sku]( - new ProductSkuLinks(_), - Products, - Skus) + extends ObjectHeadLinkQueries[ProductSkuLink, ProductSkuLinks, Product, Sku](new ProductSkuLinks(_), + Products, + Skus) with ReturningId[ProductSkuLink, ProductSkuLinks] { val returningLens: Lens[ProductSkuLink, Int] = lens[ProductSkuLink].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/objects/ProductVariantLink.scala b/phoenix-scala/phoenix/app/phoenix/models/objects/ProductVariantLink.scala index f8b4bd973c..80b25b0d64 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/objects/ProductVariantLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/objects/ProductVariantLink.scala @@ -29,9 +29,9 @@ class ProductVariantLinks(tag: Tag) object ProductVariantLinks extends ObjectHeadLinkQueries[ProductVariantLink, ProductVariantLinks, Product, Variant]( - new ProductVariantLinks(_), - Products, - Variants) + new ProductVariantLinks(_), + Products, + Variants) with ReturningId[ProductVariantLink, ProductVariantLinks] { val returningLens: Lens[ProductVariantLink, Int] = lens[ProductVariantLink].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/objects/PromotionDiscountLink.scala b/phoenix-scala/phoenix/app/phoenix/models/objects/PromotionDiscountLink.scala index 6a42407065..6242d04726 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/objects/PromotionDiscountLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/objects/PromotionDiscountLink.scala @@ -29,10 +29,10 @@ class PromotionDiscountLinks(tag: Tag) } object PromotionDiscountLinks - extends ObjectHeadLinkQueries[PromotionDiscountLink, - PromotionDiscountLinks, - Promotion, - Discount](new PromotionDiscountLinks(_), Promotions, Discounts) + extends ObjectHeadLinkQueries[PromotionDiscountLink, PromotionDiscountLinks, Promotion, Discount]( + new PromotionDiscountLinks(_), + Promotions, + Discounts) with ReturningId[PromotionDiscountLink, PromotionDiscountLinks] { val returningLens: Lens[PromotionDiscountLink, Int] = lens[PromotionDiscountLink].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/objects/SkuAlbumLink.scala b/phoenix-scala/phoenix/app/phoenix/models/objects/SkuAlbumLink.scala index c30fa96a97..300e49f3e3 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/objects/SkuAlbumLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/objects/SkuAlbumLink.scala @@ -21,8 +21,7 @@ case class SkuAlbumLink(id: Int = 0, override def withPosition(newPosition: Id): SkuAlbumLink = copy(position = newPosition) } -class SkuAlbumLinks(tag: Tag) - extends OrderedObjectHeadLinks[SkuAlbumLink](tag, "sku_album_links") { +class SkuAlbumLinks(tag: Tag) extends OrderedObjectHeadLinks[SkuAlbumLink](tag, "sku_album_links") { def * = (id, leftId, rightId, position, createdAt, updatedAt, archivedAt) <> ((SkuAlbumLink.apply _).tupled, SkuAlbumLink.unapply) @@ -32,10 +31,9 @@ class SkuAlbumLinks(tag: Tag) } object SkuAlbumLinks - extends OrderedObjectHeadLinkQueries[SkuAlbumLink, SkuAlbumLinks, Sku, Album]( - new SkuAlbumLinks(_), - Skus, - Albums) + extends OrderedObjectHeadLinkQueries[SkuAlbumLink, SkuAlbumLinks, Sku, Album](new SkuAlbumLinks(_), + Skus, + Albums) with ReturningId[SkuAlbumLink, SkuAlbumLinks] { val returningLens: Lens[SkuAlbumLink, Int] = lens[SkuAlbumLink].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/objects/TaxonProductLink.scala b/phoenix-scala/phoenix/app/phoenix/models/objects/TaxonProductLink.scala index f8338dcb12..6eb34d2d76 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/objects/TaxonProductLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/objects/TaxonProductLink.scala @@ -18,8 +18,7 @@ case class ProductTaxonLink(id: Int = 0, extends FoxModel[ProductTaxonLink] with ObjectHeadLink[ProductTaxonLink] -class ProductTaxonLinks(tag: Tag) - extends ObjectHeadLinks[ProductTaxonLink](tag, "product_taxon_links") { +class ProductTaxonLinks(tag: Tag) extends ObjectHeadLinks[ProductTaxonLink](tag, "product_taxon_links") { def * = (id, leftId, rightId, createdAt, updatedAt, archivedAt) <> ((ProductTaxonLink.apply _).tupled, ProductTaxonLink.unapply) @@ -30,9 +29,9 @@ class ProductTaxonLinks(tag: Tag) object ProductTaxonLinks extends ObjectHeadLinkQueries[ProductTaxonLink, ProductTaxonLinks, Product, Taxon]( - new ProductTaxonLinks(_), - Products, - Taxons) + new ProductTaxonLinks(_), + Products, + Taxons) with ReturningId[ProductTaxonLink, ProductTaxonLinks] { val returningLens: Lens[ProductTaxonLink, Int] = lens[ProductTaxonLink].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/objects/VariantValueLink.scala b/phoenix-scala/phoenix/app/phoenix/models/objects/VariantValueLink.scala index ad733519ea..ec18595124 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/objects/VariantValueLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/objects/VariantValueLink.scala @@ -29,9 +29,9 @@ class VariantValueLinks(tag: Tag) object VariantValueLinks extends ObjectHeadLinkQueries[VariantValueLink, VariantValueLinks, Variant, VariantValue]( - new VariantValueLinks(_), - Variants, - VariantValues) + new VariantValueLinks(_), + Variants, + VariantValues) with ReturningId[VariantValueLink, VariantValueLinks] { val returningLens: Lens[VariantValueLink, Int] = lens[VariantValueLink].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/ExternalCharge.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/ExternalCharge.scala index 5241dcbc8f..b51a3b53b7 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/ExternalCharge.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/ExternalCharge.scala @@ -16,8 +16,7 @@ trait ExternalChargeVals { trait ExternalCharge[Model <: FoxModel[Model] with FSM[ExternalCharge.State, Model]] extends FoxModel[Model] with ExternalChargeVals - with FSM[ExternalCharge.State, Model] { - self: Model ⇒ + with FSM[ExternalCharge.State, Model] { self: Model ⇒ import ExternalCharge._ override def updateTo(newModel: Model): Either[Failures, Model] = @@ -26,12 +25,12 @@ trait ExternalCharge[Model <: FoxModel[Model] with FSM[ExternalCharge.State, Mod def updateModelState(s: State)(implicit ec: EC): DbResultT[Unit] val fsm: Map[State, Set[State]] = Map( - Cart → - Set(Auth), - Auth → - Set(FullCapture, FailedCapture, CanceledAuth, ExpiredAuth), - ExpiredAuth → - Set(Auth) + Cart → + Set(Auth), + Auth → + Set(FullCapture, FailedCapture, CanceledAuth, ExpiredAuth), + ExpiredAuth → + Set(Auth) ) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/InStorePaymentAdjustment.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/InStorePaymentAdjustment.scala index 63099ee2c2..8ad09d0501 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/InStorePaymentAdjustment.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/InStorePaymentAdjustment.scala @@ -40,8 +40,7 @@ object InStorePaymentStates { implicit val stateColumnType: JdbcType[State] with BaseTypedType[State] = State.slickColumn } -abstract class InStorePaymentAdjustmentTable[M <: InStorePaymentAdjustment[M]](tag: Tag, - table: String) +abstract class InStorePaymentAdjustmentTable[M <: InStorePaymentAdjustment[M]](tag: Tag, table: String) extends FoxTable[M](tag, table) { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) @@ -56,7 +55,7 @@ abstract class InStorePaymentAdjustmentTable[M <: InStorePaymentAdjustment[M]](t } abstract class InStorePaymentAdjustmentQueries[M <: InStorePaymentAdjustment[M], - T <: InStorePaymentAdjustmentTable[M]](construct: Tag ⇒ T) +T <: InStorePaymentAdjustmentTable[M]](construct: Tag ⇒ T) extends FoxTableQuery[M, T](construct) { def cancel(id: Int): DBIO[Int] = filter(_.id === id).map(_.state).update(Canceled) diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/applepay/ApplePayCharge.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/applepay/ApplePayCharge.scala index 17b71420f7..3f9c9ba04d 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/applepay/ApplePayCharge.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/applepay/ApplePayCharge.scala @@ -6,7 +6,7 @@ import phoenix.models.cord.OrderPayment import phoenix.models.payment.ExternalCharge._ import phoenix.models.payment.ExternalCharge import phoenix.utils.aliases.stripe.StripeCharge -import shapeless.{Lens, lens} +import shapeless.{lens, Lens} import slick.jdbc.PostgresProfile.api._ import slick.lifted._ import core.utils.Money.Currency @@ -49,10 +49,7 @@ object ApplePayCharges extends FoxTableQuery[ApplePayCharge, ApplePayCharges](new ApplePayCharges(_)) with ReturningId[ApplePayCharge, ApplePayCharges] { - def authFromStripe(ap: ApplePayment, - pmt: OrderPayment, - stripeCharge: StripeCharge, - currency: Currency) = + def authFromStripe(ap: ApplePayment, pmt: OrderPayment, stripeCharge: StripeCharge, currency: Currency) = ApplePayCharge(orderPaymentId = pmt.id, stripeChargeId = stripeCharge.getId, state = Auth, diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/applepay/ApplePayment.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/applepay/ApplePayment.scala index 4f01e6620f..a4e3db7450 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/applepay/ApplePayment.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/applepay/ApplePayment.scala @@ -8,7 +8,7 @@ import core.db._ import core.failures.Failure import core.utils.Validation import phoenix.models.payment.PaymentMethod -import shapeless.{Lens, lens} +import shapeless.{lens, Lens} import slick.jdbc.PostgresProfile.api._ case class ApplePayment( @@ -24,11 +24,11 @@ case class ApplePayment( import Validation._ - override def validate: ValidatedNel[Failure, ApplePayment] = { - (validExpr(stripeTokenId.startsWith("tok_"), "Stripe token should start with 'tok_'") |@| super.validate).map { - case _ ⇒ this - } - } + override def validate: ValidatedNel[Failure, ApplePayment] = + (validExpr(stripeTokenId.startsWith("tok_"), "Stripe token should start with 'tok_'") |@| super.validate) + .map { + case _ ⇒ this + } } class ApplePayments(tag: Tag) extends FoxTable[ApplePayment](tag, "apple_payments") { diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/creditcard/CreditCard.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/creditcard/CreditCard.scala index e80a8115a1..6cb6ceaafa 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/creditcard/CreditCard.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/creditcard/CreditCard.scala @@ -51,18 +51,17 @@ case class CreditCard(id: Int = 0, import Validation._ - override def validate: ValidatedNel[Failure, CreditCard] = { + override def validate: ValidatedNel[Failure, CreditCard] = (address.validate |@| matches(lastFour, "[0-9]{4}", "lastFour") |@| notExpired( - expYear, - expMonth, - "credit card is expired") |@| withinNumberOfYears( - expYear, - expMonth, - 20, - "credit card expiration is too far in the future") |@| super.validate).map { + expYear, + expMonth, + "credit card is expired") |@| withinNumberOfYears( + expYear, + expMonth, + 20, + "credit card expiration is too far in the future") |@| super.validate).map { case _ ⇒ this } - } def mustBeInWallet: Either[Failures, CreditCard] = if (inWallet) Either.right(this) else Either.left(CannotUseInactiveCreditCard(this).single) @@ -73,12 +72,12 @@ case class CreditCard(id: Int = 0, def copyFromAddress(address: Address): CreditCard = this.copy( - address = this.address.copy(regionId = address.regionId, - name = address.name, - address1 = address.address1, - address2 = address.address2, - city = address.city, - zip = address.zip)) + address = this.address.copy(regionId = address.regionId, + name = address.name, + address1 = address.address1, + address2 = address.address2, + city = address.city, + zip = address.zip)) } object CreditCard { @@ -87,45 +86,52 @@ object CreditCard { cardToken: String, payload: CreateCreditCardFromTokenPayload, address: Address): CreditCard = - CreditCard(accountId = accountId, - gatewayCustomerId = customerToken, - gatewayCardId = cardToken, - brand = payload.brand, - lastFour = payload.lastFour, - expMonth = payload.expMonth, - expYear = payload.expYear, - holderName = payload.holderName, - address = BillingAddress(name = address.name, - regionId = address.regionId, - address1 = address.address1, - address2 = address.address2, - zip = address.zip, - city = address.city, - phoneNumber = address.phoneNumber)) + CreditCard( + accountId = accountId, + gatewayCustomerId = customerToken, + gatewayCardId = cardToken, + brand = payload.brand, + lastFour = payload.lastFour, + expMonth = payload.expMonth, + expYear = payload.expYear, + holderName = payload.holderName, + address = BillingAddress( + name = address.name, + regionId = address.regionId, + address1 = address.address1, + address2 = address.address2, + zip = address.zip, + city = address.city, + phoneNumber = address.phoneNumber + ) + ) @deprecated(message = "Use `buildFromToken` instead", "Until we are PCI compliant") def buildFromSource(accountId: Int, sCust: StripeCustomer, card: StripeCard, cardPayload: CreateCreditCardFromSourcePayload, - address: Address): CreditCard = { - CreditCard(accountId = accountId, - gatewayCustomerId = sCust.getId, - gatewayCardId = card.getId, - holderName = cardPayload.holderName, - lastFour = cardPayload.lastFour, - expMonth = cardPayload.expMonth, - expYear = cardPayload.expYear, - isDefault = cardPayload.isDefault, - brand = card.getBrand, - address = BillingAddress(regionId = address.regionId, - name = address.name, - address1 = address.address1, - address2 = address.address2, - city = address.city, - zip = address.zip, - phoneNumber = address.phoneNumber)) - } + address: Address): CreditCard = + CreditCard( + accountId = accountId, + gatewayCustomerId = sCust.getId, + gatewayCardId = card.getId, + holderName = cardPayload.holderName, + lastFour = cardPayload.lastFour, + expMonth = cardPayload.expMonth, + expYear = cardPayload.expYear, + isDefault = cardPayload.isDefault, + brand = card.getBrand, + address = BillingAddress( + regionId = address.regionId, + name = address.name, + address1 = address.address1, + address2 = address.address2, + city = address.city, + zip = address.zip, + phoneNumber = address.phoneNumber + ) + ) } class CreditCards(tag: Tag) extends FoxTable[CreditCard](tag, "credit_cards") { @@ -184,40 +190,42 @@ class CreditCards(tag: Tag) extends FoxTable[CreditCard](tag, "credit_cards") { brand, address, createdAt) ⇒ - CreditCard(id, - parentId, - accountId, - gatewayCustomerId, - gatewayCardId, - holderName, - lastFour, - expMonth, - expYear, - isDefault, - inWallet, - deletedAt, - brand, - BillingAddress.tupled.apply(address), - createdAt) + CreditCard( + id, + parentId, + accountId, + gatewayCustomerId, + gatewayCardId, + holderName, + lastFour, + expMonth, + expYear, + isDefault, + inWallet, + deletedAt, + brand, + BillingAddress.tupled.apply(address), + createdAt + ) }, { c: CreditCard ⇒ { def address(a: BillingAddress) = BillingAddress.unapply(a).get Some( - (c.id, - c.parentId, - c.accountId, - c.gatewayCustomerId, - c.gatewayCardId, - c.holderName, - c.lastFour, - c.expMonth, - c.expYear, - c.isDefault, - c.inWallet, - c.deletedAt, - c.brand, - address(c.address), - c.createdAt)) + (c.id, + c.parentId, + c.accountId, + c.gatewayCustomerId, + c.gatewayCardId, + c.holderName, + c.lastFour, + c.expMonth, + c.expYear, + c.isDefault, + c.inWallet, + c.deletedAt, + c.brand, + address(c.address), + c.createdAt)) } }) @@ -240,10 +248,9 @@ object CreditCards def findByIdAndAccountId(id: Int, accountId: Int): QuerySeq = filter(_.accountId === accountId).filter(_.id === id) - def mustFindByIdAndAccountId(id: Int, accountId: Int)(implicit ec: EC): DbResultT[CreditCard] = { + def mustFindByIdAndAccountId(id: Int, accountId: Int)(implicit ec: EC): DbResultT[CreditCard] = filter(cc ⇒ cc.id === id && cc.accountId === accountId).one.dbresult.flatMap { case Some(cc) ⇒ DbResultT.good(cc) case None ⇒ DbResultT.failure(NotFoundFailure404(CreditCard, id)) } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCard.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCard.scala index cc84fa3cef..1b71a20fac 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCard.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCard.scala @@ -66,11 +66,10 @@ case class GiftCard(id: Int = 0, } (canceledWithReason - // |@| notEmpty(code, "code") // FIXME: this check does not allow to create models - |@| validExpr(originalBalance >= 0, - "originalBalance should be greater or equal than zero") |@| validExpr( - currentBalance >= 0, - "currentBalance should be greater or equal than zero")).map { + // |@| notEmpty(code, "code") // FIXME: this check does not allow to create models + |@| validExpr(originalBalance >= 0, "originalBalance should be greater or equal than zero") |@| validExpr( + currentBalance >= 0, + "currentBalance should be greater or equal than zero")).map { case _ ⇒ this } } @@ -81,9 +80,9 @@ case class GiftCard(id: Int = 0, super.transitionModel(newModel) val fsm: Map[State, Set[State]] = Map( - OnHold → Set(Active, Canceled), - Active → Set(OnHold, Canceled), - Cart → Set(Canceled) + OnHold → Set(Active, Canceled), + Active → Set(OnHold, Canceled), + Cart → Set(Canceled) ) def isActive: Boolean = state == Active @@ -129,88 +128,81 @@ object GiftCard { val giftCardCodeRegex = """([a-zA-Z0-9-_]*)""".r - def build(balance: Long, originId: Int, currency: Currency)(implicit au: AU): GiftCard = { + def build(balance: Long, originId: Int, currency: Currency)(implicit au: AU): GiftCard = GiftCard( - scope = Scope.current, - originId = originId, - originType = GiftCard.CustomerPurchase, - state = GiftCard.Active, - currency = currency, - originalBalance = balance, - availableBalance = balance, - currentBalance = balance + scope = Scope.current, + originId = originId, + originType = GiftCard.CustomerPurchase, + state = GiftCard.Active, + currency = currency, + originalBalance = balance, + availableBalance = balance, + currentBalance = balance ) - } - def buildAppeasement(payload: GiftCardCreateByCsr, originId: Int, scope: LTree): GiftCard = { + def buildAppeasement(payload: GiftCardCreateByCsr, originId: Int, scope: LTree): GiftCard = GiftCard( - scope = scope, - originId = originId, - originType = GiftCard.CsrAppeasement, - subTypeId = payload.subTypeId, - state = GiftCard.Active, - currency = payload.currency, - originalBalance = payload.balance, - availableBalance = payload.balance, - currentBalance = payload.balance + scope = scope, + originId = originId, + originType = GiftCard.CsrAppeasement, + subTypeId = payload.subTypeId, + state = GiftCard.Active, + currency = payload.currency, + originalBalance = payload.balance, + availableBalance = payload.balance, + currentBalance = payload.balance ) - } - def buildByCustomerPurchase(payload: GiftCardCreatedByCustomer, - originId: Int, - scope: LTree): GiftCard = { + def buildByCustomerPurchase(payload: GiftCardCreatedByCustomer, originId: Int, scope: LTree): GiftCard = { val message: Option[String] = payload.message.flatMap(msg ⇒ if (msg.trim.isEmpty) None else Option(msg.trim)) GiftCard( - scope = scope, - originId = originId, - originType = GiftCard.CustomerPurchase, - subTypeId = payload.subTypeId, - state = GiftCard.Active, - currency = payload.currency, - originalBalance = payload.balance, - availableBalance = payload.balance, - currentBalance = payload.balance, - senderName = payload.senderName.some, - recipientName = payload.recipientName.some, - recipientEmail = payload.recipientEmail.some, - message = message + scope = scope, + originId = originId, + originType = GiftCard.CustomerPurchase, + subTypeId = payload.subTypeId, + state = GiftCard.Active, + currency = payload.currency, + originalBalance = payload.balance, + availableBalance = payload.balance, + currentBalance = payload.balance, + senderName = payload.senderName.some, + recipientName = payload.recipientName.some, + recipientEmail = payload.recipientEmail.some, + message = message ) } - def buildScTransfer(balance: Long, originId: Int, currency: Currency, scope: LTree): GiftCard = { + def buildScTransfer(balance: Long, originId: Int, currency: Currency, scope: LTree): GiftCard = GiftCard( - scope = scope, - originId = originId, - originType = GiftCard.FromStoreCredit, - state = GiftCard.Active, - currency = currency, - originalBalance = balance, - availableBalance = balance, - currentBalance = balance + scope = scope, + originId = originId, + originType = GiftCard.FromStoreCredit, + state = GiftCard.Active, + currency = currency, + originalBalance = balance, + availableBalance = balance, + currentBalance = balance ) - } - def buildLineItem(balance: Long, originId: Int, currency: Currency)(implicit au: AU): GiftCard = { + def buildLineItem(balance: Long, originId: Int, currency: Currency)(implicit au: AU): GiftCard = GiftCard( - scope = Scope.current, - originId = originId, - originType = GiftCard.CustomerPurchase, - state = GiftCard.Cart, - currency = currency, - originalBalance = balance, - availableBalance = balance, - currentBalance = balance + scope = Scope.current, + originId = originId, + originType = GiftCard.CustomerPurchase, + state = GiftCard.Cart, + currency = currency, + originalBalance = balance, + availableBalance = balance, + currentBalance = balance ) - } - def validateStateReason(state: State, reason: Option[Int]): ValidatedNel[Failure, Unit] = { + def validateStateReason(state: State, reason: Option[Int]): ValidatedNel[Failure, Unit] = if (state == Canceled) { validExpr(reason.isDefined, EmptyCancellationReasonFailure.description) } else { valid({}) } - } implicit val stateColumnType: JdbcType[State] with BaseTypedType[State] = State.slickColumn implicit val originTypeColumnType: JdbcType[OriginType] with BaseTypedType[OriginType] = @@ -272,10 +264,8 @@ object GiftCards implicit ec: EC): DbResultT[GiftCardAdjustment] = adjust(giftCard, orderPaymentId.some, debit = debit, state = InStorePaymentStates.Auth) - def authOrderPayment( - giftCard: GiftCard, - pmt: OrderPayment, - maxPaymentAmount: Option[Long] = None)(implicit ec: EC): DbResultT[GiftCardAdjustment] = + def authOrderPayment(giftCard: GiftCard, pmt: OrderPayment, maxPaymentAmount: Option[Long] = None)( + implicit ec: EC): DbResultT[GiftCardAdjustment] = auth(giftCard = giftCard, orderPaymentId = pmt.id, debit = pmt.getAmount(maxPaymentAmount)) def captureOrderPayment(giftCard: GiftCard, pmt: OrderPayment, maxAmount: Option[Long] = None)( @@ -293,27 +283,30 @@ object GiftCards .update(auth, auth.copy(debit = debit, state = InStorePaymentStates.Capture)) } yield cap - def cancelByCsr(giftCard: GiftCard, storeAdmin: User)( - implicit ec: EC): DbResultT[GiftCardAdjustment] = { - val adjustment = Adj(giftCardId = giftCard.id, - orderPaymentId = None, - storeAdminId = storeAdmin.accountId.some, - debit = giftCard.availableBalance, - credit = 0, - availableBalance = 0, - state = InStorePaymentStates.CancellationCapture) + def cancelByCsr(giftCard: GiftCard, storeAdmin: User)(implicit ec: EC): DbResultT[GiftCardAdjustment] = { + val adjustment = Adj( + giftCardId = giftCard.id, + orderPaymentId = None, + storeAdminId = storeAdmin.accountId.some, + debit = giftCard.availableBalance, + credit = 0, + availableBalance = 0, + state = InStorePaymentStates.CancellationCapture + ) Adjs.create(adjustment) } def redeemToStoreCredit(giftCard: GiftCard, storeAdmin: User)( implicit ec: EC): DbResultT[GiftCardAdjustment] = { - val adjustment = Adj(giftCardId = giftCard.id, - orderPaymentId = None, - storeAdminId = storeAdmin.accountId.some, - debit = giftCard.availableBalance, - credit = 0, - availableBalance = 0, - state = InStorePaymentStates.Capture) + val adjustment = Adj( + giftCardId = giftCard.id, + orderPaymentId = None, + storeAdminId = storeAdmin.accountId.some, + debit = giftCard.availableBalance, + credit = 0, + availableBalance = 0, + state = InStorePaymentStates.Capture + ) Adjs.create(adjustment) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardAdjustment.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardAdjustment.scala index 4c857172b0..055cd75cc7 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardAdjustment.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardAdjustment.scala @@ -32,7 +32,7 @@ case class GiftCardAdjustment(id: Int = 0, def getAmount: Long = if (credit > 0) credit else -debit val fsm: Map[State, Set[State]] = Map( - Auth → Set(Canceled, Capture) + Auth → Set(Canceled, Capture) ) } @@ -53,20 +53,12 @@ class GiftCardAdjustments(tag: Tag) def credit = column[Long]("credit") def * = - (id, - giftCardId, - orderPaymentId, - storeAdminId, - credit, - debit, - availableBalance, - state, - createdAt) <> ((GiftCardAdjustment.apply _).tupled, GiftCardAdjustment.unapply) + (id, giftCardId, orderPaymentId, storeAdminId, credit, debit, availableBalance, state, createdAt) <> ((GiftCardAdjustment.apply _).tupled, GiftCardAdjustment.unapply) } object GiftCardAdjustments extends InStorePaymentAdjustmentQueries[GiftCardAdjustment, GiftCardAdjustments]( - new GiftCardAdjustments(_)) + new GiftCardAdjustments(_)) with ReturningId[GiftCardAdjustment, GiftCardAdjustments] { val returningLens: Lens[GiftCardAdjustment, Int] = lens[GiftCardAdjustment].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardFromStoreCredit.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardFromStoreCredit.scala index 27644e63aa..9bb6a02146 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardFromStoreCredit.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardFromStoreCredit.scala @@ -4,8 +4,7 @@ import shapeless._ import slick.jdbc.PostgresProfile.api._ import core.db._ -case class GiftCardFromStoreCredit(id: Int = 0, storeCreditId: Int) - extends FoxModel[GiftCardFromStoreCredit] +case class GiftCardFromStoreCredit(id: Int = 0, storeCreditId: Int) extends FoxModel[GiftCardFromStoreCredit] object GiftCardFromStoreCredit @@ -19,8 +18,7 @@ class GiftCardFromStoreCredits(tag: Tag) } object GiftCardFromStoreCredits - extends FoxTableQuery[GiftCardFromStoreCredit, GiftCardFromStoreCredits]( - new GiftCardFromStoreCredits(_)) + extends FoxTableQuery[GiftCardFromStoreCredit, GiftCardFromStoreCredits](new GiftCardFromStoreCredits(_)) with ReturningId[GiftCardFromStoreCredit, GiftCardFromStoreCredits] { val returningLens: Lens[GiftCardFromStoreCredit, Int] = lens[GiftCardFromStoreCredit].id } diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardManual.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardManual.scala index d1dab41ae6..eacdf2b7b9 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardManual.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/giftcard/GiftCardManual.scala @@ -4,8 +4,7 @@ import core.db._ import shapeless._ import slick.jdbc.PostgresProfile.api._ -case class GiftCardManual(id: Int = 0, adminId: Int, reasonId: Int) - extends FoxModel[GiftCardManual] +case class GiftCardManual(id: Int = 0, adminId: Int, reasonId: Int) extends FoxModel[GiftCardManual] object GiftCardManual {} diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCredit.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCredit.scala index eda353f85f..98717ecbe0 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCredit.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCredit.scala @@ -53,13 +53,12 @@ case class StoreCredit(id: Int = 0, case _ ⇒ valid({}) } - (canceledWithReason |@| invalidExpr( - originalBalance < currentBalance, - "originalBalance cannot be less than currentBalance") |@| invalidExpr( - originalBalance < availableBalance, - "originalBalance cannot be less than availableBalance") |@| invalidExpr( - originalBalance < 0, - "originalBalance must be greater than zero")).map { + (canceledWithReason |@| invalidExpr(originalBalance < currentBalance, + "originalBalance cannot be less than currentBalance") |@| invalidExpr( + originalBalance < availableBalance, + "originalBalance cannot be less than availableBalance") |@| invalidExpr( + originalBalance < 0, + "originalBalance must be greater than zero")).map { case _ ⇒ this } } @@ -69,8 +68,8 @@ case class StoreCredit(id: Int = 0, super.transitionModel(newModel) val fsm: Map[State, Set[State]] = Map( - OnHold → Set(Active, Canceled), - Active → Set(OnHold, Canceled) + OnHold → Set(Active, Canceled), + Active → Set(OnHold, Canceled) ) def isActive: Boolean = state == Active @@ -98,13 +97,12 @@ object StoreCredit { def publicTypes = types.--(Seq(Custom)) } - def validateStateReason(state: State, reason: Option[Int]): ValidatedNel[Failure, Unit] = { + def validateStateReason(state: State, reason: Option[Int]): ValidatedNel[Failure, Unit] = if (state == Canceled) { validExpr(reason.isDefined, "Please provide valid cancellation reason") } else { valid({}) } - } implicit val stateColumnType: JdbcType[State] with BaseTypedType[State] = State.slickColumn implicit val originTypeColumnType: JdbcType[OriginType] with BaseTypedType[OriginType] = @@ -172,21 +170,13 @@ object StoreCredits extends FoxTableQuery[StoreCredit, StoreCredits](new StoreCr amount = amount, state = InStorePaymentStates.Auth) - def authOrderPayment( - storeCredit: StoreCredit, - pmt: OrderPayment, - maxPaymentAmount: Option[Long] = None)(implicit ec: EC): DbResultT[StoreCreditAdjustment] = - auth(storeCredit = storeCredit, - orderPaymentId = pmt.id, - amount = pmt.getAmount(maxPaymentAmount)) - - def captureOrderPayment( - storeCredit: StoreCredit, - pmt: OrderPayment, - maxPaymentAmount: Option[Long] = None)(implicit ec: EC): DbResultT[StoreCreditAdjustment] = - capture(storeCredit = storeCredit, - orderPaymentId = pmt.id, - amount = pmt.getAmount(maxPaymentAmount)) + def authOrderPayment(storeCredit: StoreCredit, pmt: OrderPayment, maxPaymentAmount: Option[Long] = None)( + implicit ec: EC): DbResultT[StoreCreditAdjustment] = + auth(storeCredit = storeCredit, orderPaymentId = pmt.id, amount = pmt.getAmount(maxPaymentAmount)) + + def captureOrderPayment(storeCredit: StoreCredit, pmt: OrderPayment, maxPaymentAmount: Option[Long] = None)( + implicit ec: EC): DbResultT[StoreCreditAdjustment] = + capture(storeCredit = storeCredit, orderPaymentId = pmt.id, amount = pmt.getAmount(maxPaymentAmount)) def capture(storeCredit: StoreCredit, orderPaymentId: Int, amount: Long)( implicit ec: EC): DbResultT[StoreCreditAdjustment] = @@ -201,23 +191,27 @@ object StoreCredits extends FoxTableQuery[StoreCredit, StoreCredits](new StoreCr def cancelByCsr(storeCredit: StoreCredit, storeAdmin: User)( implicit ec: EC): DbResultT[StoreCreditAdjustment] = { - val adjustment = Adj(storeCreditId = storeCredit.id, - orderPaymentId = None, - storeAdminId = storeAdmin.accountId.some, - debit = storeCredit.availableBalance, - availableBalance = 0, - state = InStorePaymentStates.CancellationCapture) + val adjustment = Adj( + storeCreditId = storeCredit.id, + orderPaymentId = None, + storeAdminId = storeAdmin.accountId.some, + debit = storeCredit.availableBalance, + availableBalance = 0, + state = InStorePaymentStates.CancellationCapture + ) Adjs.create(adjustment) } def redeemToGiftCard(storeCredit: StoreCredit, storeAdmin: User)( implicit ec: EC): DbResultT[StoreCreditAdjustment] = { - val adjustment = Adj(storeCreditId = storeCredit.id, - orderPaymentId = None, - storeAdminId = storeAdmin.accountId.some, - debit = storeCredit.availableBalance, - availableBalance = 0, - state = InStorePaymentStates.Capture) + val adjustment = Adj( + storeCreditId = storeCredit.id, + orderPaymentId = None, + storeAdminId = storeAdmin.accountId.some, + debit = storeCredit.availableBalance, + availableBalance = 0, + state = InStorePaymentStates.Capture + ) Adjs.create(adjustment) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditAdjustment.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditAdjustment.scala index bc70ee42d1..eec04ad43a 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditAdjustment.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditAdjustment.scala @@ -30,7 +30,7 @@ case class StoreCreditAdjustment(id: Int = 0, def getAmount: Long = debit val fsm: Map[State, Set[State]] = Map( - Auth → Set(Canceled, Capture) + Auth → Set(Canceled, Capture) ) } @@ -47,7 +47,7 @@ class StoreCreditAdjustments(tag: Tag) object StoreCreditAdjustments extends InStorePaymentAdjustmentQueries[StoreCreditAdjustment, StoreCreditAdjustments]( - new StoreCreditAdjustments(_)) + new StoreCreditAdjustments(_)) with ReturningId[StoreCreditAdjustment, StoreCreditAdjustments] { val returningLens: Lens[StoreCreditAdjustment, Int] = lens[StoreCreditAdjustment].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditCustom.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditCustom.scala index f95258f99e..a0919ee816 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditCustom.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditCustom.scala @@ -7,14 +7,10 @@ import core.db._ import phoenix.utils.aliases._ import shapeless._ -case class StoreCreditCustom(id: Int = 0, - adminId: Int, - metadata: Json, - createdAt: Instant = Instant.now) +case class StoreCreditCustom(id: Int = 0, adminId: Int, metadata: Json, createdAt: Instant = Instant.now) extends FoxModel[StoreCreditCustom] -class StoreCreditCustoms(tag: Tag) - extends FoxTable[StoreCreditCustom](tag, "store_credit_customs") { +class StoreCreditCustoms(tag: Tag) extends FoxTable[StoreCreditCustom](tag, "store_credit_customs") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def adminId = column[Int]("admin_id") def metadata = column[Json]("metadata") diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditFromGiftCard.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditFromGiftCard.scala index c78f75c676..8c619a54f3 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditFromGiftCard.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditFromGiftCard.scala @@ -4,8 +4,7 @@ import core.db._ import shapeless._ import slick.jdbc.PostgresProfile.api._ -case class StoreCreditFromGiftCard(id: Int = 0, giftCardId: Int) - extends FoxModel[StoreCreditFromGiftCard] +case class StoreCreditFromGiftCard(id: Int = 0, giftCardId: Int) extends FoxModel[StoreCreditFromGiftCard] object StoreCreditFromGiftCard @@ -19,8 +18,7 @@ class StoreCreditFromGiftCards(tag: Tag) } object StoreCreditFromGiftCards - extends FoxTableQuery[StoreCreditFromGiftCard, StoreCreditFromGiftCards]( - new StoreCreditFromGiftCards(_)) + extends FoxTableQuery[StoreCreditFromGiftCard, StoreCreditFromGiftCards](new StoreCreditFromGiftCards(_)) with ReturningId[StoreCreditFromGiftCard, StoreCreditFromGiftCards] { val returningLens: Lens[StoreCreditFromGiftCard, Int] = lens[StoreCreditFromGiftCard].id } diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditManual.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditManual.scala index a4c8e1f101..a797810566 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditManual.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditManual.scala @@ -4,16 +4,12 @@ import core.db._ import shapeless._ import slick.jdbc.PostgresProfile.api._ -case class StoreCreditManual(id: Int = 0, - adminId: Int, - reasonId: Int, - subReasonId: Option[Int] = None) +case class StoreCreditManual(id: Int = 0, adminId: Int, reasonId: Int, subReasonId: Option[Int] = None) extends FoxModel[StoreCreditManual] object StoreCreditManual {} -class StoreCreditManuals(tag: Tag) - extends FoxTable[StoreCreditManual](tag, "store_credit_manuals") { +class StoreCreditManuals(tag: Tag) extends FoxTable[StoreCreditManual](tag, "store_credit_manuals") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def adminId = column[Int]("admin_id") def reasonId = column[Int]("reason_id") diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditRefund.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditRefund.scala index 13811a2119..687235fcab 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditRefund.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditRefund.scala @@ -8,8 +8,7 @@ case class StoreCreditRefund(id: Int = 0, returnId: Int) extends FoxModel[StoreC object StoreCreditRefund {} -class StoreCreditRefunds(tag: Tag) - extends FoxTable[StoreCreditRefund](tag, "store_credit_refunds") { +class StoreCreditRefunds(tag: Tag) extends FoxTable[StoreCreditRefund](tag, "store_credit_refunds") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def returnId = column[Int]("return_id") diff --git a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditSubtype.scala b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditSubtype.scala index 29ace6cc33..81879d03e2 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditSubtype.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/payment/storecredit/StoreCreditSubtype.scala @@ -10,8 +10,7 @@ case class StoreCreditSubtype(id: Int = 0, title: String, originType: OriginType object StoreCreditSubtype {} -class StoreCreditSubtypes(tag: Tag) - extends FoxTable[StoreCreditSubtype](tag, "store_credit_subtypes") { +class StoreCreditSubtypes(tag: Tag) extends FoxTable[StoreCreditSubtype](tag, "store_credit_subtypes") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def title = column[String]("title") diff --git a/phoenix-scala/phoenix/app/phoenix/models/plugins/Plugin.scala b/phoenix-scala/phoenix/app/phoenix/models/plugins/Plugin.scala index 5bf01f7fc3..0fe099f9f4 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/plugins/Plugin.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/plugins/Plugin.scala @@ -36,17 +36,15 @@ case class Plugin(id: Int = 0, with Validation[Plugin] { import Validation._ - override def validate: ValidatedNel[Failure, Plugin] = { - + override def validate: ValidatedNel[Failure, Plugin] = (notEmpty(name, "name") - |@| notEmpty(version, "version") - |@| apiPort.fold(ok) { port ⇒ - greaterThan(port, 1, "Api port must be greater than 1") - } - |@| nullOrNotEmpty(apiHost, "apiHost")).map { + |@| notEmpty(version, "version") + |@| apiPort.fold(ok) { port ⇒ + greaterThan(port, 1, "Api port must be greater than 1") + } + |@| nullOrNotEmpty(apiHost, "apiHost")).map { case _ ⇒ this } - } // TODO: change me to field @narma def apiUrl(): Option[String] = @@ -58,15 +56,16 @@ case class Plugin(id: Int = 0, object Plugin { - def fromPayload(payload: RegisterPluginPayload)(implicit au: AU): Plugin = { - Plugin(name = payload.name, - version = payload.version, - scope = Scope.current, - description = payload.description, - apiHost = payload.apiHost, - apiPort = payload.apiPort, - schemaSettings = payload.schemaSettings.getOrElse(List.empty[SettingDef])) - } + def fromPayload(payload: RegisterPluginPayload)(implicit au: AU): Plugin = + Plugin( + name = payload.name, + version = payload.version, + scope = Scope.current, + description = payload.description, + apiHost = payload.apiHost, + apiPort = payload.apiPort, + schemaSettings = payload.schemaSettings.getOrElse(List.empty[SettingDef]) + ) } object PluginOrmTypeMapper { @@ -115,9 +114,7 @@ class Plugins(tag: Tag) extends FoxTable[Plugin](tag, "plugins") { ((Plugin.apply _).tupled, Plugin.unapply) } -object Plugins - extends FoxTableQuery[Plugin, Plugins](new Plugins(_)) - with ReturningId[Plugin, Plugins] { +object Plugins extends FoxTableQuery[Plugin, Plugins](new Plugins(_)) with ReturningId[Plugin, Plugins] { val returningLens: Lens[Plugin, Int] = lens[Plugin].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/plugins/PluginSettings.scala b/phoenix-scala/phoenix/app/phoenix/models/plugins/PluginSettings.scala index 8fc08cdc7e..c7a8b27b11 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/plugins/PluginSettings.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/plugins/PluginSettings.scala @@ -34,9 +34,8 @@ object PluginSettings { merged.extract[SettingsValues] } - def toJson: JValue = { + def toJson: JValue = Extraction.decompose(values) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/product/IlluminatedProduct.scala b/phoenix-scala/phoenix/app/phoenix/models/product/IlluminatedProduct.scala index 4a7b7cb7d2..60a9a026c8 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/product/IlluminatedProduct.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/product/IlluminatedProduct.scala @@ -28,13 +28,12 @@ object IlluminatedProduct { def illuminate(context: ObjectContext, product: Product, form: ObjectForm, - shadow: ObjectShadow): IlluminatedProduct = { - - IlluminatedProduct(id = form.id, - slug = product.slug, - context = IlluminatedContext(context.name, context.attributes), - attributes = - IlluminateAlgorithm.projectAttributes(form.attributes, shadow.attributes), - archivedAt = product.archivedAt) - } + shadow: ObjectShadow): IlluminatedProduct = + IlluminatedProduct( + id = form.id, + slug = product.slug, + context = IlluminatedContext(context.name, context.attributes), + attributes = IlluminateAlgorithm.projectAttributes(form.attributes, shadow.attributes), + archivedAt = product.archivedAt + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/product/IlluminatedVariant.scala b/phoenix-scala/phoenix/app/phoenix/models/product/IlluminatedVariant.scala index 919abae779..845474be08 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/product/IlluminatedVariant.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/product/IlluminatedVariant.scala @@ -9,8 +9,8 @@ case class IlluminatedVariant(id: Int, context: IlluminatedContext, attributes: object IlluminatedVariant { def illuminate(c: ObjectContext, v: FullObject[Variant]): IlluminatedVariant = - IlluminatedVariant( - id = v.form.id, - context = IlluminatedContext(c.name, c.attributes), - attributes = IlluminateAlgorithm.projectAttributes(v.form.attributes, v.shadow.attributes)) + IlluminatedVariant(id = v.form.id, + context = IlluminatedContext(c.name, c.attributes), + attributes = + IlluminateAlgorithm.projectAttributes(v.form.attributes, v.shadow.attributes)) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/product/MvpModel.scala b/phoenix-scala/phoenix/app/phoenix/models/product/MvpModel.scala index 260ef381ac..4029f93d5e 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/product/MvpModel.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/product/MvpModel.scala @@ -41,10 +41,7 @@ object SimpleContext { ObjectContext(id = id, name = name, attributes = ("modality" → modality) ~ ("lang" → lang)) } -case class SimpleProduct(title: String, - description: String, - active: Boolean, - tags: Seq[String] = Seq.empty) { +case class SimpleProduct(title: String, description: String, active: Boolean, tags: Seq[String] = Seq.empty) { val activeFrom = if (active) s""""${Instant.now}"""" else "null"; val ts: String = compact(render(JArray(tags.map(t ⇒ JString(t)).toList))) @@ -64,14 +61,15 @@ case class SimpleProduct(title: String, case class SimpleProductShadow(p: SimpleProduct) { val shadow = ObjectUtils.newShadow( - parse(""" + parse(""" { "title" : {"type": "string", "ref": "title"}, "description" : {"type": "richText", "ref": "description"}, "activeFrom" : {"type": "date", "ref": "activeFrom"}, "tags" : {"type": "tags", "ref": "tags"} }"""), - p.keyMap) + p.keyMap + ) def create: ObjectShadow = ObjectShadow(attributes = shadow) @@ -81,10 +79,9 @@ case class SimpleAlbum(payload: AlbumPayload) { def this(name: String, image: String) = this( - AlbumPayload(name = Some(name), - position = Some(1), - images = - Seq(ImagePayload(src = image, title = image.some, alt = image.some)).some)) + AlbumPayload(name = Some(name), + position = Some(1), + images = Seq(ImagePayload(src = image, title = image.some, alt = image.some)).some)) val (keyMap, form) = ObjectUtils.createForm(payload.formAndShadow.form.attributes) @@ -135,7 +132,8 @@ case class SimpleSku(code: String, case class SimpleSkuShadow(s: SimpleSku) { - val shadow = ObjectUtils.newShadow(parse(""" + val shadow = ObjectUtils.newShadow( + parse(""" { "code" : {"type": "string", "ref": "code"}, "title" : {"type": "string", "ref": "title"}, @@ -144,7 +142,8 @@ case class SimpleSkuShadow(s: SimpleSku) { "activeFrom" : {"type": "date", "ref": "activeFrom"}, "tags" : {"type": "tags", "ref": "tags"} }"""), - s.keyMap) + s.keyMap + ) def create: ObjectShadow = ObjectShadow(attributes = shadow) @@ -177,13 +176,15 @@ case class SimpleVariantValue(name: String, swatch: String, skuCodes: Seq[String } case class SimpleVariantValueShadow(v: SimpleVariantValue) { - val shadow = ObjectUtils.newShadow(parse(""" + val shadow = ObjectUtils.newShadow( + parse(""" { "name": { "type": "string", "ref": "name" }, "swatch": { "type": "string", "ref": "swatch" } } """), - v.keyMap) + v.keyMap + ) def create: ObjectShadow = ObjectShadow(attributes = shadow) } @@ -221,8 +222,7 @@ case class SimpleVariantValueData(valueId: Int, name: String, swatch: String) -case class SimpleCompleteVariantData(variant: SimpleVariantData, - variantValues: Seq[SimpleVariantValueData]) +case class SimpleCompleteVariantData(variant: SimpleVariantData, variantValues: Seq[SimpleVariantValueData]) object Mvp { @@ -312,18 +312,18 @@ object Mvp { simpleShadow ← * <~ SimpleProductShadow(simpleProduct) productSchema ← * <~ ObjectFullSchemas.findOneByName("product") productShadow ← * <~ ObjectShadows.create( - simpleShadow.create.copy(formId = productForm.id, - jsonSchema = productSchema.map(_.name))) + simpleShadow.create.copy(formId = productForm.id, + jsonSchema = productSchema.map(_.name))) productCommit ← * <~ ObjectCommits.create( - ObjectCommit(formId = productForm.id, shadowId = productShadow.id)) + ObjectCommit(formId = productForm.id, shadowId = productShadow.id)) product ← * <~ Products.create( - Product(scope = scope, - contextId = contextId, - formId = productForm.id, - shadowId = productShadow.id, - commitId = productCommit.id)) + Product(scope = scope, + contextId = contextId, + formId = productForm.id, + shadowId = productShadow.id, + commitId = productCommit.id)) _ ← * <~ skus.map(sku ⇒ linkProductAndSku(product, sku)) } yield product @@ -340,15 +340,15 @@ object Mvp { sShadow ← * <~ SimpleSkuShadow(s) skuSchema ← * <~ ObjectFullSchemas.findOneByName("sku") shadow ← * <~ ObjectShadows.create( - sShadow.create.copy(formId = form.id, jsonSchema = skuSchema.map(_.name))) + sShadow.create.copy(formId = form.id, jsonSchema = skuSchema.map(_.name))) commit ← * <~ ObjectCommits.create(ObjectCommit(formId = form.id, shadowId = shadow.id)) sku ← * <~ Skus.create( - Sku(scope = scope, - contextId = contextId, - code = s.code, - formId = form.id, - shadowId = shadow.id, - commitId = commit.id)) + Sku(scope = scope, + contextId = contextId, + code = s.code, + formId = form.id, + shadowId = shadow.id, + commitId = commit.id)) } yield sku def insertSkus(scope: LTree, contextId: Int, ss: Seq[SimpleSku]): DbResultT[Seq[Sku]] = @@ -366,13 +366,12 @@ object Mvp { shadow ← * <~ ObjectShadows.create(sShadow.create.copy(formId = form.id)) commit ← * <~ ObjectCommits.create(ObjectCommit(formId = form.id, shadowId = shadow.id)) variant ← * <~ Variants.create( - Variant(scope = scope, - contextId = contextId, - formId = form.id, - shadowId = shadow.id, - commitId = commit.id)) - _ ← * <~ ProductVariantLinks.create( - ProductVariantLink(leftId = product.id, rightId = variant.id)) + Variant(scope = scope, + contextId = contextId, + formId = form.id, + shadowId = shadow.id, + commitId = commit.id)) + _ ← * <~ ProductVariantLinks.create(ProductVariantLink(leftId = product.id, rightId = variant.id)) } yield SimpleVariantData(variantId = variant.id, variantFormId = variant.formId, @@ -391,16 +390,15 @@ object Mvp { shadow ← * <~ ObjectShadows.create(sShadow.create.copy(formId = form.id)) commit ← * <~ ObjectCommits.create(ObjectCommit(formId = form.id, shadowId = shadow.id)) value ← * <~ VariantValues.create( - VariantValue(scope = scope, - contextId = contextId, - formId = form.id, - shadowId = shadow.id, - commitId = commit.id)) - _ ← * <~ VariantValueLinks.create(VariantValueLink(leftId = variantId, rightId = value.id)) - skuCodes ← * <~ v.skuCodes.map(code ⇒ - SkuManager.mustFindSkuByContextAndCode(contextId, code)) + VariantValue(scope = scope, + contextId = contextId, + formId = form.id, + shadowId = shadow.id, + commitId = commit.id)) + _ ← * <~ VariantValueLinks.create(VariantValueLink(leftId = variantId, rightId = value.id)) + skuCodes ← * <~ v.skuCodes.map(code ⇒ SkuManager.mustFindSkuByContextAndCode(contextId, code)) _ ← * <~ skuCodes.map(s ⇒ - VariantValueSkuLinks.create(VariantValueSkuLink(leftId = value.id, rightId = s.id))) + VariantValueSkuLinks.create(VariantValueSkuLink(leftId = value.id, rightId = s.id))) } yield SimpleVariantValueData(valueId = value.id, variantShadowId = variantShadowId, @@ -415,58 +413,50 @@ object Mvp { simpleCompleteVariant: SimpleCompleteVariant): DbResultT[SimpleCompleteVariantData] = for { variant ← * <~ insertVariant(scope, contextId, simpleCompleteVariant.variant, product) - values ← * <~ simpleCompleteVariant.variantValues.map( - variantValue ⇒ - insertVariantValue(scope, - contextId, - variantValue, - variant.shadowId, - variant.variantId)) + values ← * <~ simpleCompleteVariant.variantValues.map(variantValue ⇒ + insertVariantValue(scope, contextId, variantValue, variant.shadowId, variant.variantId)) } yield SimpleCompleteVariantData(variant, values) - def insertProductIntoContext( - contextId: Int, - productForm: ObjectForm, - skuForm: ObjectForm, - albumForm: ObjectForm, - simpleProduct: SimpleProduct, - simpleSku: SimpleSku, - simpleAlbum: SimpleAlbum, - p: SimpleProductData)(implicit db: DB, au: AU): DbResultT[SimpleProductData] = + def insertProductIntoContext(contextId: Int, + productForm: ObjectForm, + skuForm: ObjectForm, + albumForm: ObjectForm, + simpleProduct: SimpleProduct, + simpleSku: SimpleSku, + simpleAlbum: SimpleAlbum, + p: SimpleProductData)(implicit db: DB, au: AU): DbResultT[SimpleProductData] = for { scope ← * <~ Scope.resolveOverride(None) simpleShadow ← * <~ SimpleProductShadow(simpleProduct) productSchema ← * <~ ObjectFullSchemas.findOneByName("product") productShadow ← * <~ ObjectShadows.create( - simpleShadow.create.copy(formId = productForm.id, - jsonSchema = productSchema.map(_.name))) + simpleShadow.create.copy(formId = productForm.id, + jsonSchema = productSchema.map(_.name))) productCommit ← * <~ ObjectCommits.create( - ObjectCommit(formId = productForm.id, shadowId = productShadow.id)) + ObjectCommit(formId = productForm.id, shadowId = productShadow.id)) product ← * <~ Products.create( - Product(scope = scope, - contextId = contextId, - formId = productForm.id, - shadowId = productShadow.id, - commitId = productCommit.id)) + Product(scope = scope, + contextId = contextId, + formId = productForm.id, + shadowId = productShadow.id, + commitId = productCommit.id)) simpleSkuShadow ← * <~ SimpleSkuShadow(simpleSku) skuSchema ← * <~ ObjectFullSchemas.findOneByName("sku") skuShadow ← * <~ ObjectShadows.create( - simpleSkuShadow.create.copy(formId = skuForm.id, - jsonSchema = skuSchema.map(_.name))) + simpleSkuShadow.create.copy(formId = skuForm.id, jsonSchema = skuSchema.map(_.name))) - skuCommit ← * <~ ObjectCommits.create( - ObjectCommit(formId = skuForm.id, shadowId = skuShadow.id)) + skuCommit ← * <~ ObjectCommits.create(ObjectCommit(formId = skuForm.id, shadowId = skuShadow.id)) sku ← * <~ Skus.create( - Sku(scope = scope, - contextId = contextId, - code = p.code, - formId = skuForm.id, - shadowId = skuShadow.id, - commitId = skuCommit.id)) + Sku(scope = scope, + contextId = contextId, + code = p.code, + formId = skuForm.id, + shadowId = skuShadow.id, + commitId = skuCommit.id)) _ ← * <~ linkProductAndSku(product, sku) @@ -479,28 +469,25 @@ object Mvp { simpleAlbum: SimpleAlbum, albumForm: ObjectForm, productShadow: ObjectShadow, - product: Product)(implicit db: DB, au: AU): DbResultT[Album] = { + product: Product)(implicit db: DB, au: AU): DbResultT[Album] = for { scope ← * <~ Scope.resolveOverride(None) albumSchema ← * <~ ObjectFullSchemas.findOneByName("album") albumShadow ← * <~ ObjectShadows.create( - SimpleAlbumShadow(simpleAlbum).create - .copy(formId = albumForm.id, jsonSchema = albumSchema.map(_.name))) - albumCommit ← * <~ ObjectCommits.create( - ObjectCommit(formId = albumForm.id, shadowId = albumShadow.id)) + SimpleAlbumShadow(simpleAlbum).create + .copy(formId = albumForm.id, jsonSchema = albumSchema.map(_.name))) + albumCommit ← * <~ ObjectCommits.create(ObjectCommit(formId = albumForm.id, shadowId = albumShadow.id)) album ← * <~ Albums.create( - Album(scope = scope, - contextId = context.id, - formId = albumForm.id, - shadowId = albumShadow.id, - commitId = albumCommit.id)) - albumLink ← * <~ ProductAlbumLinks.create( - ProductAlbumLink(leftId = product.id, rightId = album.id)) + Album(scope = scope, + contextId = context.id, + formId = albumForm.id, + shadowId = albumShadow.id, + commitId = albumCommit.id)) + albumLink ← * <~ ProductAlbumLinks.create(ProductAlbumLink(leftId = product.id, rightId = album.id)) _ ← * <~ ImageManager .createImagesForAlbum(album, simpleAlbum.payload.images.toSeq.flatten, context) } yield album - } def getPrice(skuId: Int)(implicit db: DB): DbResultT[Long] = for { @@ -520,8 +507,8 @@ object Mvp { skuShadow ← * <~ ObjectShadows.mustFindById404(sku.shadowId) } yield SimpleProductTuple(product, sku, productForm, skuForm, productShadow, skuShadow) - def insertProducts(ps: Seq[SimpleProductData], - contextId: Int)(implicit db: DB, au: AU): DbResultT[Seq[SimpleProductData]] = + def insertProducts(ps: Seq[SimpleProductData], contextId: Int)(implicit db: DB, + au: AU): DbResultT[Seq[SimpleProductData]] = for { results ← * <~ ps.map(p ⇒ insertProduct(contextId, p)) } yield results diff --git a/phoenix-scala/phoenix/app/phoenix/models/product/Product.scala b/phoenix-scala/phoenix/app/phoenix/models/product/Product.scala index 51bef09c3e..1f557073b6 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/product/Product.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/product/Product.scala @@ -104,15 +104,13 @@ object Products def filterByFormId(formId: Int): QuerySeq = filter(_.formId === formId) - def mustFindProductByContextAndFormId404(contextId: Int, formId: Int)( - implicit ec: EC): DbResultT[Product] = + def mustFindProductByContextAndFormId404(contextId: Int, formId: Int)(implicit ec: EC): DbResultT[Product] = Products .filter(_.contextId === contextId) .filter(_.formId === formId) .mustFindOneOr(ProductFormNotFoundForContext(formId, contextId)) - def mustFindByReference(reference: ProductReference)(implicit oc: OC, - ec: EC): DbResultT[Product] = { + def mustFindByReference(reference: ProductReference)(implicit oc: OC, ec: EC): DbResultT[Product] = reference match { case ProductId(id) ⇒ mustFindProductByContextAndFormId404(oc.id, id) @@ -120,7 +118,6 @@ object Products filter(p ⇒ p.contextId === oc.id && p.slug.toLowerCase === slug.toLowerCase()) .mustFindOneOr(ProductFailures.ProductNotFoundForContext(slug, oc.id)) } - } def mustFindFullByReference( ref: ProductReference)(implicit oc: OC, ec: EC, db: DB): DbResultT[FullObject[Product]] = diff --git a/phoenix-scala/phoenix/app/phoenix/models/product/ProductValidator.scala b/phoenix-scala/phoenix/app/phoenix/models/product/ProductValidator.scala index f42e6ffcfe..49826c2dd9 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/product/ProductValidator.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/product/ProductValidator.scala @@ -13,8 +13,6 @@ object ProductValidator { implicit val formats: Formats = JsonFormatters.phoenixFormats - def validate(product: Product, form: ObjectForm, shadow: ObjectShadow): Seq[Failure] = { - + def validate(product: Product, form: ObjectForm, shadow: ObjectShadow): Seq[Failure] = IlluminateAlgorithm.validateAttributes(form.attributes, shadow.attributes) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/product/VariantValue.scala b/phoenix-scala/phoenix/app/phoenix/models/product/VariantValue.scala index 4eadd7189f..c65e357e62 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/product/VariantValue.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/product/VariantValue.scala @@ -35,7 +35,7 @@ case class VariantValue(id: Int = 0, class VariantValues(tag: Tag) extends ObjectHeads[VariantValue](tag, "variant_values") { def * = (id, scope, contextId, shadowId, formId, commitId, updatedAt, createdAt, archivedAt) <> ((VariantValue.apply _).tupled, - VariantValue.unapply) + VariantValue.unapply) } object VariantValues diff --git a/phoenix-scala/phoenix/app/phoenix/models/product/VariantValueSkuLink.scala b/phoenix-scala/phoenix/app/phoenix/models/product/VariantValueSkuLink.scala index d19a8526e9..e357d7731f 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/product/VariantValueSkuLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/product/VariantValueSkuLink.scala @@ -15,8 +15,7 @@ case class VariantValueSkuLink(id: Int = 0, archivedAt: Option[Instant] = None) extends FoxModel[VariantValueSkuLink] -class VariantValueSkuLinks(tag: Tag) - extends FoxTable[VariantValueSkuLink](tag, "variant_value_sku_links") { +class VariantValueSkuLinks(tag: Tag) extends FoxTable[VariantValueSkuLink](tag, "variant_value_sku_links") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def leftId = column[Int]("left_id") def rightId = column[Int]("right_id") @@ -42,10 +41,9 @@ object VariantValueSkuLinks def filterLeft(leftIds: Seq[Int]): QuerySeq = filter(_.leftId.inSet(leftIds)) def findSkusForVariantValues( - variantValueHeadIds: Seq[Int]): Query[(Rep[Int], Rep[String]), (Int, String), Seq] = { + variantValueHeadIds: Seq[Int]): Query[(Rep[Int], Rep[String]), (Int, String), Seq] = for { link ← filterLeft(variantValueHeadIds) sku ← Skus if link.rightId === sku.id } yield (link.leftId, sku.code) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/promotion/IlluminatedPromotion.scala b/phoenix-scala/phoenix/app/phoenix/models/promotion/IlluminatedPromotion.scala index 2296fcc774..3a68e16086 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/promotion/IlluminatedPromotion.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/promotion/IlluminatedPromotion.scala @@ -17,10 +17,7 @@ import phoenix.utils.aliases._ * An IlluminatedPromotion is what you get when you combine the promotion shadow and * the form. */ -case class IlluminatedPromotion(id: Int, - context: IlluminatedContext, - applyType: ApplyType, - attributes: Json) { +case class IlluminatedPromotion(id: Int, context: IlluminatedContext, applyType: ApplyType, attributes: Json) { implicit val formats = JsonFormatters.phoenixFormats @@ -46,21 +43,19 @@ object IlluminatedPromotion { def illuminate(context: ObjectContext, promotion: Promotion, form: ObjectForm, - shadow: ObjectShadow): IlluminatedPromotion = { - + shadow: ObjectShadow): IlluminatedPromotion = IlluminatedPromotion( - id = form.id, //Id points to form since that is constant across contexts - applyType = promotion.applyType, - context = IlluminatedContext(context.name, context.attributes), - attributes = IlluminateAlgorithm.projectAttributes(form.attributes, shadow.attributes)) - } + id = form.id, //Id points to form since that is constant across contexts + applyType = promotion.applyType, + context = IlluminatedContext(context.name, context.attributes), + attributes = IlluminateAlgorithm.projectAttributes(form.attributes, shadow.attributes) + ) - def validatePromotion(applyType: ApplyType, promotion: FormAndShadow): FormAndShadow = { + def validatePromotion(applyType: ApplyType, promotion: FormAndShadow): FormAndShadow = (applyType, promotion.getAttribute("activeFrom")) match { case (Promotion.Coupon, JNothing) ⇒ promotion.setAttribute("activeFrom", "date", Instant.now.toString) case _ ⇒ promotion } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/promotion/PromotionHelpers.scala b/phoenix-scala/phoenix/app/phoenix/models/promotion/PromotionHelpers.scala index 25168b0016..75b2df5480 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/promotion/PromotionHelpers.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/promotion/PromotionHelpers.scala @@ -6,11 +6,9 @@ import phoenix.utils.aliases._ object PromotionHelpers { - def name(form: ObjectForm, shadow: ObjectShadow): Json = { + def name(form: ObjectForm, shadow: ObjectShadow): Json = ObjectUtils.get("name", form, shadow) - } - def description(form: ObjectForm, shadow: ObjectShadow): Json = { + def description(form: ObjectForm, shadow: ObjectShadow): Json = ObjectUtils.get("description", form, shadow) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/promotion/PromotionValidator.scala b/phoenix-scala/phoenix/app/phoenix/models/promotion/PromotionValidator.scala index 34e620b851..074368c1ea 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/promotion/PromotionValidator.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/promotion/PromotionValidator.scala @@ -13,8 +13,6 @@ object PromotionValidator { implicit val formats: Formats = JsonFormatters.phoenixFormats - def validate(promotion: Promotion, form: ObjectForm, shadow: ObjectShadow): Seq[Failure] = { - + def validate(promotion: Promotion, form: ObjectForm, shadow: ObjectShadow): Seq[Failure] = IlluminateAlgorithm.validateAttributes(form.attributes, shadow.attributes) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/returns/Return.scala b/phoenix-scala/phoenix/app/phoenix/models/returns/Return.scala index f2e1bccfae..4b1945688d 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/returns/Return.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/returns/Return.scala @@ -38,17 +38,17 @@ case class Return(id: Int = 0, override def primarySearchKey: String = referenceNumber val fsm: Map[State, Set[State]] = Map( - Pending → - Set(Processing, Canceled), - Processing → - Set(Review, Complete, Canceled), - Review → - Set(Complete, Canceled) + Pending → + Set(Processing, Canceled), + Processing → + Set(Review, Complete, Canceled), + Review → + Set(Complete, Canceled) ) } object Return { - sealed trait State extends Product with Serializable + sealed trait State extends Product with Serializable case object Pending extends State case object Processing extends State case object Review extends State @@ -75,15 +75,14 @@ object Return { val returnRefNumRegex = """([a-zA-Z0-9-_.]*)""".r // normally it's "[Order.refNumber].#" val messageToAccountMaxLength = 1000 - def build(order: Order, admin: User, rmaType: ReturnType = Return.Standard): Return = { + def build(order: Order, admin: User, rmaType: ReturnType = Return.Standard): Return = Return( - orderId = order.id, - orderRef = order.refNum, - returnType = rmaType, - accountId = order.accountId, - storeAdminId = Some(admin.accountId) + orderId = order.id, + orderRef = order.refNum, + returnType = rmaType, + accountId = order.accountId, + storeAdminId = Some(admin.accountId) ) - } } @@ -143,12 +142,11 @@ object Returns def findByOrderRefNum(refNum: String): QuerySeq = filter(_.orderRef === refNum) def findPrevious(rma: Return): QuerySeq = - findByOrderRefNum(rma.orderRef).filter(r ⇒ - r.id =!= rma.id && r.state === (Return.Complete: Return.State)) + findByOrderRefNum(rma.orderRef).filter(r ⇒ r.id =!= rma.id && r.state === (Return.Complete: Return.State)) def findPreviousOrCurrent(rma: Return): QuerySeq = findByOrderRefNum(rma.orderRef).filter(r ⇒ - (r.id =!= rma.id && r.state === (Return.Complete: Return.State)) || r.id === rma.id) + (r.id =!= rma.id && r.state === (Return.Complete: Return.State)) || r.id === rma.id) def findOneByRefNum(refNum: String): DBIO[Option[Return]] = findByRefNum(refNum).one diff --git a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItem.scala b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItem.scala index 27660dff2e..6fa76454b9 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItem.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItem.scala @@ -19,7 +19,7 @@ case class ReturnLineItem(id: Int = 0, extends FoxModel[ReturnLineItem] object ReturnLineItem { - sealed trait OriginType extends Product with Serializable + sealed trait OriginType extends Product with Serializable case object SkuItem extends OriginType case object ShippingCost extends OriginType diff --git a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItemShippingCost.scala b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItemShippingCost.scala index d137a244a3..088bb00e2a 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItemShippingCost.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItemShippingCost.scala @@ -7,10 +7,7 @@ import shapeless._ import slick.jdbc.PostgresProfile.api._ import core.utils.Money._ -case class ReturnLineItemShippingCost(id: Int, - returnId: Int, - amount: Long, - createdAt: Instant = Instant.now) +case class ReturnLineItemShippingCost(id: Int, returnId: Int, amount: Long, createdAt: Instant = Instant.now) extends FoxModel[ReturnLineItemShippingCost] class ReturnLineItemShippingCosts(tag: Tag) @@ -24,14 +21,13 @@ class ReturnLineItemShippingCosts(tag: Tag) (id, returnId, amount, createdAt) <> ((ReturnLineItemShippingCost.apply _).tupled, ReturnLineItemShippingCost.unapply) def li = - foreignKey(ReturnLineItems.tableName, id, ReturnLineItems)(_.id, - onDelete = ForeignKeyAction.Cascade) + foreignKey(ReturnLineItems.tableName, id, ReturnLineItems)(_.id, onDelete = ForeignKeyAction.Cascade) def returns = foreignKey(Returns.tableName, returnId, Returns)(_.id) } object ReturnLineItemShippingCosts extends FoxTableQuery[ReturnLineItemShippingCost, ReturnLineItemShippingCosts]( - new ReturnLineItemShippingCosts(_)) + new ReturnLineItemShippingCosts(_)) with ReturningId[ReturnLineItemShippingCost, ReturnLineItemShippingCosts] { val returningLens: Lens[ReturnLineItemShippingCost, Int] = lens[ReturnLineItemShippingCost].id diff --git a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItemSku.scala b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItemSku.scala index c317bed711..4a30eef7f9 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItemSku.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnLineItemSku.scala @@ -16,8 +16,7 @@ case class ReturnLineItemSku(id: Int, createdAt: Instant = Instant.now) extends FoxModel[ReturnLineItemSku] -class ReturnLineItemSkus(tag: Tag) - extends FoxTable[ReturnLineItemSku](tag, "return_line_item_skus") { +class ReturnLineItemSkus(tag: Tag) extends FoxTable[ReturnLineItemSku](tag, "return_line_item_skus") { def id = column[Int]("id", O.PrimaryKey) def returnId = column[Int]("return_id") def quantity = column[Int]("quantity") @@ -29,8 +28,7 @@ class ReturnLineItemSkus(tag: Tag) (id, returnId, quantity, skuId, skuShadowId, createdAt) <> ((ReturnLineItemSku.apply _).tupled, ReturnLineItemSku.unapply) def li = - foreignKey(ReturnLineItems.tableName, id, ReturnLineItems)(_.id, - onDelete = ForeignKeyAction.Cascade) + foreignKey(ReturnLineItems.tableName, id, ReturnLineItems)(_.id, onDelete = ForeignKeyAction.Cascade) def sku = foreignKey(Skus.tableName, skuId, Skus)(_.id) def shadow = foreignKey(ObjectShadows.tableName, skuShadowId, ObjectShadows)(_.id) } diff --git a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnPayment.scala b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnPayment.scala index 48f79ec7da..58201e87ed 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnPayment.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnPayment.scala @@ -26,7 +26,7 @@ class ReturnPayments(tag: Tag) extends FoxTable[ReturnPayment](tag, "return_paym def * = (id, returnId, amount, currency, paymentMethodId, paymentMethodType) <> ((ReturnPayment.apply _).tupled, - ReturnPayment.unapply) + ReturnPayment.unapply) def rma = foreignKey(Returns.tableName, returnId, Returns)(_.id) } @@ -41,8 +41,7 @@ object ReturnPayments def findAllByReturnId(returnId: Int): QuerySeq = filter(_.returnId === returnId) - def findGiftCards( - returnId: Int): Query[(ReturnPayments, GiftCards), (ReturnPayment, GiftCard), Seq] = + def findGiftCards(returnId: Int): Query[(ReturnPayments, GiftCards), (ReturnPayment, GiftCard), Seq] = findAllByReturnId(returnId).giftCards.join(GiftCards).on(_.paymentMethodId === _.id) def findStoreCredits( @@ -50,11 +49,13 @@ object ReturnPayments findAllByReturnId(returnId).storeCredits.join(StoreCredits).on(_.paymentMethodId === _.id) def findOnHoldGiftCards(returnId: Int): GiftCards.QuerySeq = - findGiftCards(returnId).map { case (_, gc) ⇒ gc } + findGiftCards(returnId) + .map { case (_, gc) ⇒ gc } .filter(_.state === (GiftCard.OnHold: GiftCard.State)) def findOnHoldStoreCredits(returnId: Int): StoreCredits.QuerySeq = - findStoreCredits(returnId).map { case (_, sc) ⇒ sc } + findStoreCredits(returnId) + .map { case (_, sc) ⇒ sc } .filter(_.state === (StoreCredit.OnHold: StoreCredit.State)) object scope { diff --git a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnStripePayment.scala b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnStripePayment.scala index fc4d2f9def..126ee1a52c 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnStripePayment.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/returns/ReturnStripePayment.scala @@ -15,8 +15,7 @@ case class ReturnStripePayment(id: Int = 0, currency: Currency) extends FoxModel[ReturnStripePayment] -class ReturnStripePayments(tag: Tag) - extends FoxTable[ReturnStripePayment](tag, "return_stripe_payments") { +class ReturnStripePayments(tag: Tag) extends FoxTable[ReturnStripePayment](tag, "return_stripe_payments") { def id = column[Int]("id", O.AutoInc) def returnPaymentId = column[Int]("return_payment_id") def chargeId = column[String]("charge_id") @@ -26,7 +25,7 @@ class ReturnStripePayments(tag: Tag) def * = (id, returnPaymentId, chargeId, returnId, amount, currency) <> ((ReturnStripePayment.apply _).tupled, - ReturnStripePayment.unapply) + ReturnStripePayment.unapply) def pk = primaryKey(tableName, (returnPaymentId, chargeId)) def creditCardCharge = diff --git a/phoenix-scala/phoenix/app/phoenix/models/rules/Condition.scala b/phoenix-scala/phoenix/app/phoenix/models/rules/Condition.scala index c32cce3d11..a993c0e381 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/rules/Condition.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/rules/Condition.scala @@ -35,7 +35,7 @@ object Condition { } // TODO (Jeff): Return an actual error, rather than just a boolean. - def matches(comp: Int, statement: Condition): Boolean = { + def matches(comp: Int, statement: Condition): Boolean = statement.valInt.fold(false) { (v: Int) ⇒ statement.operator match { case Equals ⇒ comp == v @@ -47,13 +47,12 @@ object Condition { case _ ⇒ false } } - } // TODO (Jeff): Make this more robust and think about things like case-sensitivity. def matches(comp: String, statement: Condition): Boolean = matches(Some(comp), statement) - def matches(comp: Option[String], statement: Condition): Boolean = { + def matches(comp: Option[String], statement: Condition): Boolean = comp.fold(matchAgainstEmptyStringOption(statement)) { (comp: String) ⇒ statement.valString.fold(false) { (v: String) ⇒ statement.operator match { @@ -68,9 +67,8 @@ object Condition { } } } - } - def matches(comp: Boolean, condition: Condition): Boolean = { + def matches(comp: Boolean, condition: Condition): Boolean = condition.valBoolean.fold(false) { (v: Boolean) ⇒ condition.operator match { case Equals ⇒ comp == v @@ -78,14 +76,12 @@ object Condition { case _ ⇒ false } } - } - private def matchAgainstEmptyStringOption(statement: Condition): Boolean = { + private def matchAgainstEmptyStringOption(statement: Condition): Boolean = statement.operator match { case Equals ⇒ statement.valString.isEmpty case NotEquals ⇒ statement.valString.nonEmpty case NotContains ⇒ true case _ ⇒ false } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/rules/QueryStatement.scala b/phoenix-scala/phoenix/app/phoenix/models/rules/QueryStatement.scala index 2b4a71c75f..1480911c99 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/rules/QueryStatement.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/rules/QueryStatement.scala @@ -34,12 +34,12 @@ object QueryStatement { implicit val QueryStatementColumn: JdbcType[QueryStatement] with BaseTypedType[QueryStatement] = { implicit val formats = JsonFormatters.phoenixFormats MappedColumnType.base[QueryStatement, Json]( - q ⇒ Extraction.decompose(q), - j ⇒ j.extract[QueryStatement] + q ⇒ Extraction.decompose(q), + j ⇒ j.extract[QueryStatement] ) } - def evaluate[A](stmt: Option[QueryStatement], data: A, f: (Condition, A) ⇒ Boolean): Boolean = { + def evaluate[A](stmt: Option[QueryStatement], data: A, f: (Condition, A) ⇒ Boolean): Boolean = stmt.fold(false) { statement ⇒ val initial = statement.comparison == QueryStatement.And @@ -51,5 +51,4 @@ object QueryStatement { statement.comparison.apply(result, evaluate(Some(nextStmt), data, f)) } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/sharedsearch/SharedSearch.scala b/phoenix-scala/phoenix/app/phoenix/models/sharedsearch/SharedSearch.scala index 3a2beb3b73..5821141840 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/sharedsearch/SharedSearch.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/sharedsearch/SharedSearch.scala @@ -53,12 +53,12 @@ object SharedSearch { def byAdmin(admin: User, payload: SharedSearchPayload, scope: LTree): SharedSearch = SharedSearch( - title = payload.title, - query = payload.query, - rawQuery = payload.rawQuery, - storeAdminId = admin.accountId, - scope = payload.scope, - accessScope = scope + title = payload.title, + query = payload.query, + rawQuery = payload.rawQuery, + storeAdminId = admin.accountId, + scope = payload.scope, + accessScope = scope ) implicit val scopeColumnType: JdbcType[Scope] with BaseTypedType[Scope] = Scope.slickColumn @@ -78,17 +78,7 @@ class SharedSearches(tag: Tag) extends FoxTable[SharedSearch](tag, "shared_searc def deletedAt = column[Option[Instant]]("deleted_at") def * = - (id, - code, - accessScope, - title, - query, - rawQuery, - scope, - storeAdminId, - isSystem, - createdAt, - deletedAt) <> ((SharedSearch.apply _).tupled, SharedSearch.unapply) + (id, code, accessScope, title, query, rawQuery, scope, storeAdminId, isSystem, createdAt, deletedAt) <> ((SharedSearch.apply _).tupled, SharedSearch.unapply) } object SharedSearches diff --git a/phoenix-scala/phoenix/app/phoenix/models/sharedsearch/SharedSearchAssociations.scala b/phoenix-scala/phoenix/app/phoenix/models/sharedsearch/SharedSearchAssociations.scala index d96622ec42..17d195361f 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/sharedsearch/SharedSearchAssociations.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/sharedsearch/SharedSearchAssociations.scala @@ -17,9 +17,8 @@ case class SharedSearchAssociation(id: Int = 0, extends FoxModel[SharedSearchAssociation] object SharedSearchAssociation { - def build(search: SharedSearch, admin: User): SharedSearchAssociation = { + def build(search: SharedSearch, admin: User): SharedSearchAssociation = SharedSearchAssociation(sharedSearchId = search.id, storeAdminId = admin.accountId) - } } class SharedSearchAssociations(tag: Tag) @@ -31,14 +30,13 @@ class SharedSearchAssociations(tag: Tag) def * = (id, sharedSearchId, storeAdminId, createdAt) <> ((SharedSearchAssociation.apply _).tupled, - SharedSearchAssociation.unapply) + SharedSearchAssociation.unapply) def sharedSearch = foreignKey(SharedSearches.tableName, sharedSearchId, Carts)(_.id) def storeAdmin = foreignKey(Users.tableName, storeAdminId, Users)(_.accountId) } object SharedSearchAssociations - extends FoxTableQuery[SharedSearchAssociation, SharedSearchAssociations]( - new SharedSearchAssociations(_)) + extends FoxTableQuery[SharedSearchAssociation, SharedSearchAssociations](new SharedSearchAssociations(_)) with ReturningId[SharedSearchAssociation, SharedSearchAssociations] { val returningLens: Lens[SharedSearchAssociation, Int] = lens[SharedSearchAssociation].id @@ -53,10 +51,9 @@ object SharedSearchAssociations def bySharedSearch(search: SharedSearch): QuerySeq = filter(_.sharedSearchId === search.id) - def associatedAdmins(search: SharedSearch): Users.QuerySeq = { + def associatedAdmins(search: SharedSearch): Users.QuerySeq = for { associations ← bySharedSearch(search).map(_.storeAdminId) admins ← Users.filter(_.accountId === associations) } yield admins - } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/shipping/DefaultShippingMethod.scala b/phoenix-scala/phoenix/app/phoenix/models/shipping/DefaultShippingMethod.scala index a32b09922d..b1e4096bf4 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/shipping/DefaultShippingMethod.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/shipping/DefaultShippingMethod.scala @@ -19,18 +19,18 @@ class DefaultShippingMethods(tag: Tag) } object DefaultShippingMethods - extends FoxTableQuery[DefaultShippingMethod, DefaultShippingMethods]( - new DefaultShippingMethods(_)) + extends FoxTableQuery[DefaultShippingMethod, DefaultShippingMethods](new DefaultShippingMethods(_)) with ReturningId[DefaultShippingMethod, DefaultShippingMethods] { val returningLens: Lens[DefaultShippingMethod, Int] = lens[DefaultShippingMethod].id private def resolveFirst[T, M](scope: LTree)(resolver: LTree ⇒ Query[T, M, Seq])( implicit ec: EC): DBIO[Option[M]] = - resolver(scope).one.flatMap { // can blow up stack currently - please see https://github.com/slick/slick/pull/1703 - case None if scope.value.nonEmpty ⇒ resolveFirst(LTree(scope.value.init))(resolver) - case other ⇒ DBIO.successful(other) - } + resolver(scope).one + .flatMap { // can blow up stack currently - please see https://github.com/slick/slick/pull/1703 + case None if scope.value.nonEmpty ⇒ resolveFirst(LTree(scope.value.init))(resolver) + case other ⇒ DBIO.successful(other) + } def findDefaultByScope(scope: LTree): QuerySeq = filter(_.scope === scope) diff --git a/phoenix-scala/phoenix/app/phoenix/models/shipping/ShippingRestriction.scala b/phoenix-scala/phoenix/app/phoenix/models/shipping/ShippingRestriction.scala index 97d1537161..acf852ed8e 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/shipping/ShippingRestriction.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/shipping/ShippingRestriction.scala @@ -18,18 +18,19 @@ object ShippingRestriction { case object ItemAttribute extends RestrictionType //Use SkuCriterion implicit val DestinationColumnType: JdbcType[RestrictionType] with BaseTypedType[RestrictionType] = - MappedColumnType.base[RestrictionType, String]({ - case t ⇒ t.toString.toLowerCase - }, { - case "shipto" ⇒ ShipTo - case "itemattribute" ⇒ ItemAttribute - case unknown ⇒ - throw new IllegalArgumentException(s"cannot map destination_type column to type $unknown") - }) + MappedColumnType.base[RestrictionType, String]( + { + case t ⇒ t.toString.toLowerCase + }, { + case "shipto" ⇒ ShipTo + case "itemattribute" ⇒ ItemAttribute + case unknown ⇒ + throw new IllegalArgumentException(s"cannot map destination_type column to type $unknown") + } + ) } -class ShippingRestrictions(tag: Tag) - extends FoxTable[ShippingRestriction](tag, "shipping_methods") { +class ShippingRestrictions(tag: Tag) extends FoxTable[ShippingRestriction](tag, "shipping_methods") { def id = column[Int]("id", O.PrimaryKey, O.AutoInc) def restrictionType = column[ShippingRestriction.RestrictionType]("restriction_type") def name = column[String]("name") diff --git a/phoenix-scala/phoenix/app/phoenix/models/taxonomy/Taxon.scala b/phoenix-scala/phoenix/app/phoenix/models/taxonomy/Taxon.scala index f7d33dd88e..b29e538133 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/taxonomy/Taxon.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/taxonomy/Taxon.scala @@ -35,12 +35,10 @@ class Taxons(tag: Tag) extends ObjectHeads[Taxon](tag, "taxons") { def * = (id, scope, contextId, shadowId, formId, commitId, updatedAt, createdAt, archivedAt) <> ((Taxon.apply _).tupled, - Taxon.unapply) + Taxon.unapply) } -object Taxons - extends ObjectHeadsQueries[Taxon, Taxons](new Taxons(_)) - with ReturningId[Taxon, Taxons] { +object Taxons extends ObjectHeadsQueries[Taxon, Taxons](new Taxons(_)) with ReturningId[Taxon, Taxons] { val returningLens: Lens[Taxon, Int] = lens[Taxon].id } diff --git a/phoenix-scala/phoenix/app/phoenix/models/taxonomy/Taxonomy.scala b/phoenix-scala/phoenix/app/phoenix/models/taxonomy/Taxonomy.scala index 03fcf20bb9..049f47bfec 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/taxonomy/Taxonomy.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/taxonomy/Taxonomy.scala @@ -36,16 +36,7 @@ class Taxonomies(tag: Tag) extends ObjectHeads[Taxonomy](tag, "taxonomies") { def hierarchical = column[Boolean]("hierarchical") def * = - (id, - scope, - hierarchical, - contextId, - formId, - shadowId, - commitId, - updatedAt, - createdAt, - archivedAt) <> ((Taxonomy.apply _).tupled, Taxonomy.unapply) + (id, scope, hierarchical, contextId, formId, shadowId, commitId, updatedAt, createdAt, archivedAt) <> ((Taxonomy.apply _).tupled, Taxonomy.unapply) } object Taxonomies diff --git a/phoenix-scala/phoenix/app/phoenix/models/taxonomy/TaxonomyTaxonLink.scala b/phoenix-scala/phoenix/app/phoenix/models/taxonomy/TaxonomyTaxonLink.scala index 54ec1da88e..4007c63f3e 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/taxonomy/TaxonomyTaxonLink.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/taxonomy/TaxonomyTaxonLink.scala @@ -46,8 +46,7 @@ case class TaxonomyTaxonLink(id: Int = 0, def parentIndex: Option[Int] = path.value.lastOption.filter(!_.isEmpty).map(_.toInt) } -class TaxonomyTaxonLinks(tag: Tag) - extends ObjectHeadLinks[TaxonomyTaxonLink](tag, "taxonomy_taxon_links") { +class TaxonomyTaxonLinks(tag: Tag) extends ObjectHeadLinks[TaxonomyTaxonLink](tag, "taxonomy_taxon_links") { def index = column[Int]("index") def position = column[Int]("position") @@ -64,9 +63,9 @@ class TaxonomyTaxonLinks(tag: Tag) object TaxonomyTaxonLinks extends ObjectHeadLinkQueries[TaxonomyTaxonLink, TaxonomyTaxonLinks, Taxonomy, Taxon]( - new TaxonomyTaxonLinks(_), - Taxonomies, - Taxons) + new TaxonomyTaxonLinks(_), + Taxonomies, + Taxons) with ReturningId[TaxonomyTaxonLink, TaxonomyTaxonLinks] { def hasChildren(link: TaxonomyTaxonLink): Rep[Boolean] = { @@ -112,11 +111,10 @@ object TaxonomyTaxonLinks for { newPosition ← * <~ position - .fold(getNextPosition(link.taxonomyId, link.path).result.dbresult) { - newPosition ⇒ - for { - _ ← * <~ shiftPositions(link.taxonomyId, link.path, newPosition) - } yield newPosition + .fold(getNextPosition(link.taxonomyId, link.path).result.dbresult) { newPosition ⇒ + for { + _ ← * <~ shiftPositions(link.taxonomyId, link.path, newPosition) + } yield newPosition } newLink = link.copy(position = newPosition) _ = assert(newLink.id == link.id && newLink.position == newPosition) @@ -160,11 +158,14 @@ object TaxonomyTaxonLinks filter(_.taxonomyId === taxonomyId).nonArchived.map(_.index).max.map(_ + 1).getOrElse(0) def filterByTaxonFormId(taxonFormId: ObjectForm#Id)(implicit oc: OC): QuerySeq = - join(Taxons).on { case (link, term) ⇒ link.taxonId === term.id }.filter { - case (_, term) ⇒ - term.formId === - taxonFormId && term.contextId === oc.id - }.map { case (link, _) ⇒ link } + join(Taxons) + .on { case (link, term) ⇒ link.taxonId === term.id } + .filter { + case (_, term) ⇒ + term.formId === + taxonFormId && term.contextId === oc.id + } + .map { case (link, _) ⇒ link } def build(left: Taxonomy, right: Taxon): TaxonomyTaxonLink = TaxonomyTaxonLink(0, 0, left.id, right.id, 0, LTree("")) @@ -193,8 +194,8 @@ object TaxonomyTaxonLinks implicit oc: OC): QuerySeq = filterByTaxonFormId(taxonFormId).filter(_.taxonomyId === taxonomyId) - def mustFindByTaxonomyAndTaxonFormId(taxonomy: Taxonomy, - taxonFormId: ObjectForm#Id)(implicit oc: OC, ec: EC) = + def mustFindByTaxonomyAndTaxonFormId(taxonomy: Taxonomy, taxonFormId: ObjectForm#Id)(implicit oc: OC, + ec: EC) = q.filterByTaxonomyAndTaxonFormId(taxonomy.id, taxonFormId) .mustFindOneOr(NoTermInTaxonomy(taxonomy.formId, taxonFormId)) diff --git a/phoenix-scala/phoenix/app/phoenix/models/traits/Addressable.scala b/phoenix-scala/phoenix/app/phoenix/models/traits/Addressable.scala index b41012aab6..bc690ab196 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/traits/Addressable.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/traits/Addressable.scala @@ -46,8 +46,9 @@ trait Addressable[M] { self: M ⇒ matches(zipValue, Address.zipPattern, "zip") } - (notEmpty(name, "name") |@| notEmpty(address1, "address1") |@| notEmpty(city, "city") |@| zipValidation |@| phone).map { - case _ ⇒ this - } + (notEmpty(name, "name") |@| notEmpty(address1, "address1") |@| notEmpty(city, "city") |@| zipValidation |@| phone) + .map { + case _ ⇒ this + } } } diff --git a/phoenix-scala/phoenix/app/phoenix/models/tree/GenericTreeNodes.scala b/phoenix-scala/phoenix/app/phoenix/models/tree/GenericTreeNodes.scala index 9b2f7f65b9..4fa4a455fe 100644 --- a/phoenix-scala/phoenix/app/phoenix/models/tree/GenericTreeNodes.scala +++ b/phoenix-scala/phoenix/app/phoenix/models/tree/GenericTreeNodes.scala @@ -8,12 +8,7 @@ import phoenix.utils.JsonFormatters import shapeless._ import slick.lifted.Tag -case class GenericTreeNode(id: Int, - treeId: Int, - index: Int, - path: LTree, - kind: String, - objectId: Int) +case class GenericTreeNode(id: Int, treeId: Int, index: Int, path: LTree, kind: String, objectId: Int) extends FoxModel[GenericTreeNode] with Validation[GenericTreeNode] diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/AuthPayload.scala b/phoenix-scala/phoenix/app/phoenix/payloads/AuthPayload.scala index 302f778502..9915b9c21c 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/AuthPayload.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/AuthPayload.scala @@ -28,7 +28,7 @@ object AuthPayload { class JwtClaimsSerializerImpl extends CustomSerializer[JwtClaims](format ⇒ - ({ + ({ case jv ⇒ JwtClaims.parse(compactJson(jv)) }, { diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/CartPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/CartPayloads.scala index 7850c04d85..64aad2daa2 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/CartPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/CartPayloads.scala @@ -14,11 +14,9 @@ object CartPayloads { scope: Option[String] = None) extends Validation[CreateCart] { - def validate: ValidatedNel[Failure, CreateCart] = { - + def validate: ValidatedNel[Failure, CreateCart] = (validExpr(customerId.isDefined || email.isDefined, "customerId or email must be given") |+| - email.fold(ok)(notEmpty(_, "email"))).map(_ ⇒ this) - } + email.fold(ok)(notEmpty(_, "email"))).map(_ ⇒ this) } case class CheckoutCart(items: List[UpdateLineItemsPayload]) diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/CustomerPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/CustomerPayloads.scala index f205f78d48..01848592ed 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/CustomerPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/CustomerPayloads.scala @@ -19,11 +19,10 @@ object CustomerPayloads { phoneNumber: Option[String] = None) extends Validation[UpdateCustomerPayload] { - def validate: ValidatedNel[Failure, UpdateCustomerPayload] = { - (nullOrNotEmpty(name, "name") |@| nullOrNotEmpty(email, "email") |@| nullOrNotEmpty( - phoneNumber, - "phoneNumber")).map { case _ ⇒ this } - } + def validate: ValidatedNel[Failure, UpdateCustomerPayload] = + (nullOrNotEmpty(name, "name") |@| nullOrNotEmpty(email, "email") |@| nullOrNotEmpty(phoneNumber, + "phoneNumber")) + .map { case _ ⇒ this } } case class ChangeCustomerPasswordPayload(oldPassword: String, newPassword: String) @@ -38,8 +37,7 @@ object CustomerPayloads { notEmpty(name, "name").map { case _ ⇒ this } } - case class CustomerSearchForNewOrder(term: String) - extends Validation[CustomerSearchForNewOrder] { + case class CustomerSearchForNewOrder(term: String) extends Validation[CustomerSearchForNewOrder] { def validate: ValidatedNel[Failure, CustomerSearchForNewOrder] = greaterThan(term.length, 1, "term size").map { case _ ⇒ this } diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/EntityExportPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/EntityExportPayloads.scala index a9df163375..ac4049c19d 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/EntityExportPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/EntityExportPayloads.scala @@ -28,15 +28,14 @@ object EntityExportPayloads { * Order in list matters, as if there are more than one `FieldCalculation` that reacts to the same field name, * only the last one will be taken into account. */ - sealed abstract class ExportableEntity(dynamicCalculations: List[FieldCalculation]) { - this: Product ⇒ + sealed abstract class ExportableEntity(dynamicCalculations: List[FieldCalculation]) { this: Product ⇒ def this(dynamicCalculations: FieldCalculation*) = this(dynamicCalculations.toList) - lazy val (extraFields, calculateFields) = dynamicCalculations.foldLeft( - List.empty[String] → PartialFunction.empty[(String, JObject), String]) { - case ((accFields, accCalc), fc) ⇒ - (fc.extraFields ::: accFields, fc.calculate.orElse(accCalc)) - } + lazy val (extraFields, calculateFields) = + dynamicCalculations.foldLeft(List.empty[String] → PartialFunction.empty[(String, JObject), String]) { + case ((accFields, accCalc), fc) ⇒ + (fc.extraFields ::: accFields, fc.calculate.orElse(accCalc)) + } def entity: String = productPrefix.underscore @@ -151,10 +150,10 @@ object EntityExportPayloads { object ExportEntity { def typeHints = ADTTypeHints( - Map( - Type.Ids → classOf[ByIDs], - Type.Query → classOf[BySearchQuery] - )) + Map( + Type.Ids → classOf[ByIDs], + Type.Query → classOf[BySearchQuery] + )) sealed trait Type extends Product with Serializable implicit object Type extends ADT[Type] { @@ -175,8 +174,7 @@ object EntityExportPayloads { case class RawSortDefinition(field: String, json: JObject) extends SortDefinition { lazy val builder: SortBuilder = new SortBuilder { - private[this] lazy val bytes = new BytesArray( - compact(render(json)).getBytes(StandardCharsets.UTF_8)) + private[this] lazy val bytes = new BytesArray(compact(render(json)).getBytes(StandardCharsets.UTF_8)) def missing(missing: Any): SortBuilder = this // no need to support this operation @@ -188,7 +186,7 @@ object EntityExportPayloads { } object RawSortDefinition { val jsonFormat = new CustomSerializer[RawSortDefinition](_ ⇒ - ({ + ({ case JString(field) ⇒ RawSortDefinition(field, JObject()) case JObject((field, order @ JString(_)) :: Nil) ⇒ RawSortDefinition(field, JObject("order" → order)) diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/GiftCardPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/GiftCardPayloads.scala index 20cbae3b14..2c31ece9f4 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/GiftCardPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/GiftCardPayloads.scala @@ -32,12 +32,11 @@ object GiftCardPayloads { scope: Option[String] = None) extends Validation[GiftCardCreateByCsr] { - def validate: ValidatedNel[Failure, GiftCardCreateByCsr] = { + def validate: ValidatedNel[Failure, GiftCardCreateByCsr] = (greaterThan(balance, 0L, "Balance") |@| scope.fold[ValidatedNel[Failure, Unit]](ok)(s ⇒ - notEmpty(s, "scope"))).map { + notEmpty(s, "scope"))).map { case _ ⇒ this } - } } case class GiftCardBulkCreateByCsr(quantity: Int, @@ -50,20 +49,18 @@ object GiftCardPayloads { val bulkCreateLimit = 20 - def validate: ValidatedNel[Failure, GiftCardBulkCreateByCsr] = { + def validate: ValidatedNel[Failure, GiftCardBulkCreateByCsr] = (greaterThan(balance, 0L, "Balance") |@| greaterThan(quantity, 0, "Quantity") |@| lesserThanOrEqual( - quantity, - bulkCreateLimit, - "Quantity") |@| scope.fold(ok)(s ⇒ notEmpty(s, "scope"))).map { case _ ⇒ this } - } + quantity, + bulkCreateLimit, + "Quantity") |@| scope.fold(ok)(s ⇒ notEmpty(s, "scope"))).map { case _ ⇒ this } } case class GiftCardUpdateStateByCsr(state: GiftCard.State, reasonId: Option[Int] = None) extends Validation[GiftCardUpdateStateByCsr] { - def validate: ValidatedNel[Failure, GiftCardUpdateStateByCsr] = { + def validate: ValidatedNel[Failure, GiftCardUpdateStateByCsr] = GiftCard.validateStateReason(state, reasonId).map(_ ⇒ this) - } } case class GiftCardBulkUpdateStateByCsr(codes: Seq[String], @@ -73,13 +70,11 @@ object GiftCardPayloads { val bulkUpdateLimit = 20 - def validate: ValidatedNel[Failure, GiftCardBulkUpdateStateByCsr] = { + def validate: ValidatedNel[Failure, GiftCardBulkUpdateStateByCsr] = (GiftCard.validateStateReason(state, reasonId) |@| validExpr( - codes.nonEmpty, - "Please provide at least one code to update") |@| lesserThanOrEqual( - codes.length, - bulkUpdateLimit, - "Quantity")).map { case _ ⇒ this } - } + codes.nonEmpty, + "Please provide at least one code to update") |@| lesserThanOrEqual(codes.length, + bulkUpdateLimit, + "Quantity")).map { case _ ⇒ this } } } diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/ImagePayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/ImagePayloads.scala index 4b503b0bc8..e3359e0ced 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/ImagePayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/ImagePayloads.scala @@ -21,11 +21,10 @@ object ImagePayloads { scope: Option[String] = None) { def formAndShadow: FormAndShadow = { - val jsonBuilder: AttributesBuilder = optionalAttributes( - Some(StringField("src", src)), - title.map(StringField("title", _)), - alt.map(StringField("alt", _)), - baseUrl.map(StringField("baseUrl", _))) + val jsonBuilder: AttributesBuilder = optionalAttributes(Some(StringField("src", src)), + title.map(StringField("title", _)), + alt.map(StringField("alt", _)), + baseUrl.map(StringField("baseUrl", _))) (ObjectForm(kind = Image.kind, attributes = jsonBuilder.objectForm), ObjectShadow(attributes = jsonBuilder.objectShadow)) diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/LineItemPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/LineItemPayloads.scala index a2b96a0244..5968d04908 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/LineItemPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/LineItemPayloads.scala @@ -4,9 +4,7 @@ import phoenix.models.cord.lineitems._ object LineItemPayloads { - case class UpdateLineItemsPayload(sku: String, - quantity: Int, - attributes: Option[LineItemAttributes] = None) + case class UpdateLineItemsPayload(sku: String, quantity: Int, attributes: Option[LineItemAttributes] = None) case class UpdateOrderLineItemsPayload( state: OrderLineItem.State, diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/Payloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/Payloads.scala index abf9e19c39..5e7a85dce2 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/Payloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/Payloads.scala @@ -15,6 +15,4 @@ case class NotificationActivity(id: String, context: ActivityContext, createdAt: Instant) -case class CreateNotification(sourceDimension: String, - sourceObjectId: String, - activity: NotificationActivity) +case class CreateNotification(sourceDimension: String, sourceObjectId: String, activity: NotificationActivity) diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/PaymentPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/PaymentPayloads.scala index c66a114d6e..4984bf1234 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/PaymentPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/PaymentPayloads.scala @@ -30,14 +30,13 @@ object PaymentPayloads { val notEmptyBrand = notEmpty(brand, "brand") val notEmptyHolderName = notEmpty(holderName, "holder name") val fieldsValid = tokenNotEmpty |@| validYear |@| validMonth |@| expDateInFuture |@| notEmptyBrand |@| - notEmptyHolderName + notEmptyHolderName (fieldsValid |@| billingAddress.validate).map { case _ ⇒ this } } } - @deprecated(message = "Use `CreateCreditCardFromTokenPayload` instead", - "Until we are PCI compliant") + @deprecated(message = "Use `CreateCreditCardFromTokenPayload` instead", "Until we are PCI compliant") case class CreateCreditCardFromSourcePayload(holderName: String, cardNumber: String, cvv: String, @@ -56,22 +55,18 @@ object PaymentPayloads { validExpr(address.isDefined || addressId.isDefined, "address or addressId") (notEmpty(holderName, "holderName") |@| matches(cardNumber, "[0-9]+", "number") |@| matches( - cvv, - "[0-9]{3,4}", - "cvv") |@| withinTwentyYears(expYear, "expiration") |@| isMonth(expMonth, - "expiration") |@| notExpired( - expYear, - expMonth, - "credit card is expired") |@| someAddress).map { case _ ⇒ this } + cvv, + "[0-9]{3,4}", + "cvv") |@| withinTwentyYears(expYear, "expiration") |@| isMonth(expMonth, "expiration") |@| notExpired( + expYear, + expMonth, + "credit card is expired") |@| someAddress).map { case _ ⇒ this } } def lastFour: String = this.cardNumber.takeRight(4) } - case class PaymentMethodPayload(cardholderName: String, - cardNumber: String, - cvv: Int, - expiration: String) + case class PaymentMethodPayload(cardholderName: String, cardNumber: String, cvv: Int, expiration: String) case class EditCreditCard(holderName: Option[String] = None, expYear: Option[Int] = None, @@ -89,10 +84,10 @@ object PaymentPayloads { } (holderName.fold(ok)(notEmpty(_, "holderName")) |@| expYear - .fold(ok)(withinTwentyYears(_, "expiration")) |@| expMonth.fold(ok)( - isMonth(_, "expiration")) |@| expired).map { - case _ ⇒ this - } + .fold(ok)(withinTwentyYears(_, "expiration")) |@| expMonth.fold(ok)(isMonth(_, "expiration")) |@| expired) + .map { + case _ ⇒ this + } } } diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/PluginPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/PluginPayloads.scala index 2ca637c763..7e5a230911 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/PluginPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/PluginPayloads.scala @@ -17,25 +17,20 @@ object PluginPayloads { schemaSettings: Option[SettingsSchema]) extends Validation[RegisterPluginPayload] { - def isManaged(): Boolean = { + def isManaged(): Boolean = apiPort.isDefined && apiHost.isDefined - } - - def apiUrlNotEmptyIfManaged(): ValidatedNel[Failure, Unit] = { - (notEmptyIf(schemaSettings, - !isManaged(), - "schemaSettings or apiHost & apiPort should be presented") - |@| apiPort.fold(ok) { port ⇒ - greaterThan(port, 0, "Api port") - }).map { case _ ⇒ () } - } - - def validate: ValidatedNel[Failure, RegisterPluginPayload] = { + + def apiUrlNotEmptyIfManaged(): ValidatedNel[Failure, Unit] = + (notEmptyIf(schemaSettings, !isManaged(), "schemaSettings or apiHost & apiPort should be presented") + |@| apiPort.fold(ok) { port ⇒ + greaterThan(port, 0, "Api port") + }).map { case _ ⇒ () } + + def validate: ValidatedNel[Failure, RegisterPluginPayload] = (notEmpty(name, "name") - |@| notEmpty(version, "version") - |@| nullOrNotEmpty(apiHost, "API host") - |@| apiUrlNotEmptyIfManaged()).map { case _ ⇒ this } - } + |@| notEmpty(version, "version") + |@| nullOrNotEmpty(apiHost, "API host") + |@| apiUrlNotEmptyIfManaged()).map { case _ ⇒ this } } case class UpdateSettingsPayload(settings: SettingsValues) diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/ProductReviewPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/ProductReviewPayloads.scala index 6cb2a77380..c4563bc291 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/ProductReviewPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/ProductReviewPayloads.scala @@ -11,9 +11,7 @@ object ProductReviewPayloads { def scope: Option[String] } - case class CreateProductReviewByCustomerPayload(attributes: Json, - sku: String, - scope: Option[String] = None) + case class CreateProductReviewByCustomerPayload(attributes: Json, sku: String, scope: Option[String] = None) extends CreateProductReviewPayload case class CreateProductReviewByAdminPayload(userId: Option[Int], diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/ReturnPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/ReturnPayloads.scala index 1b0ef8101a..aee5484656 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/ReturnPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/ReturnPayloads.scala @@ -20,10 +20,9 @@ object ReturnPayloads { extends Validation[ReturnUpdateStatePayload] { def validate: ValidatedNel[Failure, ReturnUpdateStatePayload] = (Validation.ok |+| - Validation.isInvalid(state == Return.Canceled && reasonId.isEmpty, - EmptyCancellationReasonFailure) |+| - Validation.isInvalid(state != Return.Canceled && reasonId.isDefined, - NonEmptyCancellationReasonFailure)).map(_ ⇒ this) + Validation.isInvalid(state == Return.Canceled && reasonId.isEmpty, EmptyCancellationReasonFailure) |+| + Validation.isInvalid(state != Return.Canceled && reasonId.isDefined, + NonEmptyCancellationReasonFailure)).map(_ ⇒ this) } /* Line item updater payloads */ @@ -34,10 +33,10 @@ object ReturnPayloads { object ReturnLineItemPayload { def typeHints = ADTTypeHints( - Map( - ReturnLineItem.ShippingCost → classOf[ReturnShippingCostLineItemPayload], - ReturnLineItem.SkuItem → classOf[ReturnSkuLineItemPayload] - )) + Map( + ReturnLineItem.ShippingCost → classOf[ReturnShippingCostLineItemPayload], + ReturnLineItem.SkuItem → classOf[ReturnSkuLineItemPayload] + )) } case class ReturnSkuLineItemPayload(sku: String, quantity: Int, reasonId: Int) @@ -46,8 +45,7 @@ object ReturnPayloads { greaterThan(quantity, 0, "Quantity").map(_ ⇒ this) } - case class ReturnShippingCostLineItemPayload(amount: Long, reasonId: Int) - extends ReturnLineItemPayload { + case class ReturnShippingCostLineItemPayload(amount: Long, reasonId: Int) extends ReturnLineItemPayload { def validate: ValidatedNel[Failure, ReturnLineItemPayload] = greaterThan(amount, 0L, "Amount").map(_ ⇒ this) } @@ -56,18 +54,19 @@ object ReturnPayloads { case class ReturnPaymentsPayload(payments: Map[PaymentMethod.Type, Long]) extends Validation[ReturnPaymentsPayload] { - def validate: ValidatedNel[Failure, ReturnPaymentsPayload] = { - payments.collect { - case (paymentType, amount) if amount <= 0 ⇒ - greaterThanOrEqual(amount, 0L, s"$paymentType amount") - }.fold(Validation.ok)(_ |+| _).map(_ ⇒ this) - } + def validate: ValidatedNel[Failure, ReturnPaymentsPayload] = + payments + .collect { + case (paymentType, amount) if amount <= 0 ⇒ + greaterThanOrEqual(amount, 0L, s"$paymentType amount") + } + .fold(Validation.ok)(_ |+| _) + .map(_ ⇒ this) } case class ReturnPaymentPayload(amount: Long) extends Validation[ReturnPaymentPayload] { - def validate: ValidatedNel[Failure, ReturnPaymentPayload] = { + def validate: ValidatedNel[Failure, ReturnPaymentPayload] = greaterThan(amount, 0L, "Amount").map(_ ⇒ this) - } } /* Misc */ @@ -75,14 +74,13 @@ object ReturnPayloads { case class ReturnMessageToCustomerPayload(message: String) extends Validation[ReturnMessageToCustomerPayload] { - def validate: ValidatedNel[Failure, ReturnMessageToCustomerPayload] = { + def validate: ValidatedNel[Failure, ReturnMessageToCustomerPayload] = (greaterThanOrEqual(message.length, 0, "Message length") |+| lesserThanOrEqual( - message.length, - Return.messageToAccountMaxLength, - "Message length")).map { + message.length, + Return.messageToAccountMaxLength, + "Message length")).map { case _ ⇒ this } - } } case class ReturnReasonPayload(name: String) extends Validation[ReturnReasonPayload] { @@ -90,9 +88,8 @@ object ReturnPayloads { def validate: ValidatedNel[Failure, ReturnReasonPayload] = { val clue = "Reason name length" - (greaterThan(name.length, 0, clue) |+| lesserThanOrEqual(name.length, - reasonNameMaxLength, - clue)).map(_ ⇒ this) + (greaterThan(name.length, 0, clue) |+| lesserThanOrEqual(name.length, reasonNameMaxLength, clue)) + .map(_ ⇒ this) } } } diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/SharedSearchPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/SharedSearchPayloads.scala index af1d1ef7f5..48a0ef3517 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/SharedSearchPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/SharedSearchPayloads.scala @@ -5,10 +5,7 @@ import phoenix.utils.aliases._ object SharedSearchPayloads { - case class SharedSearchPayload(title: String, - query: Json, - rawQuery: Json, - scope: SharedSearch.Scope) + case class SharedSearchPayload(title: String, query: Json, rawQuery: Json, scope: SharedSearch.Scope) case class SharedSearchAssociationPayload(associates: Seq[Int]) } diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/StoreAdminPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/StoreAdminPayloads.scala index 00cfe6ce96..ce74505935 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/StoreAdminPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/StoreAdminPayloads.scala @@ -18,25 +18,21 @@ object StoreAdminPayloads { scope: Option[String] = None) extends Validation[CreateStoreAdminPayload] { - def validate: ValidatedNel[Failure, CreateStoreAdminPayload] = { + def validate: ValidatedNel[Failure, CreateStoreAdminPayload] = (notEmpty(name, "name") |@| notEmpty(email, "email") |@| - nullOrNotEmpty(phoneNumber, "phoneNumber") |@| nullOrNotEmpty(password, "password")).map { + nullOrNotEmpty(phoneNumber, "phoneNumber") |@| nullOrNotEmpty(password, "password")).map { case _ ⇒ this } - } } - case class UpdateStoreAdminPayload(email: String, - name: String, - phoneNumber: Option[String] = None) + case class UpdateStoreAdminPayload(email: String, name: String, phoneNumber: Option[String] = None) extends Validation[UpdateStoreAdminPayload] { - def validate: ValidatedNel[Failure, UpdateStoreAdminPayload] = { + def validate: ValidatedNel[Failure, UpdateStoreAdminPayload] = (notEmpty(name, "name") |@| notEmpty(email, "email") |@| - nullOrNotEmpty(phoneNumber, "phoneNumber")).map { + nullOrNotEmpty(phoneNumber, "phoneNumber")).map { case _ ⇒ this } - } } case class StateChangeStoreAdminPayload(state: State) diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/StoreCreditPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/StoreCreditPayloads.scala index df87580aff..b9decb48e1 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/StoreCreditPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/StoreCreditPayloads.scala @@ -12,9 +12,8 @@ object StoreCreditPayloads { case class StoreCreditUpdateStateByCsr(state: StoreCredit.State, reasonId: Option[Int] = None) extends Validation[StoreCreditUpdateStateByCsr] { - def validate: ValidatedNel[Failure, StoreCreditUpdateStateByCsr] = { + def validate: ValidatedNel[Failure, StoreCreditUpdateStateByCsr] = StoreCredit.validateStateReason(state, reasonId).map { case _ ⇒ this } - } } case class StoreCreditBulkUpdateStateByCsr(ids: Seq[Int], @@ -24,13 +23,11 @@ object StoreCreditPayloads { val bulkUpdateLimit = 20 - def validate: ValidatedNel[Failure, StoreCreditBulkUpdateStateByCsr] = { + def validate: ValidatedNel[Failure, StoreCreditBulkUpdateStateByCsr] = (StoreCredit.validateStateReason(state, reasonId) |@| validExpr( - ids.nonEmpty, - "Please provide at least one code to update") |@| lesserThanOrEqual( - ids.length, - bulkUpdateLimit, - "Quantity")).map { case _ ⇒ this } - } + ids.nonEmpty, + "Please provide at least one code to update") |@| lesserThanOrEqual(ids.length, + bulkUpdateLimit, + "Quantity")).map { case _ ⇒ this } } } diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/UserPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/UserPayloads.scala index 45f95f16c3..43e59bd71a 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/UserPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/UserPayloads.scala @@ -15,11 +15,10 @@ object UserPayloads { // Reset password payloads case class ResetPasswordSend(email: String) extends Validation[ResetPasswordSend] { - def validate: ValidatedNel[Failure, ResetPasswordSend] = { + def validate: ValidatedNel[Failure, ResetPasswordSend] = notEmpty(email, "email").map { _ ⇒ this } - } } case class ResetPassword(code: String, newPassword: String) extends Validation[ResetPassword] { diff --git a/phoenix-scala/phoenix/app/phoenix/payloads/VariantPayloads.scala b/phoenix-scala/phoenix/app/phoenix/payloads/VariantPayloads.scala index 065ec36605..414c053268 100644 --- a/phoenix-scala/phoenix/app/phoenix/payloads/VariantPayloads.scala +++ b/phoenix-scala/phoenix/app/phoenix/payloads/VariantPayloads.scala @@ -24,9 +24,9 @@ object VariantPayloads { def formAndShadow: FormAndShadow = { val jsonBuilder: AttributesBuilder = ObjectPayloads.optionalAttributes( - name.map(StringField("name", _)), - swatch.map(StringField("swatch", _)), - swatch.map(StringField("image", _))) + name.map(StringField("name", _)), + swatch.map(StringField("swatch", _)), + swatch.map(StringField("image", _))) (ObjectForm(kind = VariantValue.kind, attributes = jsonBuilder.objectForm), ObjectShadow(attributes = jsonBuilder.objectShadow)) diff --git a/phoenix-scala/phoenix/app/phoenix/responses/ActivityResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/ActivityResponse.scala index 766aa4f769..9af86ef96c 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/ActivityResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/ActivityResponse.scala @@ -6,17 +6,9 @@ import phoenix.models.activity.{Activity, ActivityContext} import phoenix.utils.aliases._ object ActivityResponse { - case class Root(id: String, - kind: ActivityType, - data: Json, - context: ActivityContext, - createdAt: Instant) + case class Root(id: String, kind: ActivityType, data: Json, context: ActivityContext, createdAt: Instant) extends ResponseItem def build(a: Activity): Root = - Root(id = a.id, - kind = a.activityType, - data = a.data, - context = a.context, - createdAt = a.createdAt) + Root(id = a.id, kind = a.activityType, data = a.data, context = a.context, createdAt = a.createdAt) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/AddressResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/AddressResponse.scala index 1d4140d1c1..670ee2f889 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/AddressResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/AddressResponse.scala @@ -36,44 +36,49 @@ object AddressResponse { Regions.mustFindById400(address.regionId).map(region ⇒ build(address, region)) def build(address: Address, region: Region): AddressResponse = - AddressResponse(id = address.id, - region = region, - name = address.name, - address1 = address.address1, - address2 = address.address2, - city = address.city, - zip = address.zip, - isDefault = address.isDefaultShipping.some, - phoneNumber = address.phoneNumber, - deletedAt = address.deletedAt) + AddressResponse( + id = address.id, + region = region, + name = address.name, + address1 = address.address1, + address2 = address.address2, + city = address.city, + zip = address.zip, + isDefault = address.isDefaultShipping.some, + phoneNumber = address.phoneNumber, + deletedAt = address.deletedAt + ) def buildFromCreditCard(cc: CreditCard, region: Region): AddressResponse = - AddressResponse(id = 0, - region = region, - name = cc.address.name, - address1 = cc.address.address1, - address2 = cc.address.address2, - city = cc.address.city, - zip = cc.address.zip, - isDefault = None, - phoneNumber = cc.address.phoneNumber) + AddressResponse( + id = 0, + region = region, + name = cc.address.name, + address1 = cc.address.address1, + address2 = cc.address.address2, + city = cc.address.city, + zip = cc.address.zip, + isDefault = None, + phoneNumber = cc.address.phoneNumber + ) def buildMulti(records: Seq[(Address, Region)]): Seq[AddressResponse] = records.map((build _).tupled) - def buildFromOrder(address: OrderShippingAddress, region: Region): AddressResponse = { + def buildFromOrder(address: OrderShippingAddress, region: Region): AddressResponse = // FIXME: so AddressResponse#id is OrderShippingAddress#id, but *sometimes* also Address#id? o_O’ @michalrus - AddressResponse(id = address.id, - region = region, - name = address.name, - address1 = address.address1, - address2 = address.address2, - city = address.city, - zip = address.zip, - isDefault = None, - phoneNumber = address.phoneNumber, - deletedAt = None) - } + AddressResponse( + id = address.id, + region = region, + name = address.name, + address1 = address.address1, + address2 = address.address2, + city = address.city, + zip = address.zip, + isDefault = None, + phoneNumber = address.phoneNumber, + deletedAt = None + ) def forCordRef(cordRef: String)(implicit ec: EC): DbResultT[AddressResponse] = { val fullAddressDetails = for { @@ -85,14 +90,14 @@ object AddressResponse { fullAddress ← * <~ fullAddressDetails.result (addresses, regions) = fullAddress.unzip response ← * <~ ((addresses.headOption, regions.headOption) match { - case (Some(address), Some(region)) ⇒ - DbResultT.good(buildFromOrder(address, region)) - case (None, _) ⇒ - DbResultT.failure(NotFoundFailure404( - s"No addresses found for order with refNum=$cordRef")) - case (Some(address), None) ⇒ - DbResultT.failure(NotFoundFailure404(Region, address.regionId)) - }) + case (Some(address), Some(region)) ⇒ + DbResultT.good(buildFromOrder(address, region)) + case (None, _) ⇒ + DbResultT.failure( + NotFoundFailure404(s"No addresses found for order with refNum=$cordRef")) + case (Some(address), None) ⇒ + DbResultT.failure(NotFoundFailure404(Region, address.regionId)) + }) } yield response } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/AssignmentResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/AssignmentResponse.scala index e9c8819810..e9e587e62c 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/AssignmentResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/AssignmentResponse.scala @@ -8,15 +8,11 @@ import phoenix.responses.UserResponse.{build ⇒ buildUser} object AssignmentResponse { - case class Root(assignee: UserResponse.Root, - assignmentType: Assignment.AssignmentType, - createdAt: Instant) + case class Root(assignee: UserResponse.Root, assignmentType: Assignment.AssignmentType, createdAt: Instant) extends ResponseItem - def build(assignment: Assignment, admin: User): Root = { - + def build(assignment: Assignment, admin: User): Root = Root(assignee = buildUser(admin), assignmentType = assignment.assignmentType, createdAt = assignment.createdAt) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/CategoryResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/CategoryResponses.scala index 0e3b8194bc..95504085cb 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/CategoryResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/CategoryResponses.scala @@ -26,8 +26,7 @@ object CategoryResponses { object CategoryShadowResponse { - case class Root(id: Int, formId: Int, attributes: Json, createdAt: Instant) - extends ResponseItem + case class Root(id: Int, formId: Int, attributes: Json, createdAt: Instant) extends ResponseItem def build(c: ObjectShadow): Root = Root(c.id, c.formId, c.attributes, c.createdAt) } @@ -43,11 +42,9 @@ object CategoryResponses { object FullCategoryResponse { - case class Root(form: CategoryFormResponse.Root, shadow: CategoryShadowResponse.Root) - extends ResponseItem + case class Root(form: CategoryFormResponse.Root, shadow: CategoryShadowResponse.Root) extends ResponseItem def build(category: Category, categoryForm: ObjectForm, categoryShadow: ObjectShadow): Root = - Root(CategoryFormResponse.build(category, categoryForm), - CategoryShadowResponse.build(categoryShadow)) + Root(CategoryFormResponse.build(category, categoryForm), CategoryShadowResponse.build(categoryShadow)) } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/CouponResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/CouponResponses.scala index cdcb2dd079..a10aa7b14f 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/CouponResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/CouponResponses.scala @@ -36,16 +36,15 @@ object CouponResponses { extends ResponseItem def build(coupon: IlluminatedCoupon, originalCoupon: Coupon): Root = - Root(id = coupon.id, - context = ObjectContextResponse.build(coupon.context), - attributes = coupon.attributes, - promotion = coupon.promotion, - archivedAt = originalCoupon.archivedAt) - - def build(context: ObjectContext, - coupon: Coupon, - form: ObjectForm, - shadow: ObjectShadow): Root = + Root( + id = coupon.id, + context = ObjectContextResponse.build(coupon.context), + attributes = coupon.attributes, + promotion = coupon.promotion, + archivedAt = originalCoupon.archivedAt + ) + + def build(context: ObjectContext, coupon: Coupon, form: ObjectForm, shadow: ObjectShadow): Root = build(IlluminatedCoupon.illuminate(context, coupon, form, shadow), coupon) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/CreditCardsResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/CreditCardsResponse.scala index 14d6f03916..7515c5a043 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/CreditCardsResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/CreditCardsResponse.scala @@ -25,16 +25,18 @@ object CreditCardsResponse { } yield build(cc, region) def build(cc: CreditCard, region: Region): Root = - Root(id = cc.id, - customerId = cc.accountId, - holderName = cc.holderName, - lastFour = cc.lastFour, - expMonth = cc.expMonth, - expYear = cc.expYear, - isDefault = cc.isDefault, - inWallet = cc.inWallet, - brand = cc.brand, - address = AddressResponse.buildFromCreditCard(cc, region)) + Root( + id = cc.id, + customerId = cc.accountId, + holderName = cc.holderName, + lastFour = cc.lastFour, + expMonth = cc.expMonth, + expYear = cc.expYear, + isDefault = cc.isDefault, + inWallet = cc.inWallet, + brand = cc.brand, + address = AddressResponse.buildFromCreditCard(cc, region) + ) // Temporary simplified version w/o address case class RootSimple(id: Int, @@ -51,13 +53,15 @@ object CreditCardsResponse { extends ResponseItem def buildSimple(cc: CreditCard): RootSimple = - RootSimple(id = cc.id, - customerId = cc.accountId, - holderName = cc.holderName, - lastFour = cc.lastFour, - expMonth = cc.expMonth, - expYear = cc.expYear, - isDefault = cc.isDefault, - inWallet = cc.inWallet, - brand = cc.brand) + RootSimple( + id = cc.id, + customerId = cc.accountId, + holderName = cc.holderName, + lastFour = cc.lastFour, + expMonth = cc.expMonth, + expYear = cc.expYear, + isDefault = cc.isDefault, + inWallet = cc.inWallet, + brand = cc.brand + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/CustomerResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/CustomerResponse.scala index 8616b02ea0..5e313258ee 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/CustomerResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/CustomerResponse.scala @@ -39,21 +39,23 @@ object CustomerResponse { require(customerData.userId == customer.id) require(customerData.accountId == customer.accountId) - Root(id = customer.accountId, - email = customer.email, - name = customer.name, - phoneNumber = customer.phoneNumber, - createdAt = customer.createdAt, - isGuest = customerData.isGuest, - disabled = customer.isDisabled, - isBlacklisted = customer.isBlacklisted, - rank = rank.flatMap(_.rank), - totalSales = rank.map(_.revenue).getOrElse(0L), - numOrders = numOrders, - storeCreditTotals = scTotals.getOrElse(Totals(0, 0)), - billingRegion = billingRegion, - shippingRegion = shippingRegion, - lastOrderDays = lastOrderDays, - groups = groups) + Root( + id = customer.accountId, + email = customer.email, + name = customer.name, + phoneNumber = customer.phoneNumber, + createdAt = customer.createdAt, + isGuest = customerData.isGuest, + disabled = customer.isDisabled, + isBlacklisted = customer.isBlacklisted, + rank = rank.flatMap(_.rank), + totalSales = rank.map(_.revenue).getOrElse(0L), + numOrders = numOrders, + storeCreditTotals = scTotals.getOrElse(Totals(0, 0)), + billingRegion = billingRegion, + shippingRegion = shippingRegion, + lastOrderDays = lastOrderDays, + groups = groups + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/GenericTreeResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/GenericTreeResponses.scala index 724209afe7..8ec8dbb4dd 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/GenericTreeResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/GenericTreeResponses.scala @@ -19,21 +19,19 @@ object GenericTreeResponses { def build(tree: GenericTree, nodes: Seq[GenericTreeNode]) = buildTree(nodes).map(nodes ⇒ Root(tree.id, tree.name, tree.contextId, nodes)) - case class Node(kind: String, objectId: Int, index: Int, children: Seq[Node]) - extends ResponseItem + case class Node(kind: String, objectId: Int, index: Int, children: Seq[Node]) extends ResponseItem - def buildTree(nodes: Seq[GenericTreeNode]): Option[TreeResponse.Node] = { + def buildTree(nodes: Seq[GenericTreeNode]): Option[TreeResponse.Node] = buildTree(1, nodes.sortBy(_.path.value.size)).headOption - } private def buildTree(level: Int, nodesSorted: Seq[GenericTreeNode]): Seq[TreeResponse.Node] = { val (heads, tail) = nodesSorted.span(_.path.value.size == level) heads.map( - head ⇒ - Node(head.kind, - head.objectId, - head.index, - buildTree(level + 1, tail.filter(_.path.value.startsWith(head.path.value))))) + head ⇒ + Node(head.kind, + head.objectId, + head.index, + buildTree(level + 1, tail.filter(_.path.value.startsWith(head.path.value))))) } } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/GiftCardAdjustmentsResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/GiftCardAdjustmentsResponse.scala index 3a749928fb..150c8496be 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/GiftCardAdjustmentsResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/GiftCardAdjustmentsResponse.scala @@ -11,11 +11,10 @@ object GiftCardAdjustmentsResponse { cordRef: Option[String]) extends ResponseItem - def build(adj: GiftCardAdjustment, cordRef: Option[String] = None): Root = { + def build(adj: GiftCardAdjustment, cordRef: Option[String] = None): Root = Root(id = adj.id, amount = adj.getAmount, availableBalance = adj.availableBalance, state = adj.state, cordRef = cordRef) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/GiftCardBulkResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/GiftCardBulkResponse.scala index 473728a096..522d743df9 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/GiftCardBulkResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/GiftCardBulkResponse.scala @@ -10,8 +10,7 @@ object GiftCardBulkResponse { extends ResponseItem def buildItemResult(result: Either[Failures, GiftCardResponse.Root], - code: Option[String] = None): ItemResult = { + code: Option[String] = None): ItemResult = result.fold(errors ⇒ ItemResult(code = code, errors = Some(errors.flatten)), gc ⇒ ItemResult(code = code, success = true, giftCard = Some(gc))) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/GiftCardResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/GiftCardResponse.scala index f6f9d7e8e2..df101051dc 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/GiftCardResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/GiftCardResponse.scala @@ -34,24 +34,24 @@ object GiftCardResponse { customer: Option[CustomerResponse.Root] = None, admin: Option[UserResponse.Root] = None): Root = Root( - id = gc.id, - createdAt = gc.createdAt, - code = gc.code, - originId = gc.originId, - originType = gc.originType, - subTypeId = gc.subTypeId, - state = gc.state, - currency = gc.currency, - originalBalance = gc.originalBalance, - availableBalance = gc.availableBalance, - currentBalance = gc.currentBalance, - canceledAmount = gc.canceledAmount, - canceledReason = gc.canceledReason, - customer = customer, - storeAdmin = admin, - senderName = gc.senderName, - recipientName = gc.recipientName, - recipientEmail = gc.recipientEmail, - message = gc.message + id = gc.id, + createdAt = gc.createdAt, + code = gc.code, + originId = gc.originId, + originType = gc.originType, + subTypeId = gc.subTypeId, + state = gc.state, + currency = gc.currency, + originalBalance = gc.originalBalance, + availableBalance = gc.availableBalance, + currentBalance = gc.currentBalance, + canceledAmount = gc.canceledAmount, + canceledReason = gc.canceledReason, + customer = customer, + storeAdmin = admin, + senderName = gc.senderName, + recipientName = gc.recipientName, + recipientEmail = gc.recipientEmail, + message = gc.message ) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/GiftCardSubTypesResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/GiftCardSubTypesResponse.scala index d11de8637d..0f43b466d1 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/GiftCardSubTypesResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/GiftCardSubTypesResponse.scala @@ -3,12 +3,10 @@ package phoenix.responses import phoenix.models.payment.giftcard.{GiftCard, GiftCardSubtype} object GiftCardSubTypesResponse { - case class Root(originType: GiftCard.OriginType, subTypes: Seq[GiftCardSubtype]) - extends ResponseItem + case class Root(originType: GiftCard.OriginType, subTypes: Seq[GiftCardSubtype]) extends ResponseItem - def build(originTypes: Seq[GiftCard.OriginType], subTypes: Seq[GiftCardSubtype]): Seq[Root] = { + def build(originTypes: Seq[GiftCard.OriginType], subTypes: Seq[GiftCardSubtype]): Seq[Root] = originTypes.map { originType ⇒ Root(originType, subTypes.filter(_.originType == originType)) } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/GroupResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/GroupResponse.scala index 0fe1895d5e..58c6b7c4d5 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/GroupResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/GroupResponse.scala @@ -22,14 +22,16 @@ object GroupResponses { ) extends ResponseItem def build(group: CustomerGroup): Root = - Root(id = group.id, - name = group.name, - groupType = group.groupType, - clientState = group.clientState, - elasticRequest = group.elasticRequest, - customersCount = group.customersCount, - updatedAt = group.updatedAt, - createdAt = group.createdAt) + Root( + id = group.id, + name = group.name, + groupType = group.groupType, + clientState = group.clientState, + elasticRequest = group.elasticRequest, + customersCount = group.customersCount, + updatedAt = group.updatedAt, + createdAt = group.createdAt + ) } object CustomerGroupResponse { @@ -47,11 +49,13 @@ object GroupResponses { elasticRequest: Json) def build(groupTemplate: CustomerGroupTemplate): Root = - Root(id = groupTemplate.id, - name = groupTemplate.name, - groupType = CustomerGroup.Template, - clientState = groupTemplate.clientState, - elasticRequest = groupTemplate.elasticRequest) + Root( + id = groupTemplate.id, + name = groupTemplate.name, + groupType = CustomerGroup.Template, + clientState = groupTemplate.clientState, + elasticRequest = groupTemplate.elasticRequest + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/ImageResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/ImageResponses.scala index 3413d6fb5d..ac9c220307 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/ImageResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/ImageResponses.scala @@ -9,11 +9,7 @@ object ImageResponses { implicit val formats = JsonFormatters.phoenixFormats object ImageResponse { - case class Root(id: Int, - src: String, - baseUrl: Option[String], - title: Option[String], - alt: Option[String]) + case class Root(id: Int, src: String, baseUrl: Option[String], title: Option[String], alt: Option[String]) extends ResponseItem def build(id: Int, diff --git a/phoenix-scala/phoenix/app/phoenix/responses/ProductResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/ProductResponses.scala index 062091eceb..c54b753de4 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/ProductResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/ProductResponses.scala @@ -39,14 +39,16 @@ object ProductResponses { skus: Seq[SkuResponse.Root], variants: Seq[IlluminatedVariantResponse.Root], taxons: Seq[AssignedTaxonsResponse]): Root = - Root(id = product.id, - slug = product.slug, - attributes = product.attributes, - context = ObjectContextResponse.build(product.context), - albums = albums, - skus = skus, - variants = variants, - archivedAt = product.archivedAt, - taxons = taxons) + Root( + id = product.id, + slug = product.slug, + attributes = product.attributes, + context = ObjectContextResponse.build(product.context), + albums = albums, + skus = skus, + variants = variants, + archivedAt = product.archivedAt, + taxons = taxons + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/ProductReviewResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/ProductReviewResponses.scala index 17a959cad1..32d289a6d8 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/ProductReviewResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/ProductReviewResponses.scala @@ -7,7 +7,6 @@ object ProductReviewResponses { def build(review: ProductReview, skuCode: String): ProductReviewResponse = ProductReviewResponse(review.id, skuCode, review.userId, review.content) - case class ProductReviewResponse(id: Int, sku: String, userId: Int, attributes: Json) - extends ResponseItem + case class ProductReviewResponse(id: Int, sku: String, userId: Int, attributes: Json) extends ResponseItem } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/PromotionResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/PromotionResponses.scala index 8bc5bebe77..8c061aa8a4 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/PromotionResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/PromotionResponses.scala @@ -29,15 +29,15 @@ object PromotionResponses { archivedAt: Option[Instant]) extends ResponseItem - def build(promotion: IlluminatedPromotion, - discounts: Seq[IlluminatedDiscount], - promo: Promotion): Root = - Root(id = promotion.id, - context = ObjectContextResponse.build(promotion.context), - applyType = promotion.applyType, - attributes = promotion.attributes, - discounts = discounts.map(d ⇒ IlluminatedDiscountResponse.build(d)), - archivedAt = promo.archivedAt) + def build(promotion: IlluminatedPromotion, discounts: Seq[IlluminatedDiscount], promo: Promotion): Root = + Root( + id = promotion.id, + context = ObjectContextResponse.build(promotion.context), + applyType = promotion.applyType, + attributes = promotion.attributes, + discounts = discounts.map(d ⇒ IlluminatedDiscountResponse.build(d)), + archivedAt = promo.archivedAt + ) def build(context: ObjectContext, promotion: Promotion, diff --git a/phoenix-scala/phoenix/app/phoenix/responses/PublicResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/PublicResponses.scala index 34c4125b03..3808c37cf7 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/PublicResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/PublicResponses.scala @@ -17,7 +17,7 @@ object PublicResponses { object CountryWithRegions { val jsonFormat = new CustomSerializer[CountryWithRegions](format ⇒ - ({ + ({ case json: JObject ⇒ val country = json.extract[Country] val regions = (json \ "regions").extract[Seq[Region]] diff --git a/phoenix-scala/phoenix/app/phoenix/responses/ReturnResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/ReturnResponse.scala index 947993e5f4..cbbc769489 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/ReturnResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/ReturnResponse.scala @@ -16,11 +16,7 @@ import phoenix.services.carts.CartTotaler import phoenix.services.returns.{ReturnLineItemManager, ReturnTotaler} object ReturnResponse { - case class ReturnTotals(subTotal: Long, - taxes: Long, - shipping: Long, - adjustments: Long, - total: Long) + case class ReturnTotals(subTotal: Long, taxes: Long, shipping: Long, adjustments: Long, total: Long) extends ResponseItem sealed trait LineItem extends ResponseItem { @@ -88,25 +84,22 @@ object ReturnResponse { giftCard: Option[(ReturnPayment, GiftCard)], storeCredit: Option[ReturnPayment]): Payments = Payments( - creditCard = - creditCard.map(cc ⇒ Payment.CreditCard(cc.paymentMethodId, cc.amount, cc.currency)), - applePay = applePay.map(ap ⇒ Payment.ApplePay(ap.paymentMethodId, ap.amount, ap.currency)), - giftCard = giftCard.map { - case (p, gc) ⇒ Payment.GiftCard(p.paymentMethodId, gc.code, p.amount, p.currency) - }, - storeCredit = - storeCredit.map(sc ⇒ Payment.StoreCredit(sc.paymentMethodId, sc.amount, sc.currency)) + creditCard = creditCard.map(cc ⇒ Payment.CreditCard(cc.paymentMethodId, cc.amount, cc.currency)), + applePay = applePay.map(ap ⇒ Payment.ApplePay(ap.paymentMethodId, ap.amount, ap.currency)), + giftCard = giftCard.map { + case (p, gc) ⇒ Payment.GiftCard(p.paymentMethodId, gc.code, p.amount, p.currency) + }, + storeCredit = storeCredit.map(sc ⇒ Payment.StoreCredit(sc.paymentMethodId, sc.amount, sc.currency)) ) - def buildTotals(subTotal: Long, shipping: Long, adjustments: Long, taxes: Long): ReturnTotals = { + def buildTotals(subTotal: Long, shipping: Long, adjustments: Long, taxes: Long): ReturnTotals = ReturnTotals(subTotal = subTotal, shipping = shipping, adjustments = adjustments, taxes = taxes, total = subTotal + shipping + taxes - adjustments) - } - def fromRma(rma: Return)(implicit ec: EC, db: DB): DbResultT[Root] = { + def fromRma(rma: Return)(implicit ec: EC, db: DB): DbResultT[Root] = for { // Either customer or storeAdmin as creator customer ← * <~ Users.findOneByAccountId(rma.accountId) @@ -131,26 +124,23 @@ object ReturnResponse { adjustments = adjustments) } yield build( - rma = rma, - customer = for { - c ← customer - cu ← customerData - } yield CustomerResponse.build(c, cu), - storeAdmin = for { - a ← storeAdmin - au ← adminData - } yield StoreAdminResponse.build(a, au), - payments = buildPayments(creditCard = ccPayment, - applePay = applePayPayment, - giftCard = gcPayment, - storeCredit = scPayment), - lineItems = LineItems(skus = lineItems, shippingCosts = shippingCosts), - totals = buildTotals(subTotal = subTotal, - shipping = shipping, - adjustments = adjustments, - taxes = taxes) + rma = rma, + customer = for { + c ← customer + cu ← customerData + } yield CustomerResponse.build(c, cu), + storeAdmin = for { + a ← storeAdmin + au ← adminData + } yield StoreAdminResponse.build(a, au), + payments = buildPayments(creditCard = ccPayment, + applePay = applePayPayment, + giftCard = gcPayment, + storeCredit = scPayment), + lineItems = LineItems(skus = lineItems, shippingCosts = shippingCosts), + totals = + buildTotals(subTotal = subTotal, shipping = shipping, adjustments = adjustments, taxes = taxes) ) - } def build(rma: Return, customer: Option[Customer] = None, @@ -158,18 +148,20 @@ object ReturnResponse { lineItems: LineItems = LineItems(List.empty, Option.empty), payments: Payments = Payments(Option.empty, Option.empty, Option.empty, Option.empty), totals: ReturnTotals = ReturnTotals(0, 0, 0, 0, 0)): Root = - Root(id = rma.id, - referenceNumber = rma.refNum, - orderRefNum = rma.orderRef, - rmaType = rma.returnType, - state = rma.state, - customer = customer, - storeAdmin = storeAdmin, - payments = payments, - lineItems = lineItems, - messageToCustomer = rma.messageToAccount, - canceledReasonId = rma.canceledReasonId, - createdAt = rma.createdAt, - updatedAt = rma.updatedAt, - totals = totals) + Root( + id = rma.id, + referenceNumber = rma.refNum, + orderRefNum = rma.orderRef, + rmaType = rma.returnType, + state = rma.state, + customer = customer, + storeAdmin = storeAdmin, + payments = payments, + lineItems = lineItems, + messageToCustomer = rma.messageToAccount, + canceledReasonId = rma.canceledReasonId, + createdAt = rma.createdAt, + updatedAt = rma.updatedAt, + totals = totals + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/SaveForLaterResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/SaveForLaterResponse.scala index 7196ebdf7e..c7ef57579a 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/SaveForLaterResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/SaveForLaterResponse.scala @@ -28,8 +28,7 @@ object SaveForLaterResponse { for { sfl ← * <~ SaveForLaters .filter(_.skuId === skuId) - .mustFindOneOr( - NotFoundFailure404(s"Save for later entry for sku with id=$skuId not found")) + .mustFindOneOr(NotFoundFailure404(s"Save for later entry for sku with id=$skuId not found")) sku ← * <~ Skus.mustFindById404(skuId) form ← * <~ ObjectForms.mustFindById404(sku.formId) shadow ← * <~ ObjectShadows.mustFindById404(sku.shadowId) @@ -37,10 +36,10 @@ object SaveForLaterResponse { def build(sfl: SaveForLater, sku: Sku, form: ObjectForm, shadow: ObjectShadow): Root = Root( - id = sfl.id, - name = FormShadowGet.title(form, shadow), - sku = sku.code, - price = FormShadowGet.priceAsLong(form, shadow), - createdAt = sfl.createdAt + id = sfl.id, + name = FormShadowGet.title(form, shadow), + sku = sku.code, + price = FormShadowGet.priceAsLong(form, shadow), + createdAt = sfl.createdAt ) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/ShippingMethodsResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/ShippingMethodsResponse.scala index 9faa5ce902..be1346649d 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/ShippingMethodsResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/ShippingMethodsResponse.scala @@ -3,8 +3,7 @@ package phoenix.responses import phoenix.models.shipping.ShippingMethod object ShippingMethodsResponse { - case class Root(id: Int, name: String, code: String, price: Long, isEnabled: Boolean) - extends ResponseItem + case class Root(id: Int, name: String, code: String, price: Long, isEnabled: Boolean) extends ResponseItem def build(record: ShippingMethod, isEnabled: Boolean = true): Root = Root(id = record.id, diff --git a/phoenix-scala/phoenix/app/phoenix/responses/SkuResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/SkuResponses.scala index 930a22db69..82e5986d2f 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/SkuResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/SkuResponses.scala @@ -23,8 +23,7 @@ object SkuResponses { object SkuFormResponse { - case class Root(id: Int, code: String, attributes: Json, createdAt: Instant) - extends ResponseItem + case class Root(id: Int, code: String, attributes: Json, createdAt: Instant) extends ResponseItem def build(sku: Sku, form: ObjectForm): Root = Root(id = form.id, code = sku.code, attributes = form.attributes, createdAt = form.createdAt) @@ -63,9 +62,7 @@ object SkuResponses { def buildLite(s: IlluminatedSku): Root = Root(code = s.code, attributes = s.attributes, context = None, albums = Seq.empty) - def buildLite(ctx: ObjectContext, - sku: FullObject[Sku], - albums: Seq[AlbumResponse.Root]): Root = { + def buildLite(ctx: ObjectContext, sku: FullObject[Sku], albums: Seq[AlbumResponse.Root]): Root = { val illuminatedSku = IlluminatedSku.illuminate(ctx, sku) Root(code = illuminatedSku.code, attributes = illuminatedSku.attributes, @@ -81,13 +78,8 @@ object SkuResponses { form: SkuFormResponse.Root, shadow: SkuShadowResponse.Root) - def build(form: SkuFormResponse.Root, - shadow: SkuShadowResponse.Root, - context: ObjectContext): Root = - Root(code = shadow.code, - form = form, - shadow = shadow, - context = ObjectContextResponse.build(context)) + def build(form: SkuFormResponse.Root, shadow: SkuShadowResponse.Root, context: ObjectContext): Root = + Root(code = shadow.code, form = form, shadow = shadow, context = ObjectContextResponse.build(context)) } object SkuResponse { diff --git a/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditAdjustmentsResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditAdjustmentsResponse.scala index a09c4f459f..9ed6c98eb8 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditAdjustmentsResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditAdjustmentsResponse.scala @@ -14,12 +14,11 @@ object StoreCreditAdjustmentsResponse { cordRef: Option[String]) extends ResponseItem - def build(adj: StoreCreditAdjustment, cordRef: Option[String] = None): Root = { + def build(adj: StoreCreditAdjustment, cordRef: Option[String] = None): Root = Root(id = adj.id, createdAt = adj.createdAt, debit = adj.debit, availableBalance = adj.availableBalance, state = adj.state, cordRef = cordRef) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditBulkResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditBulkResponse.scala index 70512a80f5..1b1f8e22d4 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditBulkResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditBulkResponse.scala @@ -9,8 +9,7 @@ object StoreCreditBulkResponse { errors: Option[List[String]] = None) extends ResponseItem - def buildItemResult(id: Int, result: Either[Failures, StoreCreditResponse.Root]): ItemResult = { + def buildItemResult(id: Int, result: Either[Failures, StoreCreditResponse.Root]): ItemResult = result.fold(errors ⇒ ItemResult(id = id, errors = Some(errors.flatten)), sc ⇒ ItemResult(id = id, success = true, storeCredit = Some(sc))) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditResponse.scala index 3b285e48e4..2c7a96b736 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditResponse.scala @@ -27,19 +27,20 @@ object StoreCreditResponse { def build(records: Seq[StoreCredit]): Seq[Root] = records.map(build) - def build(storeCredit: StoreCredit): Root = { - Root(id = storeCredit.id, - originId = storeCredit.originId, - originType = storeCredit.originType, - subTypeId = storeCredit.subTypeId, - currency = storeCredit.currency, - customerId = storeCredit.accountId, - originalBalance = storeCredit.originalBalance, - currentBalance = storeCredit.currentBalance, - availableBalance = storeCredit.availableBalance, - canceledAmount = storeCredit.canceledAmount, - canceledReason = storeCredit.canceledReason, - state = storeCredit.state, - createdAt = storeCredit.createdAt) - } + def build(storeCredit: StoreCredit): Root = + Root( + id = storeCredit.id, + originId = storeCredit.originId, + originType = storeCredit.originType, + subTypeId = storeCredit.subTypeId, + currency = storeCredit.currency, + customerId = storeCredit.accountId, + originalBalance = storeCredit.originalBalance, + currentBalance = storeCredit.currentBalance, + availableBalance = storeCredit.availableBalance, + canceledAmount = storeCredit.canceledAmount, + canceledReason = storeCredit.canceledReason, + state = storeCredit.state, + createdAt = storeCredit.createdAt + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditSubTypesResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditSubTypesResponse.scala index 54bcf425c6..06d177da50 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditSubTypesResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/StoreCreditSubTypesResponse.scala @@ -3,13 +3,10 @@ package phoenix.responses import phoenix.models.payment.storecredit.{StoreCredit, StoreCreditSubtype} object StoreCreditSubTypesResponse { - case class Root(originType: StoreCredit.OriginType, subTypes: Seq[StoreCreditSubtype]) - extends ResponseItem + case class Root(originType: StoreCredit.OriginType, subTypes: Seq[StoreCreditSubtype]) extends ResponseItem - def build(originTypes: Seq[StoreCredit.OriginType], - subTypes: Seq[StoreCreditSubtype]): Seq[Root] = { + def build(originTypes: Seq[StoreCredit.OriginType], subTypes: Seq[StoreCreditSubtype]): Seq[Root] = originTypes.map { originType ⇒ Root(originType, subTypes.filter(_.originType == originType)) } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/TaxonResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/TaxonResponses.scala index 6f1a9ab34c..1f5adff9d1 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/TaxonResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/TaxonResponses.scala @@ -17,9 +17,8 @@ object TaxonResponses { case list ⇒ list.size } - def parentOf(other: LTree): Boolean = { + def parentOf(other: LTree): Boolean = if (level == 0) other.level == 1 else other.value.startsWith(ltree.value) - } } case class AssignedTaxonsResponse(taxonomyId: Int, @@ -29,8 +28,7 @@ object TaxonResponses { extends ResponseItem object AssignedTaxonsResponse { - def build(taxonomy: FullObject[Taxonomy], - taxons: Seq[FullObject[Taxon]]): AssignedTaxonsResponse = { + def build(taxonomy: FullObject[Taxonomy], taxons: Seq[FullObject[Taxon]]): AssignedTaxonsResponse = { val taxonAttributes = IlluminateAlgorithm.projectAttributes(taxonomy.form.attributes, taxonomy.shadow.attributes) @@ -50,22 +48,15 @@ object TaxonResponses { case class TaxonLocationResponse(parent: Option[Int] = None) extends ResponseItem - case class FullTaxonResponse(id: Int, - taxonomyId: Int, - location: TaxonLocationResponse, - attributes: JValue) + case class FullTaxonResponse(id: Int, taxonomyId: Int, location: TaxonLocationResponse, attributes: JValue) extends ResponseItem object FullTaxonResponse { - def build(taxon: FullObject[Taxon], - taxonomyId: Int, - parentId: Option[Int] = None): FullTaxonResponse = { - FullTaxonResponse( - taxon.model.formId, - taxonomyId, - TaxonLocationResponse(parentId), - IlluminateAlgorithm.projectAttributes(taxon.form.attributes, taxon.shadow.attributes)) - } + def build(taxon: FullObject[Taxon], taxonomyId: Int, parentId: Option[Int] = None): FullTaxonResponse = + FullTaxonResponse(taxon.model.formId, + taxonomyId, + TaxonLocationResponse(parentId), + IlluminateAlgorithm.projectAttributes(taxon.form.attributes, taxon.shadow.attributes)) } case class TaxonTreeResponse(node: FullTaxonResponse, children: Option[Seq[TaxonTreeResponse]]) @@ -74,9 +65,8 @@ object TaxonResponses { } object TaxonTreeResponse { - def build(taxon: FullTaxonResponse, children: Seq[TaxonTreeResponse]): TaxonTreeResponse = { + def build(taxon: FullTaxonResponse, children: Seq[TaxonTreeResponse]): TaxonTreeResponse = TaxonTreeResponse(taxon, children.some.filterNot(_.isEmpty)) - } def buildTree(nodes: Seq[LinkedTaxon], taxonomyId: Int): Seq[TaxonTreeResponse] = buildTree(0, nodes.sortBy { case (_, link) ⇒ link.path.level }, taxonomyId) diff --git a/phoenix-scala/phoenix/app/phoenix/responses/TaxonomyResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/TaxonomyResponses.scala index 9879abc8b2..ac45f10e4b 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/TaxonomyResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/TaxonomyResponses.scala @@ -22,12 +22,12 @@ object TaxonomyResponses { extends ResponseItem object FullTaxonomyResponse { - def build(taxonomy: FullObject[Taxonomy], taxons: Seq[LinkedTaxon]): FullTaxonomyResponse = { - FullTaxonomyResponse(taxonomy.model.formId, - taxonomy.model.hierarchical, - IlluminateAlgorithm.projectAttributes(taxonomy.form.attributes, - taxonomy.shadow.attributes), - TaxonTreeResponse.buildTree(taxons, taxonomy.model.formId)) - } + def build(taxonomy: FullObject[Taxonomy], taxons: Seq[LinkedTaxon]): FullTaxonomyResponse = + FullTaxonomyResponse( + taxonomy.model.formId, + taxonomy.model.hierarchical, + IlluminateAlgorithm.projectAttributes(taxonomy.form.attributes, taxonomy.shadow.attributes), + TaxonTreeResponse.buildTree(taxons, taxonomy.model.formId) + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/TheResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/TheResponse.scala index 7b3918c32d..590c5b484f 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/TheResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/TheResponse.scala @@ -44,16 +44,16 @@ object TheResponse { def combineBatch(a: BatchMetadata, b: BatchMetadata): BatchMetadata = BatchMetadata(success = a.success ++ b.success, failures = a.failures ++ b.failures) TheResponse( - result = fb.result, - alerts = combineOL(fa.alerts, fb.alerts), - errors = combineOL(fa.errors, fb.errors), - warnings = combineOL(fa.warnings, fb.warnings), - batch = (fa.batch, fb.batch) match { - case (Some(a), Some(b)) ⇒ Some(combineBatch(a, b)) - case (oa, None) ⇒ oa - case (None, ob) ⇒ ob - case _ ⇒ None - } + result = fb.result, + alerts = combineOL(fa.alerts, fb.alerts), + errors = combineOL(fa.errors, fb.errors), + warnings = combineOL(fa.warnings, fb.warnings), + batch = (fa.batch, fb.batch) match { + case (Some(a), Some(b)) ⇒ Some(combineBatch(a, b)) + case (oa, None) ⇒ oa + case (None, ob) ⇒ ob + case _ ⇒ None + } ) } @@ -107,7 +107,6 @@ object BatchMetadata { case class BatchMetadataSource(className: String, success: SuccessData, failures: FailureData) object BatchMetadataSource { - def apply[A](model: A, success: SuccessData, failures: FailureData): BatchMetadataSource = { + def apply[A](model: A, success: SuccessData, failures: FailureData): BatchMetadataSource = BatchMetadataSource(friendlyClassName(model), success, failures) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/UserResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/UserResponse.scala index ccae8d4b4c..9392c52cbe 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/UserResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/UserResponse.scala @@ -14,15 +14,16 @@ object UserResponse { isBlacklisted: Boolean) extends ResponseItem - def build(user: User): Root = { - Root(id = user.accountId, - email = user.email, - name = user.name, - phoneNumber = user.phoneNumber, - createdAt = user.createdAt, - disabled = user.isDisabled, - isBlacklisted = user.isBlacklisted) - } + def build(user: User): Root = + Root( + id = user.accountId, + email = user.email, + name = user.name, + phoneNumber = user.phoneNumber, + createdAt = user.createdAt, + disabled = user.isDisabled, + isBlacklisted = user.isBlacklisted + ) case class ResetPasswordSendAnswer(status: String) diff --git a/phoenix-scala/phoenix/app/phoenix/responses/VariantResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/VariantResponses.scala index c08400e577..1b04e1d0c4 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/VariantResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/VariantResponses.scala @@ -21,10 +21,12 @@ object VariantResponses { def build(variant: IlluminatedVariant, variantValues: Seq[FullObject[VariantValue]], variantValueSkus: VariantValueSkuLinks): Root = - Root(id = variant.id, - attributes = variant.attributes, - context = ObjectContextResponse.build(variant.context).some, - values = illuminateValues(variantValues, variantValueSkus)) + Root( + id = variant.id, + attributes = variant.attributes, + context = ObjectContextResponse.build(variant.context).some, + values = illuminateValues(variantValues, variantValueSkus) + ) def buildLite(variant: IlluminatedVariant, variantValues: Seq[FullObject[VariantValue]], @@ -34,12 +36,11 @@ object VariantResponses { context = None, values = illuminateValues(variantValues, variantValueSkus)) - def illuminateValues( - variantValues: Seq[FullObject[VariantValue]], - variantValueSkus: VariantValueSkuLinks): Seq[IlluminatedVariantValueResponse.Root] = + def illuminateValues(variantValues: Seq[FullObject[VariantValue]], + variantValueSkus: VariantValueSkuLinks): Seq[IlluminatedVariantValueResponse.Root] = variantValues.map( - vv ⇒ - IlluminatedVariantValueResponse - .build(vv, variantValueSkus.getOrElse(vv.model.id, Seq.empty))) + vv ⇒ + IlluminatedVariantValueResponse + .build(vv, variantValueSkus.getOrElse(vv.model.id, Seq.empty))) } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/AllOrders.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/AllOrders.scala index 4867cb1ebc..1e62199d97 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/AllOrders.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/AllOrders.scala @@ -26,14 +26,14 @@ object AllOrders { def build(order: Order, customer: Option[User] = None, paymentState: Option[CordPaymentState.State] = None): Root = Root( - referenceNumber = order.referenceNumber, - orderState = order.state, - name = customer.flatMap(_.name), - email = customer.flatMap(_.email), - paymentState = paymentState, - shippingState = order.getShippingState, - placedAt = order.placedAt, - remorsePeriodEnd = order.getRemorsePeriodEnd, - total = order.grandTotal + referenceNumber = order.referenceNumber, + orderState = order.state, + name = customer.flatMap(_.name), + email = customer.flatMap(_.email), + paymentState = paymentState, + shippingState = order.getShippingState, + placedAt = order.placedAt, + remorsePeriodEnd = order.getRemorsePeriodEnd, + total = order.grandTotal ) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala index 14289b876a..d8db4d8627 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/AmazonOrderResponse.scala @@ -23,16 +23,18 @@ case class AmazonOrderResponse(id: Int, object AmazonOrderResponse { def build(amazonOrder: AmazonOrder): AmazonOrderResponse = - AmazonOrderResponse(id = amazonOrder.id, - amazonOrderId = amazonOrder.amazonOrderId, - orderTotal = amazonOrder.orderTotal, - paymentMethodDetail = amazonOrder.paymentMethodDetail, - orderType = amazonOrder.orderType, - currency = amazonOrder.currency, - orderStatus = amazonOrder.orderStatus, - purchaseDate = amazonOrder.purchaseDate, - scope = amazonOrder.scope, - accountId = amazonOrder.accountId, - createdAt = amazonOrder.createdAt, - updatedAt = amazonOrder.updatedAt) + AmazonOrderResponse( + id = amazonOrder.id, + amazonOrderId = amazonOrder.amazonOrderId, + orderTotal = amazonOrder.orderTotal, + paymentMethodDetail = amazonOrder.paymentMethodDetail, + orderType = amazonOrder.orderType, + currency = amazonOrder.currency, + orderStatus = amazonOrder.orderStatus, + purchaseDate = amazonOrder.purchaseDate, + scope = amazonOrder.scope, + accountId = amazonOrder.accountId, + createdAt = amazonOrder.createdAt, + updatedAt = amazonOrder.updatedAt + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/CartResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/CartResponse.scala index b1a7a8fcd8..3f43de6dc1 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/CartResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/CartResponse.scala @@ -33,10 +33,9 @@ object CartResponse { def buildRefreshed(cart: Cart)(implicit db: DB, ec: EC, ctx: OC): DbResultT[CartResponse] = Carts.refresh(cart).dbresult.flatMap(c ⇒ fromCart(c, grouped = true)) - def fromCart(cart: Cart, grouped: Boolean, isGuest: Boolean = false)( - implicit db: DB, - ec: EC, - ctx: OC): DbResultT[CartResponse] = + def fromCart(cart: Cart, grouped: Boolean, isGuest: Boolean = false)(implicit db: DB, + ec: EC, + ctx: OC): DbResultT[CartResponse] = for { lineItemAdj ← * <~ CordResponseLineItemAdjustments.fetch(cart.refNum) lineItemsSku ← * <~ CartLineItems.byCordRef(cart.refNum).result @@ -60,36 +59,34 @@ object CartResponse { .result } yield CartResponse( - referenceNumber = cart.refNum, - lineItems = lineItems, - lineItemAdjustments = lineItemAdj, - promotion = promo.map { case (promotion, _) ⇒ promotion }, - coupon = promo.flatMap { case (_, coupon) ⇒ coupon }, - totals = - CartResponseTotals.build(cart, coveredByInStoreMethods = coveredByInStoreMethods), - customer = for { - c ← customer - cu ← customerData - } yield CustomerResponse.build(c, cu), - shippingMethod = shippingMethod, - shippingAddress = shippingAddress, - paymentMethods = paymentMethods, - paymentState = paymentState - ) - - def buildEmpty(cart: Cart, - customer: Option[User] = None, - customerData: Option[CustomerData] = None): CartResponse = { - CartResponse( referenceNumber = cart.refNum, - lineItems = CordResponseLineItems(), + lineItems = lineItems, + lineItemAdjustments = lineItemAdj, + promotion = promo.map { case (promotion, _) ⇒ promotion }, + coupon = promo.flatMap { case (_, coupon) ⇒ coupon }, + totals = CartResponseTotals.build(cart, coveredByInStoreMethods = coveredByInStoreMethods), customer = for { c ← customer cu ← customerData } yield CustomerResponse.build(c, cu), - totals = CartResponseTotals.empty, - paymentState = CordPaymentState.Cart + shippingMethod = shippingMethod, + shippingAddress = shippingAddress, + paymentMethods = paymentMethods, + paymentState = paymentState + ) + + def buildEmpty(cart: Cart, + customer: Option[User] = None, + customerData: Option[CustomerData] = None): CartResponse = + CartResponse( + referenceNumber = cart.refNum, + lineItems = CordResponseLineItems(), + customer = for { + c ← customer + cu ← customerData + } yield CustomerResponse.build(c, cu), + totals = CartResponseTotals.empty, + paymentState = CordPaymentState.Cart ) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/OrderResponse.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/OrderResponse.scala index 1df81f81a7..04667735d5 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/OrderResponse.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/OrderResponse.scala @@ -37,14 +37,12 @@ case class OrderResponse(referenceNumber: String, object OrderResponse { private def getCreditCardResponse( - paymentMethods: Seq[_ <: CordResponsePayments]): Option[CordResponseCreditCardPayment] = { + paymentMethods: Seq[_ <: CordResponsePayments]): Option[CordResponseCreditCardPayment] = paymentMethods.collectFirst { case ccPayment: CordResponseCreditCardPayment ⇒ ccPayment } - } - def fromOrder(order: Order, grouped: Boolean)(implicit db: DB, - ec: EC): DbResultT[OrderResponse] = + def fromOrder(order: Order, grouped: Boolean)(implicit db: DB, ec: EC): DbResultT[OrderResponse] = for { context ← * <~ ObjectContexts.mustFindById400(order.contextId) payState ← * <~ OrderQueries.getCordPaymentState(order.refNum) @@ -61,27 +59,27 @@ object OrderResponse { ccResponse = getCreditCardResponse(paymentMethods) } yield OrderResponse( - referenceNumber = order.refNum, - paymentState = payState, - lineItems = lineItems, - lineItemAdjustments = lineItemAdj, - promotion = promo.map { case (promotion, _) ⇒ promotion }, - coupon = promo.flatMap { case (_, coupon) ⇒ coupon }, - totals = OrderResponseTotals.build(order), - customer = for { - c ← customer - cu ← customerData - } yield CustomerResponse.build(c, cu), - shippingMethod = shippingMethod, - shippingAddress = shippingAddress, - billingCreditCardInfo = ccResponse, - billingAddress = ccResponse.map(_.address), - paymentMethods = paymentMethods, - orderState = order.state, - shippingState = order.getShippingState, - fraudScore = order.fraudScore, - remorsePeriodEnd = order.remorsePeriodEnd, - placedAt = order.placedAt + referenceNumber = order.refNum, + paymentState = payState, + lineItems = lineItems, + lineItemAdjustments = lineItemAdj, + promotion = promo.map { case (promotion, _) ⇒ promotion }, + coupon = promo.flatMap { case (_, coupon) ⇒ coupon }, + totals = OrderResponseTotals.build(order), + customer = for { + c ← customer + cu ← customerData + } yield CustomerResponse.build(c, cu), + shippingMethod = shippingMethod, + shippingAddress = shippingAddress, + billingCreditCardInfo = ccResponse, + billingAddress = ccResponse.map(_.address), + paymentMethods = paymentMethods, + orderState = order.state, + shippingState = order.getShippingState, + fraudScore = order.fraudScore, + remorsePeriodEnd = order.remorsePeriodEnd, + placedAt = order.placedAt ) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseLineItems.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseLineItems.scala index 723f4f72df..273de542c1 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseLineItems.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseLineItems.scala @@ -34,16 +34,15 @@ object CordResponseLineItems { if (grouped) fetchLineItems(cordRef, adjustments, cordLineItemsFromOrderGrouped) else fetchLineItems(cordRef, adjustments, cordLineItemsFromOrder) - def fetchCart(cordRef: String, - adjustments: Seq[CordResponseLineItemAdjustment], - grouped: Boolean)(implicit ec: EC, db: DB): DbResultT[CordResponseLineItems] = + def fetchCart(cordRef: String, adjustments: Seq[CordResponseLineItemAdjustment], grouped: Boolean)( + implicit ec: EC, + db: DB): DbResultT[CordResponseLineItems] = if (grouped) fetchLineItems(cordRef, adjustments, cordLineItemsFromCartGrouped) else fetchLineItems(cordRef, adjustments, cordLineItemsFromCart) def fetchLineItems(cordRef: String, adjustments: Seq[CordResponseLineItemAdjustment], - readLineItems: (String, - AdjustmentMap) ⇒ DbResultT[Seq[CordResponseLineItem]])( + readLineItems: (String, AdjustmentMap) ⇒ DbResultT[Seq[CordResponseLineItem]])( implicit ec: EC, db: DB): DbResultT[CordResponseLineItems] = { val adjustmentMap = mapAdjustments(adjustments) @@ -58,11 +57,10 @@ object CordResponseLineItems { result ← * <~ li.map(data ⇒ createResponse(data, Seq(data.lineItemReferenceNumber), 1)) } yield result - def cordLineItemsGrouped(lineItems: Seq[LineItemProductData[_]], - cordRef: String, - adjustmentMap: AdjustmentMap)( - implicit ec: EC, - db: DB): DbResultT[Seq[CordResponseLineItem]] = + def cordLineItemsGrouped( + lineItems: Seq[LineItemProductData[_]], + cordRef: String, + adjustmentMap: AdjustmentMap)(implicit ec: EC, db: DB): DbResultT[Seq[CordResponseLineItem]] = for { _ ← * <~ lineItems.map(data ⇒ createResponse(data, Seq(data.lineItemReferenceNumber), 1)) result ← * <~ lineItems @@ -94,16 +92,14 @@ object CordResponseLineItems { db: DB): DbResultT[Seq[CordResponseLineItem]] = for { lineItems ← * <~ LineItemManager.getCartLineItems(cordRef) - result ← * <~ lineItems.map(data ⇒ - createResponse(data, Seq(data.lineItemReferenceNumber), 1)) + result ← * <~ lineItems.map(data ⇒ createResponse(data, Seq(data.lineItemReferenceNumber), 1)) } yield result private val NOT_A_REF = "not_a_ref" - private def mapAdjustments(adjustments: Seq[CordResponseLineItemAdjustment]) - : Map[String, CordResponseLineItemAdjustment] = { + private def mapAdjustments( + adjustments: Seq[CordResponseLineItemAdjustment]): Map[String, CordResponseLineItemAdjustment] = adjustments.map(a ⇒ a.lineItemRefNum.getOrElse(NOT_A_REF) → a).toMap - } val NOT_ADJUSTED = "na" @@ -123,10 +119,9 @@ object CordResponseLineItems { val NO_IMAGE = "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/no_image.jpg" - private def createResponseGrouped(lineItemData: Seq[LineItemProductData[_]], - adjMap: Map[String, CordResponseLineItemAdjustment])( - implicit ec: EC, - db: DB): CordResponseLineItem = { + private def createResponseGrouped( + lineItemData: Seq[LineItemProductData[_]], + adjMap: Map[String, CordResponseLineItemAdjustment])(implicit ec: EC, db: DB): CordResponseLineItem = { val data = lineItemData.head val referenceNumbers = lineItemData.map(_.lineItemReferenceNumber) @@ -134,9 +129,9 @@ object CordResponseLineItems { createResponse(data, referenceNumbers, lineItemData.length) } - private def createResponse(data: LineItemProductData[_], - referenceNumbers: Seq[String], - quantity: Int)(implicit ec: EC, db: DB): CordResponseLineItem = { + private def createResponse(data: LineItemProductData[_], referenceNumbers: Seq[String], quantity: Int)( + implicit ec: EC, + db: DB): CordResponseLineItem = { require(quantity > 0) val title = FormShadowGet.title(data.productForm, data.productShadow) @@ -146,18 +141,20 @@ object CordResponseLineItems { val externalId = FormShadowGet.externalId(data.skuForm, data.skuShadow) val trackInventory = FormShadowGet.trackInventory(data.skuForm, data.skuShadow) - CordResponseLineItem(imagePath = image, - sku = data.sku.code, - referenceNumbers = Seq(data.lineItemReferenceNumber), - state = data.lineItemState, - name = title, - price = price, - externalId = externalId, - trackInventory = trackInventory, - productFormId = data.productForm.id, - totalPrice = price, - quantity = quantity, - attributes = data.attributes) + CordResponseLineItem( + imagePath = image, + sku = data.sku.code, + referenceNumbers = Seq(data.lineItemReferenceNumber), + state = data.lineItemState, + name = title, + price = price, + externalId = externalId, + trackInventory = trackInventory, + productFormId = data.productForm.id, + totalPrice = price, + quantity = quantity, + attributes = data.attributes + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponsePayments.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponsePayments.scala index 15bb36f656..7e98a61703 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponsePayments.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponsePayments.scala @@ -47,16 +47,17 @@ object CordResponseCreditCardPayment { region ← creditCard.region } yield (creditCard, region)).result.map(_.map { case (creditCard, region) ⇒ - CordResponseCreditCardPayment(id = creditCard.id, - customerId = creditCard.accountId, - holderName = creditCard.holderName, - lastFour = creditCard.lastFour, - expMonth = creditCard.expMonth, - expYear = creditCard.expYear, - brand = creditCard.brand, - createdAt = creditCard.createdAt, - address = - AddressResponse.buildFromCreditCard(creditCard, region)) + CordResponseCreditCardPayment( + id = creditCard.id, + customerId = creditCard.accountId, + holderName = creditCard.holderName, + lastFour = creditCard.lastFour, + expMonth = creditCard.expMonth, + expYear = creditCard.expYear, + brand = creditCard.brand, + createdAt = creditCard.createdAt, + address = AddressResponse.buildFromCreditCard(creditCard, region) + ) }) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponsePromotions.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponsePromotions.scala index 17badf04e0..dc92689072 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponsePromotions.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponsePromotions.scala @@ -21,9 +21,7 @@ case class CordResponseCouponPair(coupon: CouponResponse.Root, code: String) ext object CordResponsePromotions { - def fetch(cordRef: String)(implicit db: DB, - ec: EC, - ctx: OC): DbResultT[Option[CordResponsePromoDetails]] = + def fetch(cordRef: String)(implicit db: DB, ec: EC, ctx: OC): DbResultT[Option[CordResponsePromoDetails]] = for { orderPromo ← * <~ OrderPromotions.filterByCordRef(cordRef).one promo ← * <~ fetchPromoDetails(orderPromo) @@ -36,15 +34,13 @@ object CordResponsePromotions { // FIXME: how to compose this better without laziness? This is awful. :/ @michalrus val coupon = orderPromo.flatTraverse(_.couponCodeId.traverse(fetchCoupon)) lazy val auto = orderPromo.traverse(x ⇒ fetchAutoApply(x.promotionShadowId)) - lazyOrElse(fa = coupon.map(_.map { case (a, b) ⇒ (a, b.some) }), - fb = auto.map(_.map((_, none)))) + lazyOrElse(fa = coupon.map(_.map { case (a, b) ⇒ (a, b.some) }), fb = auto.map(_.map((_, none)))) } /** Try `fa` and if it’s `None`, evaluate and fallback to `fb`. Basically, `Option#orElse` lifted to `DbResultT`. */ private def lazyOrElse[A](fa: DbResultT[Option[A]], fb: ⇒ DbResultT[Option[A]])( - implicit ec: EC): DbResultT[Option[A]] = { + implicit ec: EC): DbResultT[Option[A]] = fa.flatMap(_.map(a ⇒ DbResultT.pure(a.some)).getOrElse(fb)) - } private def renderPromotionResponse( promotion: Promotion)(implicit ec: EC, ctx: OC, db: DB): DbResultT[PromotionResponse.Root] = @@ -55,21 +51,18 @@ object CordResponsePromotions { discounts ← * <~ PromotionDiscountLinks.queryRightByLeft(promotion) // Illuminate theDiscounts = discounts.map(discount ⇒ - IlluminatedDiscount.illuminate(ctx.some, discount.form, discount.shadow)) + IlluminatedDiscount.illuminate(ctx.some, discount.form, discount.shadow)) thePromotion = IlluminatedPromotion.illuminate(ctx, promotion, promoForm, promoShadow) // Responses respPromo = PromotionResponse.build(thePromotion, theDiscounts, promotion) } yield respPromo - private def fetchAutoApply(promotionShadowId: Int)(implicit ec: EC, - db: DB, - ctx: OC): DbResultT[PromotionResponse.Root] = + private def fetchAutoApply( + promotionShadowId: Int)(implicit ec: EC, db: DB, ctx: OC): DbResultT[PromotionResponse.Root] = renderHistoricalPromotion(promotionShadowId) - private def renderHistoricalPromotion(promotionShadowId: Int)( - implicit ec: EC, - db: DB, - ctx: OC): DbResultT[PromotionResponse.Root] = { + private def renderHistoricalPromotion( + promotionShadowId: Int)(implicit ec: EC, db: DB, ctx: OC): DbResultT[PromotionResponse.Root] = for { promotionShadow ← * <~ ObjectShadows.mustFindById404(promotionShadowId) promotionFormId = promotionShadow.formId @@ -87,9 +80,8 @@ object CordResponsePromotions { // FIXME: https://foxcommerce.slack.com/archives/phoenix/p1489674138182180 @michalrus discounts ← * <~ PromotionDiscountLinks.queryRightByLeft(promotionHead) illuminatedDiscounts = discounts.map(discount ⇒ - IlluminatedDiscount.illuminate(ctx.some, discount.form, discount.shadow)) + IlluminatedDiscount.illuminate(ctx.some, discount.form, discount.shadow)) } yield PromotionResponse.build(illuminatedPromotion, illuminatedDiscounts, promotionHead) - } // TBD: Get discounts from cached field in `OrderPromotion` model private def fetchCoupon(couponCodeId: Int)( diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseShipping.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseShipping.scala index 8b1ab64ea3..a347c1823f 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseShipping.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseShipping.scala @@ -7,8 +7,7 @@ import slick.dbio.DBIO object CordResponseShipping { - def shippingMethod(cordRef: String)( - implicit ec: EC): DBIO[Option[ShippingMethodsResponse.Root]] = + def shippingMethod(cordRef: String)(implicit ec: EC): DBIO[Option[ShippingMethodsResponse.Root]] = ShippingMethods.forCordRef(cordRef).one.map(_.map(ShippingMethodsResponse.build(_))) def shippingAddress(cordRef: String)(implicit ec: EC): DbResultT[AddressResponse] = diff --git a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseTotals.scala b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseTotals.scala index 9f7ccd9476..c0c03d964b 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseTotals.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/cord/base/CordResponseTotals.scala @@ -3,11 +3,7 @@ package phoenix.responses.cord.base import phoenix.models.cord.{Cart, Order} import phoenix.responses.ResponseItem -case class OrderResponseTotals(subTotal: Long, - taxes: Long, - shipping: Long, - adjustments: Long, - total: Long) +case class OrderResponseTotals(subTotal: Long, taxes: Long, shipping: Long, adjustments: Long, total: Long) extends ResponseItem object OrderResponseTotals { @@ -34,11 +30,13 @@ object CartResponseTotals { def empty: CartResponseTotals = CartResponseTotals(0, 0, 0, 0, 0, 0) def build(cart: Cart, coveredByInStoreMethods: Long): CartResponseTotals = - CartResponseTotals(subTotal = cart.subTotal, - shipping = cart.shippingTotal, - adjustments = cart.adjustmentsTotal, - taxes = cart.taxesTotal, - total = cart.grandTotal, - customersExpenses = cart.grandTotal - coveredByInStoreMethods) + CartResponseTotals( + subTotal = cart.subTotal, + shipping = cart.shippingTotal, + adjustments = cart.adjustmentsTotal, + taxes = cart.taxesTotal, + total = cart.grandTotal, + customersExpenses = cart.grandTotal - coveredByInStoreMethods + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/responses/plugins/PluginCommonResponses.scala b/phoenix-scala/phoenix/app/phoenix/responses/plugins/PluginCommonResponses.scala index ffe759cdd5..0e536d2428 100644 --- a/phoenix-scala/phoenix/app/phoenix/responses/plugins/PluginCommonResponses.scala +++ b/phoenix-scala/phoenix/app/phoenix/responses/plugins/PluginCommonResponses.scala @@ -10,21 +10,19 @@ object PluginCommonResponses { case class RegisterAnswer(foundOrCreated: String, settings: SettingsValues) - def buildRegister(plugin: Plugin, foundOrCreated: db.FoundOrCreated): RegisterAnswer = { + def buildRegister(plugin: Plugin, foundOrCreated: db.FoundOrCreated): RegisterAnswer = RegisterAnswer(foundOrCreated = foundOrCreated.toString, settings = plugin.settings) - } case class SettingsUpdated(settings: SettingsValues) case class PluginInfo(name: String, description: String, version: String, createdAt: Instant) object PluginInfo { - def fromPlugin(plugin: Plugin): PluginInfo = { + def fromPlugin(plugin: Plugin): PluginInfo = PluginInfo(name = plugin.name, description = plugin.description, version = plugin.version, createdAt = plugin.createdAt) - } } case class PluginSettingsResponse(settings: SettingsValues, schema: SettingsSchema) diff --git a/phoenix-scala/phoenix/app/phoenix/routes/AuthRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/AuthRoutes.scala index 4fc4f24680..ac2b39583c 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/AuthRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/AuthRoutes.scala @@ -20,8 +20,7 @@ import phoenix.utils.http.JsonSupport._ object AuthRoutes { - def routes(defaultScope: LTree)(implicit ec: EC, db: DB, apis: Apis): Route = { - + def routes(defaultScope: LTree)(implicit ec: EC, db: DB, apis: Apis): Route = pathPrefix("public") { (post & path("login") & entity(as[LoginPayload])) { payload ⇒ onSuccess(Authenticator.authenticate(payload).runEmptyA.value) { result ⇒ // TODO: rethink discarding warnings here @michalrus @@ -30,42 +29,41 @@ object AuthRoutes { }, identity) } } ~ - activityContext(defaultScope) { implicit ac ⇒ - (post & path("send-password-reset") & pathEnd & entity(as[ResetPasswordSend])) { payload ⇒ - mutateOrFailures { - AccountManager.resetPasswordSend(payload.email) - } + activityContext(defaultScope) { implicit ac ⇒ + (post & path("send-password-reset") & pathEnd & entity(as[ResetPasswordSend])) { payload ⇒ + mutateOrFailures { + AccountManager.resetPasswordSend(payload.email) + } + } ~ + (post & path("reset-password") & pathEnd & entity(as[ResetPassword])) { payload ⇒ + mutateOrFailures { + AccountManager.resetPassword(code = payload.code, newPassword = payload.newPassword) + } + } } ~ - (post & path("reset-password") & pathEnd & entity(as[ResetPassword])) { payload ⇒ - mutateOrFailures { - AccountManager.resetPassword(code = payload.code, newPassword = payload.newPassword) + (post & path("logout")) { + deleteCookie("JWT", path = "/") { + redirect(Uri("/"), StatusCodes.Found) } - } - } ~ - (post & path("logout")) { - deleteCookie("JWT", path = "/") { - redirect(Uri("/"), StatusCodes.Found) - } - } ~ - activityContext(defaultScope) { implicit ac ⇒ - lazy val customerGoogleOauth = oauthServiceFromConfig(config.users.customer) - lazy val adminGoogleOauth = oauthServiceFromConfig(config.users.admin) - - (path("oauth2callback" / "google" / "admin") & get & oauthResponse) { - adminGoogleOauth.adminCallback - } ~ - (path("oauth2callback" / "google" / "customer") & get & oauthResponse) { - customerGoogleOauth.customerCallback } ~ - (path("signin" / "google" / "admin") & get) { - val url = adminGoogleOauth.authorizationUri(scope = Seq("openid", "email", "profile")) - complete(Map("url" → url)) - } ~ - (path("signin" / "google" / "customer") & get) { - val url = customerGoogleOauth.authorizationUri(scope = Seq("openid", "email", "profile")) - complete(Map("url" → url)) + activityContext(defaultScope) { implicit ac ⇒ + lazy val customerGoogleOauth = oauthServiceFromConfig(config.users.customer) + lazy val adminGoogleOauth = oauthServiceFromConfig(config.users.admin) + + (path("oauth2callback" / "google" / "admin") & get & oauthResponse) { + adminGoogleOauth.adminCallback + } ~ + (path("oauth2callback" / "google" / "customer") & get & oauthResponse) { + customerGoogleOauth.customerCallback + } ~ + (path("signin" / "google" / "admin") & get) { + val url = adminGoogleOauth.authorizationUri(scope = Seq("openid", "email", "profile")) + complete(Map("url" → url)) + } ~ + (path("signin" / "google" / "customer") & get) { + val url = customerGoogleOauth.authorizationUri(scope = Seq("openid", "email", "profile")) + complete(Map("url" → url)) + } } - } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/Customer.scala b/phoenix-scala/phoenix/app/phoenix/routes/Customer.scala index 2e567e4631..6cfb1126e2 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/Customer.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/Customer.scala @@ -14,7 +14,7 @@ import phoenix.payloads.LineItemPayloads.UpdateLineItemsPayload import phoenix.payloads.PaymentPayloads._ import phoenix.payloads.ProductReviewPayloads._ import phoenix.payloads.UpdateShippingMethod -import phoenix.services.Authenticator.{UserAuthenticator, requireCustomerAuth} +import phoenix.services.Authenticator.{requireCustomerAuth, UserAuthenticator} import phoenix.services._ import phoenix.services.carts._ import phoenix.services.customers.CustomerManager @@ -41,309 +41,303 @@ object Customer { } } } ~ - pathPrefix("cart") { - (get & pathEnd) { - getOrFailures { - CartQueries.findOrCreateCartByAccountId(auth.account.id, ctx) - } - } ~ - (post & path("line-items") & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { - reqItems ⇒ - mutateOrFailures { - LineItemUpdater.updateQuantitiesOnCustomersCart(auth.model, reqItems) - } - } ~ - (patch & path("line-items") & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { - reqItems ⇒ - mutateOrFailures { - LineItemUpdater.addQuantitiesOnCustomersCart(auth.model, reqItems) - } - } ~ - (post & path("coupon" / Segment) & pathEnd) { code ⇒ - mutateOrFailures { - CartPromotionUpdater.attachCoupon(auth.model, None, code) - } - } ~ - (delete & path("coupon") & pathEnd) { - mutateOrFailures { - CartPromotionUpdater.detachCoupon(auth.model) - } - } ~ - (post & path("checkout") & pathEnd & entity(as[CheckoutCart])) { payload ⇒ - mutateOrFailures { - Checkout.forCustomerOneClick(payload) - } - } ~ - (post & path("checkout") & pathEnd) { - mutateOrFailures { - Checkout.forCustomer(auth.model) - } - } ~ - (post & path("apple-pay-checkout") & pathEnd & entity(as[CreateApplePayPayment])) { - payload ⇒ - mutateOrFailures { - Checkout.applePayCheckout(auth.model, payload) - } - } ~ - pathPrefix("payment-methods" / "credit-cards") { - (post & pathEnd & entity(as[CreditCardPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addCreditCard(auth.model, payload.creditCardId) + pathPrefix("cart") { + (get & pathEnd) { + getOrFailures { + CartQueries.findOrCreateCartByAccountId(auth.account.id, ctx) } } ~ - (delete & pathEnd) { - mutateOrFailures { - CartPaymentUpdater.deleteCreditCard(auth.model) + (post & path("line-items") & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { reqItems ⇒ + mutateOrFailures { + LineItemUpdater.updateQuantitiesOnCustomersCart(auth.model, reqItems) + } + } ~ + (patch & path("line-items") & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { + reqItems ⇒ + mutateOrFailures { + LineItemUpdater.addQuantitiesOnCustomersCart(auth.model, reqItems) + } + } ~ + (post & path("coupon" / Segment) & pathEnd) { code ⇒ + mutateOrFailures { + CartPromotionUpdater.attachCoupon(auth.model, None, code) + } + } ~ + (delete & path("coupon") & pathEnd) { + mutateOrFailures { + CartPromotionUpdater.detachCoupon(auth.model) + } + } ~ + (post & path("checkout") & pathEnd & entity(as[CheckoutCart])) { payload ⇒ + mutateOrFailures { + Checkout.forCustomerOneClick(payload) + } + } ~ + (post & path("checkout") & pathEnd) { + mutateOrFailures { + Checkout.forCustomer(auth.model) + } + } ~ + (post & path("apple-pay-checkout") & pathEnd & entity(as[CreateApplePayPayment])) { + payload ⇒ + mutateOrFailures { + Checkout.applePayCheckout(auth.model, payload) + } + } ~ + pathPrefix("payment-methods" / "credit-cards") { + (post & pathEnd & entity(as[CreditCardPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addCreditCard(auth.model, payload.creditCardId) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + CartPaymentUpdater.deleteCreditCard(auth.model) + } + } + } ~ + pathPrefix("payment-methods" / "gift-cards") { + (post & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addGiftCard(auth.model, payload) + } + } ~ + (patch & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.editGiftCard(auth.model, payload) + } + } ~ + (delete & path(GiftCard.giftCardCodeRegex) & pathEnd) { code ⇒ + mutateOrFailures { + CartPaymentUpdater.deleteGiftCard(auth.model, code) + } + } + } ~ + pathPrefix("payment-methods" / "store-credit") { + (post & pathEnd & entity(as[StoreCreditPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addStoreCredit(auth.model, payload) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + CartPaymentUpdater.deleteStoreCredit(auth.model) + } + } + } ~ + pathPrefix("shipping-address") { + (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ + mutateOrFailures { + CartShippingAddressUpdater.createShippingAddressFromPayload(auth.model, payload) + } + } ~ + (patch & path(IntNumber) & pathEnd) { addressId ⇒ + mutateOrFailures { + CartShippingAddressUpdater.createShippingAddressFromAddressId(auth.model, addressId) + } + } ~ + (patch & pathEnd & entity(as[UpdateAddressPayload])) { payload ⇒ + mutateOrFailures { + CartShippingAddressUpdater.updateShippingAddressFromPayload(auth.model, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + CartShippingAddressUpdater.removeShippingAddress(auth.model) + } + } + } ~ + pathPrefix("shipping-methods") { + (get & pathEnd) { + getOrFailures { + ShippingManager.getShippingMethodsForCart(auth.model) + } + } ~ + (get & path(Country.countryCodeRegex) & pathEnd) { countryCode ⇒ + getOrFailures { + ShippingManager.getShippingMethodsForRegion(countryCode, auth.model) + } + } + } ~ + pathPrefix("shipping-method") { + (patch & pathEnd & entity(as[UpdateShippingMethod])) { payload ⇒ + mutateOrFailures { + CartShippingMethodUpdater.updateShippingMethod(auth.model, payload.shippingMethodId) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + CartShippingMethodUpdater.deleteShippingMethod(auth.model) + } + } } - } } ~ - pathPrefix("payment-methods" / "gift-cards") { - (post & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addGiftCard(auth.model, payload) - } - } ~ - (patch & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.editGiftCard(auth.model, payload) + pathPrefix("account") { + (get & pathEnd) { + getOrFailures { + CustomerManager.getByAccountId(auth.account.id) } } ~ - (delete & path(GiftCard.giftCardCodeRegex) & pathEnd) { code ⇒ - mutateOrFailures { - CartPaymentUpdater.deleteGiftCard(auth.model, code) + (pathPrefix("change-password") & pathEnd & post & entity(as[ChangeCustomerPasswordPayload])) { + payload ⇒ + doOrFailures { + CustomerManager.changePassword(auth.account.id, payload) + } + } ~ + (patch & pathEnd & entity(as[UpdateCustomerPayload])) { payload ⇒ + mutateWithNewTokenOrFailures { + CustomerManager.update(auth.account.id, payload) + } } - } } ~ - pathPrefix("payment-methods" / "store-credit") { - (post & pathEnd & entity(as[StoreCreditPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addStoreCredit(auth.model, payload) + pathPrefix("orders") { + (get & pathEnd) { + getOrFailures { + OrderQueries.findAllByUser(auth.model) } } ~ - (delete & pathEnd) { - mutateOrFailures { - CartPaymentUpdater.deleteStoreCredit(auth.model) + (get & pathPrefix(cordRefNumRegex) & pathEnd) { refNum ⇒ + (get & pathEnd) { + getOrFailures { + OrderQueries.findOneByUser(refNum, auth.model) + } + } } - } } ~ - pathPrefix("shipping-address") { - (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ - mutateOrFailures { - CartShippingAddressUpdater.createShippingAddressFromPayload(auth.model, - payload) - } - } ~ - (patch & path(IntNumber) & pathEnd) { addressId ⇒ - mutateOrFailures { - CartShippingAddressUpdater.createShippingAddressFromAddressId(auth.model, - addressId) - } - } ~ - (patch & pathEnd & entity(as[UpdateAddressPayload])) { payload ⇒ - mutateOrFailures { - CartShippingAddressUpdater.updateShippingAddressFromPayload(auth.model, - payload) + pathPrefix("addresses") { + (get & pathEnd) { + getOrFailures { + AddressManager.findAllByAccountId(auth.account.id) } } ~ - (delete & pathEnd) { - deleteOrFailures { - CartShippingAddressUpdater.removeShippingAddress(auth.model) + (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ + mutateOrFailures { + AddressManager.create(auth.model, payload, auth.account.id) + } + } ~ + (delete & path("default") & pathEnd) { + deleteOrFailures { + AddressManager.removeDefaultShippingAddress(auth.account.id) + } } - } } ~ - pathPrefix("shipping-methods") { + pathPrefix("addresses" / IntNumber) { addressId ⇒ (get & pathEnd) { getOrFailures { - ShippingManager.getShippingMethodsForCart(auth.model) + AddressManager.get(auth.model, addressId, auth.account.id) } } ~ - (get & path(Country.countryCodeRegex) & pathEnd) { countryCode ⇒ - getOrFailures { - ShippingManager.getShippingMethodsForRegion(countryCode, auth.model) + (post & path("default") & pathEnd) { + mutateOrFailures { + AddressManager.setDefaultShippingAddress(addressId, auth.account.id) + } + } ~ + (patch & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ + mutateOrFailures { + AddressManager.edit(auth.model, addressId, auth.account.id, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + AddressManager.remove(auth.model, addressId, auth.account.id) + } } - } } ~ - pathPrefix("shipping-method") { - (patch & pathEnd & entity(as[UpdateShippingMethod])) { payload ⇒ + pathPrefix("payment-methods" / "apple-pay") { + (post & pathEnd & entity(as[CreateApplePayPayment])) { payload ⇒ mutateOrFailures { - CartShippingMethodUpdater.updateShippingMethod(auth.model, - payload.shippingMethodId) + CartPaymentUpdater.addApplePayPayment(auth.model, payload) } - } ~ - (delete & pathEnd) { - mutateOrFailures { - CartShippingMethodUpdater.deleteShippingMethod(auth.model) - } - } - } - } ~ - pathPrefix("account") { - (get & pathEnd) { - getOrFailures { - CustomerManager.getByAccountId(auth.account.id) - } - } ~ - (pathPrefix("change-password") & pathEnd & post & entity( - as[ChangeCustomerPasswordPayload])) { payload ⇒ - doOrFailures { - CustomerManager.changePassword(auth.account.id, payload) } } ~ - (patch & pathEnd & entity(as[UpdateCustomerPayload])) { payload ⇒ - mutateWithNewTokenOrFailures { - CustomerManager.update(auth.account.id, payload) - } - } - } ~ - pathPrefix("orders") { - (get & pathEnd) { - getOrFailures { - OrderQueries.findAllByUser(auth.model) - } - } ~ - (get & pathPrefix(cordRefNumRegex) & pathEnd) { refNum ⇒ + pathPrefix("payment-methods" / "credit-cards") { (get & pathEnd) { - getOrFailures { - OrderQueries.findOneByUser(refNum, auth.model) + complete { + CreditCardManager.creditCardsInWalletFor(auth.account.id) } - } - } - } ~ - pathPrefix("addresses") { - (get & pathEnd) { - getOrFailures { - AddressManager.findAllByAccountId(auth.account.id) - } - } ~ - (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ - mutateOrFailures { - AddressManager.create(auth.model, payload, auth.account.id) - } - } ~ - (delete & path("default") & pathEnd) { - deleteOrFailures { - AddressManager.removeDefaultShippingAddress(auth.account.id) - } - } - } ~ - pathPrefix("addresses" / IntNumber) { addressId ⇒ - (get & pathEnd) { - getOrFailures { - AddressManager.get(auth.model, addressId, auth.account.id) - } - } ~ - (post & path("default") & pathEnd) { - mutateOrFailures { - AddressManager.setDefaultShippingAddress(addressId, auth.account.id) - } - } ~ - (patch & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ - mutateOrFailures { - AddressManager.edit(auth.model, addressId, auth.account.id, payload) - } - } ~ - (delete & pathEnd) { - deleteOrFailures { - AddressManager.remove(auth.model, addressId, auth.account.id) - } - } - } ~ - pathPrefix("payment-methods" / "apple-pay") { - (post & pathEnd & entity(as[CreateApplePayPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addApplePayPayment(auth.model, payload) - } - } - } ~ - pathPrefix("payment-methods" / "credit-cards") { - (get & pathEnd) { - complete { - CreditCardManager.creditCardsInWalletFor(auth.account.id) - } - } ~ - (get & path(IntNumber) & pathEnd) { creditCardId ⇒ - getOrFailures { - CreditCardManager.getByIdAndCustomer(creditCardId, auth.model) - } - } ~ - (post & path(IntNumber / "default") & pathEnd) { cardId ⇒ - mutateOrFailures { - CreditCardManager.setDefaultCreditCard(auth.account.id, cardId) - } - } ~ - (post & pathEnd & entity(as[CreateCreditCardFromTokenPayload])) { payload ⇒ - mutateOrFailures { - CreditCardManager.createCardFromToken(auth.account.id, payload) - } - } ~ - (patch & path(IntNumber) & pathEnd & entity(as[EditCreditCard])) { - (cardId, payload) ⇒ - mutateOrFailures { - CreditCardManager.editCreditCard(auth.account.id, cardId, payload) + } ~ + (get & path(IntNumber) & pathEnd) { creditCardId ⇒ + getOrFailures { + CreditCardManager.getByIdAndCustomer(creditCardId, auth.model) + } + } ~ + (post & path(IntNumber / "default") & pathEnd) { cardId ⇒ + mutateOrFailures { + CreditCardManager.setDefaultCreditCard(auth.account.id, cardId) + } + } ~ + (post & pathEnd & entity(as[CreateCreditCardFromTokenPayload])) { payload ⇒ + mutateOrFailures { + CreditCardManager.createCardFromToken(auth.account.id, payload) + } + } ~ + (patch & path(IntNumber) & pathEnd & entity(as[EditCreditCard])) { (cardId, payload) ⇒ + mutateOrFailures { + CreditCardManager.editCreditCard(auth.account.id, cardId, payload) + } + } ~ + (delete & path(IntNumber) & pathEnd) { cardId ⇒ + deleteOrFailures { + CreditCardManager.deleteCreditCard(auth.account.id, cardId) + } + } ~ + (delete & path("default") & pathEnd) { + deleteOrFailures { + CreditCardManager.removeDefaultCreditCard(auth.account.id) + } } } ~ - (delete & path(IntNumber) & pathEnd) { cardId ⇒ - deleteOrFailures { - CreditCardManager.deleteCreditCard(auth.account.id, cardId) - } - } ~ - (delete & path("default") & pathEnd) { - deleteOrFailures { - CreditCardManager.removeDefaultCreditCard(auth.account.id) - } - } - } ~ - pathPrefix("payment-methods" / "store-credits") { - (get & path(IntNumber) & pathEnd) { storeCreditId ⇒ - getOrFailures { - StoreCreditService.getByIdAndCustomer(storeCreditId, auth.model) - } - } ~ - (get & path("totals") & pathEnd) { - getOrFailures { - StoreCreditService.totalsForCustomer(auth.account.id) - } - } - } ~ - pathPrefix("save-for-later") { - determineObjectContext(db, ec) { context ⇒ - (get & pathEnd) { + pathPrefix("payment-methods" / "store-credits") { + (get & path(IntNumber) & pathEnd) { storeCreditId ⇒ getOrFailures { - SaveForLaterManager.findAll(auth.account.id, context.id) - } - } ~ - (post & path(skuCodeRegex) & pathEnd) { code ⇒ - mutateOrFailures { - SaveForLaterManager.saveForLater(auth.account.id, code, context) + StoreCreditService.getByIdAndCustomer(storeCreditId, auth.model) } } ~ - (delete & path(IntNumber) & pathEnd) { id ⇒ - deleteOrFailures { - SaveForLaterManager.deleteSaveForLater(id) + (get & path("totals") & pathEnd) { + getOrFailures { + StoreCreditService.totalsForCustomer(auth.account.id) + } } + } ~ + pathPrefix("save-for-later") { + determineObjectContext(db, ec) { context ⇒ + (get & pathEnd) { + getOrFailures { + SaveForLaterManager.findAll(auth.account.id, context.id) + } + } ~ + (post & path(skuCodeRegex) & pathEnd) { code ⇒ + mutateOrFailures { + SaveForLaterManager.saveForLater(auth.account.id, code, context) + } + } ~ + (delete & path(IntNumber) & pathEnd) { id ⇒ + deleteOrFailures { + SaveForLaterManager.deleteSaveForLater(id) + } + } } - } - } ~ - pathPrefix("review") { - determineObjectContext(db, ec) { implicit ctx ⇒ - (post & entity(as[CreateProductReviewByCustomerPayload]) & pathEnd) { payload ⇒ - mutateOrFailures { - ProductReviewManager.createProductReview(auth.account.id, payload) - } - } ~ - (path(IntNumber) & patch & entity(as[UpdateProductReviewPayload]) & pathEnd) { - (reviewId, payload) ⇒ + } ~ + pathPrefix("review") { + determineObjectContext(db, ec) { implicit ctx ⇒ + (post & entity(as[CreateProductReviewByCustomerPayload]) & pathEnd) { payload ⇒ mutateOrFailures { - ProductReviewManager.updateProductReview(reviewId, payload) + ProductReviewManager.createProductReview(auth.account.id, payload) + } + } ~ + (path(IntNumber) & patch & entity(as[UpdateProductReviewPayload]) & pathEnd) { + (reviewId, payload) ⇒ + mutateOrFailures { + ProductReviewManager.updateProductReview(reviewId, payload) + } + } ~ + (delete & path(IntNumber) & pathEnd) { id ⇒ + deleteOrFailures { + ProductReviewManager.archiveByContextAndId(id) + } } - } ~ - (delete & path(IntNumber) & pathEnd) { id ⇒ - deleteOrFailures { - ProductReviewManager.archiveByContextAndId(id) - } } } - } } } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/Public.scala b/phoenix-scala/phoenix/app/phoenix/routes/Public.scala index 8ac483c510..b338fa4ccf 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/Public.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/Public.scala @@ -20,8 +20,7 @@ import phoenix.utils.http.JsonSupport._ object Public { def routes(customerCreateContext: AccountCreateContext, - defaultScope: LTree)(implicit ec: EC, db: DB, apis: Apis): Route = { - + defaultScope: LTree)(implicit ec: EC, db: DB, apis: Apis): Route = activityContext(defaultScope) { implicit ac ⇒ pathPrefix("public") { pathPrefix("registrations") { @@ -31,70 +30,69 @@ object Public { } } } ~ - pathPrefix("products") { - determineObjectContext(db, ec) { implicit productContext ⇒ - pathPrefix(ProductRef) { productId ⇒ - (get & pathEnd) { - getOrFailures { - ProductManager.getProduct(productId, checkActive = true) + pathPrefix("products") { + determineObjectContext(db, ec) { implicit productContext ⇒ + pathPrefix(ProductRef) { productId ⇒ + (get & pathEnd) { + getOrFailures { + ProductManager.getProduct(productId, checkActive = true) + } } } } - } - } ~ - pathPrefix("gift-cards" / "types") { - (get & pathEnd) { - getOrFailures { - GiftCardService.getOriginTypes - } - } - } ~ - pathPrefix("store-credits" / "types") { - (get & pathEnd) { - getOrFailures { - StoreCreditService.getOriginTypes - } - } - } ~ - pathPrefix("reasons" / reasonTypeRegex) { reasonType ⇒ - (get & pathEnd) { - getOrFailures { - ReasonService.listReasonsByType(reasonType) - } - } - } ~ - // TODO move to ES - pathPrefix("regions") { - (get & pathEnd) { - good { - listRegions + } ~ + pathPrefix("gift-cards" / "types") { + (get & pathEnd) { + getOrFailures { + GiftCardService.getOriginTypes + } } } ~ - (get & path(Region.regionCodeRegex) & pathEnd) { shortName ⇒ - getOrFailures { - findRegionByShortName(shortName) + pathPrefix("store-credits" / "types") { + (get & pathEnd) { + getOrFailures { + StoreCreditService.getOriginTypes + } } - } - } ~ - // TODO move to ES - pathPrefix("countries") { - (get & pathEnd) { - good { - listCountries + } ~ + pathPrefix("reasons" / reasonTypeRegex) { reasonType ⇒ + (get & pathEnd) { + getOrFailures { + ReasonService.listReasonsByType(reasonType) + } } } ~ - (get & path(IntNumber) & pathEnd) { countryId ⇒ - mutateOrFailures { - findCountry(countryId) + // TODO move to ES + pathPrefix("regions") { + (get & pathEnd) { + good { + listRegions + } + } ~ + (get & path(Region.regionCodeRegex) & pathEnd) { shortName ⇒ + getOrFailures { + findRegionByShortName(shortName) + } + } + } ~ + // TODO move to ES + pathPrefix("countries") { + (get & pathEnd) { + good { + listCountries + } + } ~ + (get & path(IntNumber) & pathEnd) { countryId ⇒ + mutateOrFailures { + findCountry(countryId) + } + } + } ~ + pathPrefix("ping") { + (get & pathEnd) { + complete(renderPlain("pong")) } } - } ~ - pathPrefix("ping") { - (get & pathEnd) { - complete(renderPlain("pong")) - } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/AdminRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/AdminRoutes.scala index a967f4de1b..9b95f6cba8 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/AdminRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/AdminRoutes.scala @@ -30,298 +30,296 @@ object AdminRoutes { activityContext(auth) { implicit ac ⇒ StoreCreditRoutes.storeCreditRoutes ~ - pathPrefix("export") { - (post & path(ExportableEntityMatcher) & entity(as[ExportEntity])) { (entity, payload) ⇒ - complete { - EntityExporter.export(payload, entity) - } - } - } ~ - pathPrefix("notes") { - pathPrefix("order" / cordRefNumRegex) { refNum ⇒ - (get & pathEnd) { - getOrFailures { - CordNoteManager.list(refNum) - } - } ~ - (post & pathEnd & entity(as[CreateNote])) { payload ⇒ - mutateOrFailures { - CordNoteManager.create(refNum, auth.model, payload) - } - } ~ - (patch & path(IntNumber) & pathEnd & entity(as[UpdateNote])) { (noteId, payload) ⇒ - mutateOrFailures { - CordNoteManager.update(refNum, noteId, auth.model, payload) - } - } ~ - (delete & path(IntNumber)) { noteId ⇒ - deleteOrFailures { - CordNoteManager.delete(refNum, noteId, auth.model) + pathPrefix("export") { + (post & path(ExportableEntityMatcher) & entity(as[ExportEntity])) { (entity, payload) ⇒ + complete { + EntityExporter.export(payload, entity) } } } ~ - pathPrefix("gift-card" / GiftCard.giftCardCodeRegex) { code ⇒ - (get & pathEnd) { - getOrFailures { - GiftCardNoteManager.list(code) - } - } ~ - (post & pathEnd & entity(as[CreateNote])) { payload ⇒ - mutateOrFailures { - GiftCardNoteManager.create(code, auth.model, payload) - } - } ~ - path(IntNumber) { noteId ⇒ - (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ - mutateOrFailures { - GiftCardNoteManager.update(code, noteId, auth.model, payload) + pathPrefix("notes") { + pathPrefix("order" / cordRefNumRegex) { refNum ⇒ + (get & pathEnd) { + getOrFailures { + CordNoteManager.list(refNum) } } ~ - (delete & pathEnd) { - deleteOrFailures { - GiftCardNoteManager.delete(code, noteId, auth.model) + (post & pathEnd & entity(as[CreateNote])) { payload ⇒ + mutateOrFailures { + CordNoteManager.create(refNum, auth.model, payload) + } + } ~ + (patch & path(IntNumber) & pathEnd & entity(as[UpdateNote])) { (noteId, payload) ⇒ + mutateOrFailures { + CordNoteManager.update(refNum, noteId, auth.model, payload) + } + } ~ + (delete & path(IntNumber)) { noteId ⇒ + deleteOrFailures { + CordNoteManager.delete(refNum, noteId, auth.model) + } } - } - } - } ~ - pathPrefix("customer" / IntNumber) { accountId ⇒ - (get & pathEnd) { - getOrFailures { - CustomerNoteManager.list(accountId) - } - } ~ - (post & pathEnd & entity(as[CreateNote])) { payload ⇒ - mutateOrFailures { - CustomerNoteManager.create(accountId, auth.model, payload) - } } ~ - path(IntNumber) { noteId ⇒ - (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ - mutateOrFailures { - CustomerNoteManager.update(accountId, noteId, auth.model, payload) - } + pathPrefix("gift-card" / GiftCard.giftCardCodeRegex) { code ⇒ + (get & pathEnd) { + getOrFailures { + GiftCardNoteManager.list(code) + } + } ~ + (post & pathEnd & entity(as[CreateNote])) { payload ⇒ + mutateOrFailures { + GiftCardNoteManager.create(code, auth.model, payload) + } + } ~ + path(IntNumber) { noteId ⇒ + (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + mutateOrFailures { + GiftCardNoteManager.update(code, noteId, auth.model, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + GiftCardNoteManager.delete(code, noteId, auth.model) + } + } + } } ~ - (delete & pathEnd) { - deleteOrFailures { - CustomerNoteManager.delete(accountId, noteId, auth.model) - } - } - } - } ~ - pathPrefix("return" / Return.returnRefNumRegex) { refNum ⇒ - (get & pathEnd) { - getOrFailures { - ReturnNoteManager.list(refNum) - } - } ~ - (post & pathEnd & entity(as[CreateNote])) { payload ⇒ - mutateOrFailures { - ReturnNoteManager.create(refNum, auth.model, payload) - } - } ~ - path(IntNumber) { noteId ⇒ - (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ - mutateOrFailures { - ReturnNoteManager.update(refNum, noteId, auth.model, payload) - } + pathPrefix("customer" / IntNumber) { accountId ⇒ + (get & pathEnd) { + getOrFailures { + CustomerNoteManager.list(accountId) + } + } ~ + (post & pathEnd & entity(as[CreateNote])) { payload ⇒ + mutateOrFailures { + CustomerNoteManager.create(accountId, auth.model, payload) + } + } ~ + path(IntNumber) { noteId ⇒ + (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + mutateOrFailures { + CustomerNoteManager.update(accountId, noteId, auth.model, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + CustomerNoteManager.delete(accountId, noteId, auth.model) + } + } + } } ~ - (delete & pathEnd) { - deleteOrFailures { - ReturnNoteManager.delete(refNum, noteId, auth.model) - } - } - } - } ~ - pathPrefix("sku" / Sku.skuCodeRegex) { code ⇒ - (get & pathEnd) { - getOrFailures { - SkuNoteManager.list(code) - } - } ~ - (post & pathEnd & entity(as[CreateNote])) { payload ⇒ - mutateOrFailures { - SkuNoteManager.create(code, auth.model, payload) - } - } ~ - path(IntNumber) { noteId ⇒ - (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ - mutateOrFailures { - SkuNoteManager.update(code, noteId, auth.model, payload) - } + pathPrefix("return" / Return.returnRefNumRegex) { refNum ⇒ + (get & pathEnd) { + getOrFailures { + ReturnNoteManager.list(refNum) + } + } ~ + (post & pathEnd & entity(as[CreateNote])) { payload ⇒ + mutateOrFailures { + ReturnNoteManager.create(refNum, auth.model, payload) + } + } ~ + path(IntNumber) { noteId ⇒ + (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + mutateOrFailures { + ReturnNoteManager.update(refNum, noteId, auth.model, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + ReturnNoteManager.delete(refNum, noteId, auth.model) + } + } + } } ~ - (delete & pathEnd) { - deleteOrFailures { - SkuNoteManager.delete(code, noteId, auth.model) - } + pathPrefix("sku" / Sku.skuCodeRegex) { code ⇒ + (get & pathEnd) { + getOrFailures { + SkuNoteManager.list(code) + } + } ~ + (post & pathEnd & entity(as[CreateNote])) { payload ⇒ + mutateOrFailures { + SkuNoteManager.create(code, auth.model, payload) + } + } ~ + path(IntNumber) { noteId ⇒ + (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + mutateOrFailures { + SkuNoteManager.update(code, noteId, auth.model, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + SkuNoteManager.delete(code, noteId, auth.model) + } + } + } + } ~ + pathPrefix("product" / IntNumber) { productId ⇒ + (get & pathEnd) { + getOrFailures { + ProductNoteManager.list(productId) + } + } ~ + (post & pathEnd & entity(as[CreateNote])) { payload ⇒ + mutateOrFailures { + ProductNoteManager.create(productId, auth.model, payload) + } + } ~ + path(IntNumber) { noteId ⇒ + (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + mutateOrFailures { + ProductNoteManager.update(productId, noteId, auth.model, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + ProductNoteManager.delete(productId, noteId, auth.model) + } + } + } + } ~ + pathPrefix("promotion" / IntNumber) { promoId ⇒ + (get & pathEnd) { + getOrFailures { + PromotionNoteManager.list(promoId) + } + } ~ + (post & pathEnd & entity(as[CreateNote])) { payload ⇒ + mutateOrFailures { + PromotionNoteManager.create(promoId, auth.model, payload) + } + } ~ + path(IntNumber) { noteId ⇒ + (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + mutateOrFailures { + PromotionNoteManager.update(promoId, noteId, auth.model, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + PromotionNoteManager.delete(promoId, noteId, auth.model) + } + } + } + } ~ + pathPrefix("coupon" / IntNumber) { couponId ⇒ + (get & pathEnd) { + getOrFailures { + CouponNoteManager.list(couponId) + } + } ~ + (post & pathEnd & entity(as[CreateNote])) { payload ⇒ + mutateOrFailures { + CouponNoteManager.create(couponId, auth.model, payload) + } + } ~ + path(IntNumber) { noteId ⇒ + (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + mutateOrFailures { + CouponNoteManager.update(couponId, noteId, auth.model, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + CouponNoteManager.delete(couponId, noteId, auth.model) + } + } + } + } ~ + pathPrefix("store-admins" / IntNumber) { adminId ⇒ + (get & pathEnd) { + getOrFailures { + StoreAdminNoteManager.list(adminId) + } + } ~ + (post & pathEnd & entity(as[CreateNote])) { payload ⇒ + mutateOrFailures { + StoreAdminNoteManager.create(adminId, auth.model, payload) + } + } ~ + path(IntNumber) { noteId ⇒ + (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + mutateOrFailures { + StoreAdminNoteManager.update(adminId, noteId, auth.model, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + StoreAdminNoteManager.delete(adminId, noteId, auth.model) + } + } + } } - } } ~ - pathPrefix("product" / IntNumber) { productId ⇒ - (get & pathEnd) { - getOrFailures { - ProductNoteManager.list(productId) - } - } ~ - (post & pathEnd & entity(as[CreateNote])) { payload ⇒ - mutateOrFailures { - ProductNoteManager.create(productId, auth.model, payload) - } - } ~ - path(IntNumber) { noteId ⇒ - (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ - mutateOrFailures { - ProductNoteManager.update(productId, noteId, auth.model, payload) + pathPrefix("save-for-later") { + determineObjectContext(db, ec) { productContext ⇒ + (get & path(IntNumber) & pathEnd) { accountId ⇒ + getOrFailures { + SaveForLaterManager.findAll(accountId, productContext.id) } } ~ - (delete & pathEnd) { - deleteOrFailures { - ProductNoteManager.delete(productId, noteId, auth.model) + (post & path(IntNumber / Segment) & pathEnd) { (accountId, skuCode) ⇒ + mutateOrFailures { + SaveForLaterManager.saveForLater(accountId, skuCode, productContext) + } + } ~ + (delete & path(IntNumber) & pathEnd) { id ⇒ + deleteOrFailures { + SaveForLaterManager.deleteSaveForLater(id) + } } - } } } ~ - pathPrefix("promotion" / IntNumber) { promoId ⇒ - (get & pathEnd) { + pathPrefix("shared-search") { + (get & pathEnd & parameters('scope.as[String].?)) { scope ⇒ getOrFailures { - PromotionNoteManager.list(promoId) + SharedSearchService.getAll(auth.model, scope) } } ~ - (post & pathEnd & entity(as[CreateNote])) { payload ⇒ - mutateOrFailures { - PromotionNoteManager.create(promoId, auth.model, payload) - } - } ~ - path(IntNumber) { noteId ⇒ - (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + (post & pathEnd & entityOr(as[SharedSearchPayload], SharedSearchInvalidQueryFailure)) { payload ⇒ mutateOrFailures { - PromotionNoteManager.update(promoId, noteId, auth.model, payload) - } - } ~ - (delete & pathEnd) { - deleteOrFailures { - PromotionNoteManager.delete(promoId, noteId, auth.model) + SharedSearchService.create(auth.model, payload) } } - } } ~ - pathPrefix("coupon" / IntNumber) { couponId ⇒ + pathPrefix("shared-search" / SharedSearch.sharedSearchRegex) { code ⇒ (get & pathEnd) { getOrFailures { - CouponNoteManager.list(couponId) - } - } ~ - (post & pathEnd & entity(as[CreateNote])) { payload ⇒ - mutateOrFailures { - CouponNoteManager.create(couponId, auth.model, payload) + SharedSearchService.get(code) } } ~ - path(IntNumber) { noteId ⇒ - (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ + (patch & pathEnd & entityOr(as[SharedSearchPayload], SharedSearchInvalidQueryFailure)) { payload ⇒ mutateOrFailures { - CouponNoteManager.update(couponId, noteId, auth.model, payload) + SharedSearchService.update(auth.model, code, payload) } } ~ (delete & pathEnd) { deleteOrFailures { - CouponNoteManager.delete(couponId, noteId, auth.model) - } - } - } - } ~ - pathPrefix("store-admins" / IntNumber) { adminId ⇒ - (get & pathEnd) { - getOrFailures { - StoreAdminNoteManager.list(adminId) - } - } ~ - (post & pathEnd & entity(as[CreateNote])) { payload ⇒ - mutateOrFailures { - StoreAdminNoteManager.create(adminId, auth.model, payload) - } - } ~ - path(IntNumber) { noteId ⇒ - (patch & pathEnd & entity(as[UpdateNote])) { payload ⇒ - mutateOrFailures { - StoreAdminNoteManager.update(adminId, noteId, auth.model, payload) + SharedSearchService.delete(auth.model, code) } } ~ - (delete & pathEnd) { - deleteOrFailures { - StoreAdminNoteManager.delete(adminId, noteId, auth.model) + pathPrefix("associates") { + (get & pathEnd) { + getOrFailures { + SharedSearchService.getAssociates(code) + } } + } ~ + pathPrefix("associate") { + (post & pathEnd & entity(as[SharedSearchAssociationPayload])) { payload ⇒ + mutateOrFailures { + SharedSearchService.associate(auth.model, code, payload.associates) + } + } ~ + (delete & path(IntNumber) & pathEnd) { associateId ⇒ + mutateOrFailures { + SharedSearchService.unassociate(auth.model, code, associateId) + } + } } - } - } - } ~ - pathPrefix("save-for-later") { - determineObjectContext(db, ec) { productContext ⇒ - (get & path(IntNumber) & pathEnd) { accountId ⇒ - getOrFailures { - SaveForLaterManager.findAll(accountId, productContext.id) - } - } ~ - (post & path(IntNumber / Segment) & pathEnd) { (accountId, skuCode) ⇒ - mutateOrFailures { - SaveForLaterManager.saveForLater(accountId, skuCode, productContext) - } - } ~ - (delete & path(IntNumber) & pathEnd) { id ⇒ - deleteOrFailures { - SaveForLaterManager.deleteSaveForLater(id) - } - } - } - } ~ - pathPrefix("shared-search") { - (get & pathEnd & parameters('scope.as[String].?)) { scope ⇒ - getOrFailures { - SharedSearchService.getAll(auth.model, scope) - } - } ~ - (post & pathEnd & entityOr(as[SharedSearchPayload], SharedSearchInvalidQueryFailure)) { - payload ⇒ - mutateOrFailures { - SharedSearchService.create(auth.model, payload) - } - } - } ~ - pathPrefix("shared-search" / SharedSearch.sharedSearchRegex) { code ⇒ - (get & pathEnd) { - getOrFailures { - SharedSearchService.get(code) - } - } ~ - (patch & pathEnd & entityOr(as[SharedSearchPayload], SharedSearchInvalidQueryFailure)) { - payload ⇒ - mutateOrFailures { - SharedSearchService.update(auth.model, code, payload) - } - } ~ - (delete & pathEnd) { - deleteOrFailures { - SharedSearchService.delete(auth.model, code) - } - } ~ - pathPrefix("associates") { - (get & pathEnd) { - getOrFailures { - SharedSearchService.getAssociates(code) - } - } - } ~ - pathPrefix("associate") { - (post & pathEnd & entity(as[SharedSearchAssociationPayload])) { payload ⇒ - mutateOrFailures { - SharedSearchService.associate(auth.model, code, payload.associates) - } - } ~ - (delete & path(IntNumber) & pathEnd) { associateId ⇒ - mutateOrFailures { - SharedSearchService.unassociate(auth.model, code, associateId) - } - } } - } } } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/AmazonOrderRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/AmazonOrderRoutes.scala index 2a6a4f2dc3..866be65028 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/AmazonOrderRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/AmazonOrderRoutes.scala @@ -14,7 +14,7 @@ import phoenix.utils.http.CustomDirectives._ import phoenix.utils.http.Http._ object AmazonOrderRoutes { - def routes(implicit ec: EC, db: DB, auth: AU): Route = { + def routes(implicit ec: EC, db: DB, auth: AU): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("amazon-orders") { (post & pathEnd & entity(as[CreateAmazonOrderPayload])) { payload ⇒ @@ -22,14 +22,13 @@ object AmazonOrderRoutes { createAmazonOrder(payload) } } ~ - pathPrefix(Segment) { amazonOrderId ⇒ - (patch & pathEnd & entity(as[UpdateAmazonOrderPayload])) { payload ⇒ - mutateOrFailures { - updateAmazonOrder(amazonOrderId, payload) + pathPrefix(Segment) { amazonOrderId ⇒ + (patch & pathEnd & entity(as[UpdateAmazonOrderPayload])) { payload ⇒ + mutateOrFailures { + updateAmazonOrder(amazonOrderId, payload) + } } } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/AssignmentsRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/AssignmentsRoutes.scala index 1c3767afdc..25ef4959fd 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/AssignmentsRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/AssignmentsRoutes.scala @@ -31,755 +31,755 @@ object AssignmentsRoutes { } } } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - CustomerAssignmentsManager.unassignBulk(auth.model, payload) + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + CustomerAssignmentsManager.unassignBulk(auth.model, payload) + } } } - } } ~ - pathPrefix("watchers") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - CustomerWatchersManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - CustomerWatchersManager.unassignBulk(auth.model, payload) + pathPrefix("watchers") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + CustomerWatchersManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + CustomerWatchersManager.unassignBulk(auth.model, payload) + } + } } - } - } - } - } ~ - // Customers Single Assignments - pathPrefix("customers" / IntNumber) { accountId ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - CustomerAssignmentsManager.list(accountId) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - CustomerAssignmentsManager.assign(accountId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - CustomerAssignmentsManager.unassign(accountId, assigneeId, auth.model) - } - } - } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - CustomerWatchersManager.list(accountId) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - CustomerWatchersManager.assign(accountId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - CustomerWatchersManager.unassign(accountId, assigneeId, auth.model) - } } - } } ~ - // Gift Cards Bulk Assignments - pathPrefix("gift-cards") { - pathPrefix("assignees") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - GiftCardAssignmentsManager.assignBulk(auth.model, payload) - } + // Customers Single Assignments + pathPrefix("customers" / IntNumber) { accountId ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + CustomerAssignmentsManager.list(accountId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + CustomerAssignmentsManager.assign(accountId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + CustomerAssignmentsManager.unassign(accountId, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + CustomerWatchersManager.list(accountId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + CustomerWatchersManager.assign(accountId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + CustomerWatchersManager.unassign(accountId, assigneeId, auth.model) + } + } } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - GiftCardAssignmentsManager.unassignBulk(auth.model, payload) - } - } - } } ~ - pathPrefix("watchers") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - GiftCardWatchersManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - GiftCardWatchersManager.unassignBulk(auth.model, payload) - } - } - } - } - } ~ - // Gift Cards Single Assignments - pathPrefix("gift-cards" / giftCardCodeRegex) { code ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - GiftCardAssignmentsManager.list(code) + // Gift Cards Bulk Assignments + pathPrefix("gift-cards") { + pathPrefix("assignees") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + GiftCardAssignmentsManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + GiftCardAssignmentsManager.unassignBulk(auth.model, payload) + } + } + } + } ~ + pathPrefix("watchers") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + GiftCardWatchersManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + GiftCardWatchersManager.unassignBulk(auth.model, payload) + } + } + } } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - GiftCardAssignmentsManager.assign(code, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - GiftCardAssignmentsManager.unassign(code, assigneeId, auth.model) - } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - GiftCardWatchersManager.list(code) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - GiftCardWatchersManager.assign(code, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - GiftCardWatchersManager.unassign(code, assigneeId, auth.model) - } - } - } - } ~ - // Orders Bulk Assignments - pathPrefix("orders") { - pathPrefix("assignees") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - OrderAssignmentsManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - OrderAssignmentsManager.unassignBulk(auth.model, payload) - } + // Gift Cards Single Assignments + pathPrefix("gift-cards" / giftCardCodeRegex) { code ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + GiftCardAssignmentsManager.list(code) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + GiftCardAssignmentsManager.assign(code, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + GiftCardAssignmentsManager.unassign(code, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + GiftCardWatchersManager.list(code) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + GiftCardWatchersManager.assign(code, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + GiftCardWatchersManager.unassign(code, assigneeId, auth.model) + } + } } - } } ~ - pathPrefix("watchers") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - OrderWatchersManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - OrderWatchersManager.unassignBulk(auth.model, payload) - } - } - } - } - } ~ - // Orders Single Assignments - pathPrefix("orders" / cordRefNumRegex) { refNum ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - OrderAssignmentsManager.list(refNum) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - OrderAssignmentsManager.assign(refNum, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - OrderAssignmentsManager.unassign(refNum, assigneeId, auth.model) + // Orders Bulk Assignments + pathPrefix("orders") { + pathPrefix("assignees") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + OrderAssignmentsManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + OrderAssignmentsManager.unassignBulk(auth.model, payload) + } + } + } + } ~ + pathPrefix("watchers") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + OrderWatchersManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + OrderWatchersManager.unassignBulk(auth.model, payload) + } + } + } } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - OrderWatchersManager.list(refNum) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - OrderWatchersManager.assign(refNum, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - OrderWatchersManager.unassign(refNum, assigneeId, auth.model) - } - } - } - } ~ - // Carts Bulk Assignments - pathPrefix("carts") { - pathPrefix("assignees") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - CartAssignmentsManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - CartAssignmentsManager.unassignBulk(auth.model, payload) - } + // Orders Single Assignments + pathPrefix("orders" / cordRefNumRegex) { refNum ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + OrderAssignmentsManager.list(refNum) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + OrderAssignmentsManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + OrderAssignmentsManager.unassign(refNum, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + OrderWatchersManager.list(refNum) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + OrderWatchersManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + OrderWatchersManager.unassign(refNum, assigneeId, auth.model) + } + } } - } } ~ - pathPrefix("watchers") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - CartWatchersManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - CartWatchersManager.unassignBulk(auth.model, payload) - } - } - } - } - } ~ - // Carts Single Assignments - pathPrefix("carts" / cordRefNumRegex) { refNum ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - CartAssignmentsManager.list(refNum) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - CartAssignmentsManager.assign(refNum, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - CartAssignmentsManager.unassign(refNum, assigneeId, auth.model) + // Carts Bulk Assignments + pathPrefix("carts") { + pathPrefix("assignees") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + CartAssignmentsManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + CartAssignmentsManager.unassignBulk(auth.model, payload) + } + } + } + } ~ + pathPrefix("watchers") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + CartWatchersManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + CartWatchersManager.unassignBulk(auth.model, payload) + } + } + } } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - CartWatchersManager.list(refNum) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - CartWatchersManager.assign(refNum, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - CartWatchersManager.unassign(refNum, assigneeId, auth.model) - } - } - } - } ~ - // Returns Bulk Assignments - pathPrefix("returns") { - pathPrefix("assignees") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - ReturnAssignmentsManager.assignBulk(auth.model, payload) - } + // Carts Single Assignments + pathPrefix("carts" / cordRefNumRegex) { refNum ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + CartAssignmentsManager.list(refNum) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + CartAssignmentsManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + CartAssignmentsManager.unassign(refNum, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + CartWatchersManager.list(refNum) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + CartWatchersManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + CartWatchersManager.unassign(refNum, assigneeId, auth.model) + } + } } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - ReturnAssignmentsManager.unassignBulk(auth.model, payload) - } - } - } } ~ - pathPrefix("watchers") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - ReturnWatchersManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - ReturnWatchersManager.unassignBulk(auth.model, payload) - } - } - } - } - } ~ - // Returns Single Assignments - pathPrefix("returns" / returnRefNumRegex) { refNum ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - ReturnAssignmentsManager.list(refNum) - } - } ~ - (post & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - ReturnAssignmentsManager.assign(refNum, payload, auth.model) + // Returns Bulk Assignments + pathPrefix("returns") { + pathPrefix("assignees") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + ReturnAssignmentsManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + ReturnAssignmentsManager.unassignBulk(auth.model, payload) + } + } + } + } ~ + pathPrefix("watchers") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + ReturnWatchersManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + ReturnWatchersManager.unassignBulk(auth.model, payload) + } + } + } } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - ReturnAssignmentsManager.unassign(refNum, assigneeId, auth.model) - } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - ReturnWatchersManager.list(refNum) - } - } ~ - (post & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - ReturnWatchersManager.assign(refNum, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - ReturnWatchersManager.unassign(refNum, assigneeId, auth.model) - } - } - } - } ~ - // Products Bulk Assignments - pathPrefix("products") { - pathPrefix("assignees") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - ProductAssignmentsManager.assignBulk(auth.model, payload) - } + // Returns Single Assignments + pathPrefix("returns" / returnRefNumRegex) { refNum ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + ReturnAssignmentsManager.list(refNum) + } + } ~ + (post & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + ReturnAssignmentsManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + ReturnAssignmentsManager.unassign(refNum, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + ReturnWatchersManager.list(refNum) + } + } ~ + (post & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + ReturnWatchersManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + ReturnWatchersManager.unassign(refNum, assigneeId, auth.model) + } + } } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - ProductAssignmentsManager.unassignBulk(auth.model, payload) - } - } - } } ~ - pathPrefix("watchers") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - ProductWatchersManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - ProductWatchersManager.unassignBulk(auth.model, payload) - } - } - } - } - } ~ - // Products Single Assignments - pathPrefix("products" / IntNumber) { productId ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - ProductAssignmentsManager.list(productId) + // Products Bulk Assignments + pathPrefix("products") { + pathPrefix("assignees") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + ProductAssignmentsManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + ProductAssignmentsManager.unassignBulk(auth.model, payload) + } + } + } + } ~ + pathPrefix("watchers") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + ProductWatchersManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + ProductWatchersManager.unassignBulk(auth.model, payload) + } + } + } } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - ProductAssignmentsManager.assign(productId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - ProductAssignmentsManager.unassign(productId, assigneeId, auth.model) - } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - ProductWatchersManager.list(productId) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - ProductWatchersManager.assign(productId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - ProductWatchersManager.unassign(productId, assigneeId, auth.model) - } - } - } - } ~ - // SKUs Bulk Assignments - pathPrefix("skus") { - pathPrefix("assignees") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - SkuAssignmentsManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - SkuAssignmentsManager.unassignBulk(auth.model, payload) - } + // Products Single Assignments + pathPrefix("products" / IntNumber) { productId ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + ProductAssignmentsManager.list(productId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + ProductAssignmentsManager.assign(productId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + ProductAssignmentsManager.unassign(productId, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + ProductWatchersManager.list(productId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + ProductWatchersManager.assign(productId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + ProductWatchersManager.unassign(productId, assigneeId, auth.model) + } + } } - } } ~ - pathPrefix("watchers") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - SkuWatchersManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[String]]) { payload ⇒ - mutateOrFailures { - SkuWatchersManager.unassignBulk(auth.model, payload) - } - } - } - } - } ~ - // SKUs Single Assignments - pathPrefix("skus" / skuCodeRegex) { refNum ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - SkuAssignmentsManager.list(refNum) - } - } ~ - (post & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - SkuAssignmentsManager.assign(refNum, payload, auth.model) + // SKUs Bulk Assignments + pathPrefix("skus") { + pathPrefix("assignees") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + SkuAssignmentsManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + SkuAssignmentsManager.unassignBulk(auth.model, payload) + } + } + } + } ~ + pathPrefix("watchers") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + SkuWatchersManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[String]]) { payload ⇒ + mutateOrFailures { + SkuWatchersManager.unassignBulk(auth.model, payload) + } + } + } } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - SkuAssignmentsManager.unassign(refNum, assigneeId, auth.model) - } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - SkuWatchersManager.list(refNum) - } - } ~ - (post & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - SkuWatchersManager.assign(refNum, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - SkuWatchersManager.unassign(refNum, assigneeId, auth.model) - } - } - } - } ~ - // Promotions Bulk Assignments - pathPrefix("promotions") { - pathPrefix("assignees") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - PromotionAssignmentsManager.assignBulk(auth.model, payload) - } + // SKUs Single Assignments + pathPrefix("skus" / skuCodeRegex) { refNum ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + SkuAssignmentsManager.list(refNum) + } + } ~ + (post & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + SkuAssignmentsManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + SkuAssignmentsManager.unassign(refNum, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + SkuWatchersManager.list(refNum) + } + } ~ + (post & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + SkuWatchersManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + SkuWatchersManager.unassign(refNum, assigneeId, auth.model) + } + } } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - PromotionAssignmentsManager.unassignBulk(auth.model, payload) - } - } - } } ~ - pathPrefix("watchers") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - PromotionWatchersManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - PromotionWatchersManager.unassignBulk(auth.model, payload) - } - } - } - } - } ~ - // Promotions Single Assignments - pathPrefix("promotions" / IntNumber) { promotionId ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - PromotionAssignmentsManager.list(promotionId) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - PromotionAssignmentsManager.assign(promotionId, payload, auth.model) + // Promotions Bulk Assignments + pathPrefix("promotions") { + pathPrefix("assignees") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + PromotionAssignmentsManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + PromotionAssignmentsManager.unassignBulk(auth.model, payload) + } + } + } + } ~ + pathPrefix("watchers") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + PromotionWatchersManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + PromotionWatchersManager.unassignBulk(auth.model, payload) + } + } + } } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - PromotionAssignmentsManager.unassign(promotionId, assigneeId, auth.model) - } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - PromotionWatchersManager.list(promotionId) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - PromotionWatchersManager.assign(promotionId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - PromotionWatchersManager.unassign(promotionId, assigneeId, auth.model) - } - } - } - } ~ - // Coupons Bulk Assignments - pathPrefix("coupons") { - pathPrefix("assignees") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - CouponAssignmentsManager.assignBulk(auth.model, payload) - } + // Promotions Single Assignments + pathPrefix("promotions" / IntNumber) { promotionId ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + PromotionAssignmentsManager.list(promotionId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + PromotionAssignmentsManager.assign(promotionId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + PromotionAssignmentsManager.unassign(promotionId, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + PromotionWatchersManager.list(promotionId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + PromotionWatchersManager.assign(promotionId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + PromotionWatchersManager.unassign(promotionId, assigneeId, auth.model) + } + } } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - CouponAssignmentsManager.unassignBulk(auth.model, payload) - } - } - } } ~ - pathPrefix("watchers") { - (post & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - CouponWatchersManager.assignBulk(auth.model, payload) - } - } - } ~ - (post & path("delete") & pathEnd) { - entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ - mutateOrFailures { - CouponWatchersManager.unassignBulk(auth.model, payload) - } - } - } - } - } ~ - // Coupons Single Assignments - pathPrefix("coupons" / IntNumber) { couponId ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - CouponAssignmentsManager.list(couponId) + // Coupons Bulk Assignments + pathPrefix("coupons") { + pathPrefix("assignees") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + CouponAssignmentsManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + CouponAssignmentsManager.unassignBulk(auth.model, payload) + } + } + } + } ~ + pathPrefix("watchers") { + (post & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + CouponWatchersManager.assignBulk(auth.model, payload) + } + } + } ~ + (post & path("delete") & pathEnd) { + entity(as[BulkAssignmentPayload[Int]]) { payload ⇒ + mutateOrFailures { + CouponWatchersManager.unassignBulk(auth.model, payload) + } + } + } } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - CouponAssignmentsManager.assign(couponId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - CouponAssignmentsManager.unassign(couponId, assigneeId, auth.model) - } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - CouponWatchersManager.list(couponId) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - CouponWatchersManager.assign(couponId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - CouponWatchersManager.unassign(couponId, assigneeId, auth.model) - } - } - } - } ~ - // Taxonomies Single Assignments - pathPrefix("taxonomies" / IntNumber) { taxonomyId ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - TaxonomyAssignmentsManager.list(taxonomyId) + // Coupons Single Assignments + pathPrefix("coupons" / IntNumber) { couponId ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + CouponAssignmentsManager.list(couponId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + CouponAssignmentsManager.assign(couponId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + CouponAssignmentsManager.unassign(couponId, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + CouponWatchersManager.list(couponId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + CouponWatchersManager.assign(couponId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + CouponWatchersManager.unassign(couponId, assigneeId, auth.model) + } + } } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - TaxonomyAssignmentsManager.assign(taxonomyId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - TaxonomyAssignmentsManager.unassign(taxonomyId, assigneeId, auth.model) - } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - TaxonomyWatchersManager.list(taxonomyId) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - TaxonomyWatchersManager.assign(taxonomyId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - TaxonomyWatchersManager.unassign(taxonomyId, assigneeId, auth.model) - } - } - } - } ~ - // Taxons Single Assignments - pathPrefix("taxons" / IntNumber) { taxonId ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - TaxonAssignmentsManager.list(taxonId) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - TaxonAssignmentsManager.assign(taxonId, payload, auth.model) + // Taxonomies Single Assignments + pathPrefix("taxonomies" / IntNumber) { taxonomyId ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + TaxonomyAssignmentsManager.list(taxonomyId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + TaxonomyAssignmentsManager.assign(taxonomyId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + TaxonomyAssignmentsManager.unassign(taxonomyId, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + TaxonomyWatchersManager.list(taxonomyId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + TaxonomyWatchersManager.assign(taxonomyId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + TaxonomyWatchersManager.unassign(taxonomyId, assigneeId, auth.model) + } + } } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - TaxonAssignmentsManager.unassign(taxonId, assigneeId, auth.model) - } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - TaxonWatchersManager.list(taxonId) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - TaxonWatchersManager.assign(taxonId, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - TaxonWatchersManager.unassign(taxonId, assigneeId, auth.model) - } - } - } - } ~ - // Amazon Order Single Assignments - pathPrefix("amazon-orders" / cordRefNumRegex) { refNum ⇒ - pathPrefix("assignees") { - (get & pathEnd) { - getOrFailures { - AmazonOrderAssignmentsManager.list(refNum) - } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - AmazonOrderAssignmentsManager.assign(refNum, payload, auth.model) + // Taxons Single Assignments + pathPrefix("taxons" / IntNumber) { taxonId ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + TaxonAssignmentsManager.list(taxonId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + TaxonAssignmentsManager.assign(taxonId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + TaxonAssignmentsManager.unassign(taxonId, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + TaxonWatchersManager.list(taxonId) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + TaxonWatchersManager.assign(taxonId, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + TaxonWatchersManager.unassign(taxonId, assigneeId, auth.model) + } + } } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - AmazonOrderAssignmentsManager.unassign(refNum, assigneeId, auth.model) - } - } } ~ - pathPrefix("watchers") { - (get & pathEnd) { - getOrFailures { - AmazonOrderWatchersManager.list(refNum) + // Amazon Order Single Assignments + pathPrefix("amazon-orders" / cordRefNumRegex) { refNum ⇒ + pathPrefix("assignees") { + (get & pathEnd) { + getOrFailures { + AmazonOrderAssignmentsManager.list(refNum) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + AmazonOrderAssignmentsManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + AmazonOrderAssignmentsManager.unassign(refNum, assigneeId, auth.model) + } + } + } ~ + pathPrefix("watchers") { + (get & pathEnd) { + getOrFailures { + AmazonOrderWatchersManager.list(refNum) + } + } ~ + (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ + mutateOrFailures { + AmazonOrderWatchersManager.assign(refNum, payload, auth.model) + } + } ~ + (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ + mutateOrFailures { + AmazonOrderWatchersManager.unassign(refNum, assigneeId, auth.model) + } + } } - } ~ - (post & pathEnd & entity(as[AssignmentPayload])) { payload ⇒ - mutateOrFailures { - AmazonOrderWatchersManager.assign(refNum, payload, auth.model) - } - } ~ - (delete & path(IntNumber) & pathEnd) { assigneeId ⇒ - mutateOrFailures { - AmazonOrderWatchersManager.unassign(refNum, assigneeId, auth.model) - } - } } - } } } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/CartRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/CartRoutes.scala index 8c6e85e3e4..2506f545f1 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/CartRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/CartRoutes.scala @@ -32,140 +32,140 @@ object CartRoutes { CartCreator.createCart(auth.model, payload) } } ~ - pathPrefix(cordRefNumRegex) { refNum ⇒ - (get & pathEnd) { - getOrFailures { - CartQueries.findOne(refNum) - } - } ~ - pathPrefix("coupon") { - (post & path(Segment) & pathEnd) { code ⇒ - mutateOrFailures { - CartPromotionUpdater.attachCoupon(auth.model, refNum.some, code) + pathPrefix(cordRefNumRegex) { refNum ⇒ + (get & pathEnd) { + getOrFailures { + CartQueries.findOne(refNum) } } ~ - (delete & pathEnd) { - mutateOrFailures { - CartPromotionUpdater.detachCoupon(auth.model, refNum.some) - } - } - } ~ - (post & path("checkout")) { - mutateOrFailures { - Checkout.fromCart(refNum) - } - } ~ - pathPrefix("line-items") { - (post & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { reqItems ⇒ - mutateOrFailures { - LineItemUpdater.updateQuantitiesOnCart(auth.model, refNum, reqItems) - } - } ~ - (patch & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { reqItems ⇒ - mutateOrFailures { - LineItemUpdater.addQuantitiesOnCart(auth.model, refNum, reqItems) - } - } ~ - (patch & path("attributes") & pathEnd & entity(as[Seq[UpdateOrderLineItemsPayload]])) { - reqItems ⇒ - mutateOrFailures { - LineItemUpdater.updateOrderLineItems(auth.model, reqItems, refNum) - } - } - } ~ - pathPrefix("payment-methods") { - pathPrefix("apple-pay") { - (post & pathEnd & entity(as[CreateApplePayPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addApplePayPayment(auth.model, payload, refNum.some) - } - } - } ~ - pathPrefix("credit-cards") { - (post & pathEnd & entity(as[CreditCardPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addCreditCard(auth.model, payload.creditCardId, refNum.some) - } + pathPrefix("coupon") { + (post & path(Segment) & pathEnd) { code ⇒ + mutateOrFailures { + CartPromotionUpdater.attachCoupon(auth.model, refNum.some, code) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + CartPromotionUpdater.detachCoupon(auth.model, refNum.some) + } + } } ~ - (delete & pathEnd) { + (post & path("checkout")) { mutateOrFailures { - CartPaymentUpdater.deleteCreditCard(auth.model, refNum.some) - } - } - } ~ - pathPrefix("gift-cards") { - (post & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addGiftCard(auth.model, payload, refNum.some) + Checkout.fromCart(refNum) } } ~ - (patch & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.editGiftCard(auth.model, payload, refNum.some) - } + pathPrefix("line-items") { + (post & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { reqItems ⇒ + mutateOrFailures { + LineItemUpdater.updateQuantitiesOnCart(auth.model, refNum, reqItems) + } + } ~ + (patch & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { reqItems ⇒ + mutateOrFailures { + LineItemUpdater.addQuantitiesOnCart(auth.model, refNum, reqItems) + } + } ~ + (patch & path("attributes") & pathEnd & entity(as[Seq[UpdateOrderLineItemsPayload]])) { + reqItems ⇒ + mutateOrFailures { + LineItemUpdater.updateOrderLineItems(auth.model, reqItems, refNum) + } + } } ~ - (delete & path(GiftCard.giftCardCodeRegex) & pathEnd) { code ⇒ - mutateOrFailures { - CartPaymentUpdater.deleteGiftCard(auth.model, code, refNum.some) - } - } - } ~ - pathPrefix("store-credit") { - (post & pathEnd & entity(as[StoreCreditPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addStoreCredit(auth.model, payload, refNum.some) - } + pathPrefix("payment-methods") { + pathPrefix("apple-pay") { + (post & pathEnd & entity(as[CreateApplePayPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addApplePayPayment(auth.model, payload, refNum.some) + } + } + } ~ + pathPrefix("credit-cards") { + (post & pathEnd & entity(as[CreditCardPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addCreditCard(auth.model, payload.creditCardId, refNum.some) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + CartPaymentUpdater.deleteCreditCard(auth.model, refNum.some) + } + } + } ~ + pathPrefix("gift-cards") { + (post & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addGiftCard(auth.model, payload, refNum.some) + } + } ~ + (patch & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.editGiftCard(auth.model, payload, refNum.some) + } + } ~ + (delete & path(GiftCard.giftCardCodeRegex) & pathEnd) { code ⇒ + mutateOrFailures { + CartPaymentUpdater.deleteGiftCard(auth.model, code, refNum.some) + } + } + } ~ + pathPrefix("store-credit") { + (post & pathEnd & entity(as[StoreCreditPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addStoreCredit(auth.model, payload, refNum.some) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + CartPaymentUpdater.deleteStoreCredit(auth.model, refNum.some) + } + } + } } ~ - (delete & pathEnd) { - mutateOrFailures { - CartPaymentUpdater.deleteStoreCredit(auth.model, refNum.some) - } - } - } - } ~ - pathPrefix("shipping-address") { - (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ - mutateOrFailures { - CartShippingAddressUpdater.createShippingAddressFromPayload(auth.model, - payload, - Some(refNum)) - } - } ~ - (patch & path(IntNumber) & pathEnd) { addressId ⇒ - mutateOrFailures { - CartShippingAddressUpdater.createShippingAddressFromAddressId(auth.model, - addressId, - Some(refNum)) - } - } ~ - (patch & pathEnd & entity(as[UpdateAddressPayload])) { payload ⇒ - mutateOrFailures { - CartShippingAddressUpdater.updateShippingAddressFromPayload(auth.model, - payload, - Some(refNum)) - } - } ~ - (delete & pathEnd) { - mutateOrFailures { - CartShippingAddressUpdater.removeShippingAddress(auth.model, Some(refNum)) - } - } - } ~ - pathPrefix("shipping-method") { - (patch & pathEnd & entity(as[UpdateShippingMethod])) { payload ⇒ - mutateOrFailures { - CartShippingMethodUpdater.updateShippingMethod(auth.model, - payload.shippingMethodId, - Some(refNum)) - } - } ~ - (delete & pathEnd) { - mutateOrFailures { - CartShippingMethodUpdater.deleteShippingMethod(auth.model, Some(refNum)) + pathPrefix("shipping-address") { + (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ + mutateOrFailures { + CartShippingAddressUpdater.createShippingAddressFromPayload(auth.model, + payload, + Some(refNum)) + } + } ~ + (patch & path(IntNumber) & pathEnd) { addressId ⇒ + mutateOrFailures { + CartShippingAddressUpdater.createShippingAddressFromAddressId(auth.model, + addressId, + Some(refNum)) + } + } ~ + (patch & pathEnd & entity(as[UpdateAddressPayload])) { payload ⇒ + mutateOrFailures { + CartShippingAddressUpdater.updateShippingAddressFromPayload(auth.model, + payload, + Some(refNum)) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + CartShippingAddressUpdater.removeShippingAddress(auth.model, Some(refNum)) + } + } + } ~ + pathPrefix("shipping-method") { + (patch & pathEnd & entity(as[UpdateShippingMethod])) { payload ⇒ + mutateOrFailures { + CartShippingMethodUpdater.updateShippingMethod(auth.model, + payload.shippingMethodId, + Some(refNum)) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + CartShippingMethodUpdater.deleteShippingMethod(auth.model, Some(refNum)) + } + } } - } } - } } } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/CategoryRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/CategoryRoutes.scala index fcb259c2f3..85c3d5c9fc 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/CategoryRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/CategoryRoutes.scala @@ -14,8 +14,7 @@ import phoenix.utils.http.JsonSupport._ object CategoryRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("categories") { pathPrefix(IntNumber / "form") { categoryId ⇒ @@ -25,40 +24,39 @@ object CategoryRoutes { } } } ~ - pathPrefix(Segment) { context ⇒ - pathPrefix(IntNumber) { categoryId ⇒ - (get & pathEnd) { - getOrFailures { - CategoryManager.getCategory(categoryId, context) - } - } ~ - (patch & pathEnd & entity(as[UpdateFullCategory])) { payload ⇒ - mutateOrFailures { - CategoryManager.updateCategory(auth.model, categoryId, payload, context) - } - } ~ - pathPrefix("baked") { + pathPrefix(Segment) { context ⇒ + pathPrefix(IntNumber) { categoryId ⇒ (get & pathEnd) { getOrFailures { - CategoryManager.getIlluminatedCategory(categoryId, context) + CategoryManager.getCategory(categoryId, context) + } + } ~ + (patch & pathEnd & entity(as[UpdateFullCategory])) { payload ⇒ + mutateOrFailures { + CategoryManager.updateCategory(auth.model, categoryId, payload, context) + } + } ~ + pathPrefix("baked") { + (get & pathEnd) { + getOrFailures { + CategoryManager.getIlluminatedCategory(categoryId, context) + } + } + } ~ + pathPrefix("shadow") { + (get & pathEnd) { + getOrFailures { + CategoryManager.getShadow(categoryId, context) + } + } } - } } ~ - pathPrefix("shadow") { - (get & pathEnd) { - getOrFailures { - CategoryManager.getShadow(categoryId, context) + (post & pathEnd & entity(as[CreateFullCategory])) { payload ⇒ + mutateOrFailures { + CategoryManager.createCategory(auth.model, payload, context) } } - } - } ~ - (post & pathEnd & entity(as[CreateFullCategory])) { payload ⇒ - mutateOrFailures { - CategoryManager.createCategory(auth.model, payload, context) - } } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/CouponRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/CouponRoutes.scala index 6169485054..0d3736bc80 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/CouponRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/CouponRoutes.scala @@ -14,8 +14,7 @@ import phoenix.utils.http.JsonSupport._ object CouponRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("coupons") { @@ -28,54 +27,53 @@ object CouponRoutes { } } } ~ - pathPrefix(IntNumber) { id ⇒ - (post & pathEnd & entity(as[GenerateCouponCodes])) { payload ⇒ - mutateOrFailures { - CouponManager.generateCodes(id, payload, auth.model) + pathPrefix(IntNumber) { id ⇒ + (post & pathEnd & entity(as[GenerateCouponCodes])) { payload ⇒ + mutateOrFailures { + CouponManager.generateCodes(id, payload, auth.model) + } } } - } } ~ - pathPrefix(IntNumber) { id ⇒ - (get & pathEnd) { - mutateOrFailures { - CouponManager.getCodes(id) + pathPrefix(IntNumber) { id ⇒ + (get & pathEnd) { + mutateOrFailures { + CouponManager.getCodes(id) + } } } - } } ~ - pathPrefix(Segment) { (context) ⇒ - (post & pathEnd & entity(as[CreateCoupon])) { payload ⇒ - mutateOrFailures { - CouponManager.create(payload, context, Some(auth.model)) - } - } ~ - pathPrefix(IntNumber) { id ⇒ - (get & pathEnd) { - getOrFailures { - CouponManager.getIlluminated(id, context) - } - } ~ - (patch & pathEnd & entity(as[UpdateCoupon])) { payload ⇒ + pathPrefix(Segment) { (context) ⇒ + (post & pathEnd & entity(as[CreateCoupon])) { payload ⇒ mutateOrFailures { - CouponManager.update(id, payload, context, auth.model) + CouponManager.create(payload, context, Some(auth.model)) } } ~ - (delete & pathEnd) { - mutateOrFailures { - CouponManager.archiveByContextAndId(context, id) - } - } - } ~ - pathPrefix(Segment) { code ⇒ - (get & pathEnd) { - getOrFailures { - CouponManager.getIlluminatedByCode(code, context) + pathPrefix(IntNumber) { id ⇒ + (get & pathEnd) { + getOrFailures { + CouponManager.getIlluminated(id, context) + } + } ~ + (patch & pathEnd & entity(as[UpdateCoupon])) { payload ⇒ + mutateOrFailures { + CouponManager.update(id, payload, context, auth.model) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + CouponManager.archiveByContextAndId(context, id) + } + } + } ~ + pathPrefix(Segment) { code ⇒ + (get & pathEnd) { + getOrFailures { + CouponManager.getIlluminatedByCode(code, context) + } + } } - } } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/CustomerGroupsRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/CustomerGroupsRoutes.scala index 129e105a92..3fc3cd25b5 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/CustomerGroupsRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/CustomerGroupsRoutes.scala @@ -13,8 +13,7 @@ import phoenix.utils.http.Http._ import phoenix.utils.http.JsonSupport._ object CustomerGroupsRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("customer-groups") { (get & pathEnd) { @@ -22,43 +21,42 @@ object CustomerGroupsRoutes { GroupManager.findAll } } ~ - (post & pathEnd & entity(as[CustomerGroupPayload])) { payload ⇒ - mutateOrFailures { - GroupManager.create(payload, auth.model) + (post & pathEnd & entity(as[CustomerGroupPayload])) { payload ⇒ + mutateOrFailures { + GroupManager.create(payload, auth.model) + } + } ~ + pathPrefix("templates") { + (get & pathEnd) { + getOrFailures { + GroupTemplateManager.getAll() + } + } } - } ~ - pathPrefix("templates") { + } ~ + pathPrefix("customer-groups" / IntNumber) { groupId ⇒ (get & pathEnd) { getOrFailures { - GroupTemplateManager.getAll() + GroupManager.getById(groupId) + } + } ~ + (patch & pathEnd & entity(as[CustomerGroupPayload])) { payload ⇒ + mutateOrFailures { + GroupManager.update(groupId, payload, auth.model) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + GroupManager.delete(groupId, auth.model) + } + } ~ + path("customers") { + (post & pathEnd & entity(as[CustomerGroupMemberSyncPayload])) { payload ⇒ + doOrFailures( + GroupMemberManager.sync(groupId, payload) + ) + } } - } - } - } ~ - pathPrefix("customer-groups" / IntNumber) { groupId ⇒ - (get & pathEnd) { - getOrFailures { - GroupManager.getById(groupId) - } - } ~ - (patch & pathEnd & entity(as[CustomerGroupPayload])) { payload ⇒ - mutateOrFailures { - GroupManager.update(groupId, payload, auth.model) - } - } ~ - (delete & pathEnd) { - deleteOrFailures { - GroupManager.delete(groupId, auth.model) - } - } ~ - path("customers") { - (post & pathEnd & entity(as[CustomerGroupMemberSyncPayload])) { payload ⇒ - doOrFailures( - GroupMemberManager.sync(groupId, payload) - ) - } } - } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/CustomerRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/CustomerRoutes.scala index 8c7f00f047..c5d403095e 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/CustomerRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/CustomerRoutes.scala @@ -39,151 +39,151 @@ object CustomerRoutes { CustomerManager.createFromAdmin(payload, Some(auth.model), context) } } ~ - pathPrefix("email" / Segment) { customerEmail ⇒ - (get & pathEnd) { - getOrFailures { - CustomerManager.getByEmail(customerEmail) + pathPrefix("email" / Segment) { customerEmail ⇒ + (get & pathEnd) { + getOrFailures { + CustomerManager.getByEmail(customerEmail) + } } } - } } ~ - pathPrefix("customers" / IntNumber) { accountId ⇒ - (get & pathEnd) { - getOrFailures { - CustomerManager.getByAccountId(accountId) - } - } ~ - (get & path("cart")) { - getOrFailures { - CartQueries.findOrCreateCartByAccountId(accountId, ctx, Some(auth.model)) - } - } ~ - (post & path("checkout") & pathEnd & entity(as[CheckoutCart])) { payload ⇒ - mutateOrFailures { - Checkout.forAdminOneClick(accountId, payload) - } - } ~ - (patch & pathEnd & entity(as[UpdateCustomerPayload])) { payload ⇒ - mutateOrFailures { - CustomerManager.updateFromAdmin(accountId, payload, Some(auth.model)) - } - } ~ - (post & path("activate") & pathEnd & entity(as[ActivateCustomerPayload])) { payload ⇒ - mutateOrFailures { - CustomerManager.activate(accountId, payload, auth.model) - } - } ~ - (post & path("disable") & pathEnd & entity(as[ToggleUserDisabled])) { payload ⇒ - mutateOrFailures { - CustomerManager.toggleDisabled(accountId, payload.disabled, auth.model) - } - } ~ - (post & path("blacklist") & pathEnd & entity(as[ToggleUserBlacklisted])) { payload ⇒ - mutateOrFailures { - CustomerManager.toggleBlacklisted(accountId, payload.blacklisted, auth.model) - } - } ~ - pathPrefix("addresses") { + pathPrefix("customers" / IntNumber) { accountId ⇒ (get & pathEnd) { getOrFailures { - AddressManager.findAllByAccountId(accountId) - } - } ~ - (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ - mutateOrFailures { - AddressManager.create(auth.model, payload, accountId) - } - } ~ - (post & path(IntNumber / "default") & pathEnd) { addressId ⇒ - mutateOrFailures { - AddressManager.setDefaultShippingAddress(addressId, accountId) - } - } ~ - (get & path(IntNumber) & pathEnd) { addressId ⇒ - getOrFailures { - AddressManager.get(auth.model, addressId, accountId) - } - } ~ - (delete & path(IntNumber) & pathEnd) { addressId ⇒ - deleteOrFailures { - AddressManager.remove(auth.model, addressId, accountId) + CustomerManager.getByAccountId(accountId) } } ~ - (delete & path("default") & pathEnd) { - deleteOrFailures { - AddressManager.removeDefaultShippingAddress(accountId) - } - } ~ - (patch & path(IntNumber) & pathEnd & entity(as[CreateAddressPayload])) { - (addressId, payload) ⇒ + (get & path("cart")) { + getOrFailures { + CartQueries.findOrCreateCartByAccountId(accountId, ctx, Some(auth.model)) + } + } ~ + (post & path("checkout") & pathEnd & entity(as[CheckoutCart])) { payload ⇒ mutateOrFailures { - AddressManager.edit(auth.model, addressId, accountId, payload) + Checkout.forAdminOneClick(accountId, payload) + } + } ~ + (patch & pathEnd & entity(as[UpdateCustomerPayload])) { payload ⇒ + mutateOrFailures { + CustomerManager.updateFromAdmin(accountId, payload, Some(auth.model)) + } + } ~ + (post & path("activate") & pathEnd & entity(as[ActivateCustomerPayload])) { payload ⇒ + mutateOrFailures { + CustomerManager.activate(accountId, payload, auth.model) + } + } ~ + (post & path("disable") & pathEnd & entity(as[ToggleUserDisabled])) { payload ⇒ + mutateOrFailures { + CustomerManager.toggleDisabled(accountId, payload.disabled, auth.model) + } + } ~ + (post & path("blacklist") & pathEnd & entity(as[ToggleUserBlacklisted])) { payload ⇒ + mutateOrFailures { + CustomerManager.toggleBlacklisted(accountId, payload.blacklisted, auth.model) + } + } ~ + pathPrefix("addresses") { + (get & pathEnd) { + getOrFailures { + AddressManager.findAllByAccountId(accountId) + } + } ~ + (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ + mutateOrFailures { + AddressManager.create(auth.model, payload, accountId) + } + } ~ + (post & path(IntNumber / "default") & pathEnd) { addressId ⇒ + mutateOrFailures { + AddressManager.setDefaultShippingAddress(addressId, accountId) + } + } ~ + (get & path(IntNumber) & pathEnd) { addressId ⇒ + getOrFailures { + AddressManager.get(auth.model, addressId, accountId) + } + } ~ + (delete & path(IntNumber) & pathEnd) { addressId ⇒ + deleteOrFailures { + AddressManager.remove(auth.model, addressId, accountId) + } + } ~ + (delete & path("default") & pathEnd) { + deleteOrFailures { + AddressManager.removeDefaultShippingAddress(accountId) + } + } ~ + (patch & path(IntNumber) & pathEnd & entity(as[CreateAddressPayload])) { + (addressId, payload) ⇒ + mutateOrFailures { + AddressManager.edit(auth.model, addressId, accountId, payload) + } + } + } ~ + pathPrefix("payment-methods" / "credit-cards") { + (get & pathEnd) { + complete { + CreditCardManager.creditCardsInWalletFor(accountId) + } + } ~ + (post & path(IntNumber / "default") & pathEnd) { cardId ⇒ + mutateOrFailures { + CreditCardManager.setDefaultCreditCard(accountId, cardId) + } + } ~ + (post & pathEnd & entity(as[CreateCreditCardFromTokenPayload])) { payload ⇒ + mutateOrFailures { + CreditCardManager.createCardFromToken(accountId, payload, Some(auth.model)) + } + } ~ + (patch & path(IntNumber) & pathEnd & entity(as[EditCreditCard])) { (cardId, payload) ⇒ + mutateOrFailures { + CreditCardManager.editCreditCard(accountId, cardId, payload, Some(auth.model)) + } + } ~ + (delete & path(IntNumber) & pathEnd) { cardId ⇒ + deleteOrFailures { + CreditCardManager.deleteCreditCard(accountId, cardId, Some(auth.model)) + } + } ~ + (delete & path("default") & pathEnd) { + deleteOrFailures { + CreditCardManager.removeDefaultCreditCard(accountId) + } + } + } ~ + pathPrefix("payment-methods" / "store-credit") { + (get & path("totals")) { + getOrFailures { + StoreCreditService.totalsForCustomer(accountId) + } + } ~ + (post & pathEnd & entity(as[CreateManualStoreCredit])) { payload ⇒ + mutateOrFailures { + StoreCreditService.createManual(auth.model, accountId, payload) + } + } ~ + (post & path("custom") & pathEnd & entity(as[CreateExtensionStoreCredit])) { payload ⇒ + mutateOrFailures { + // TODO: prohibit access from non-extensions? by user probably? + StoreCreditService.createFromExtension(auth.model, accountId, payload) + } + } ~ + (post & path(IntNumber / "convert") & pathEnd) { storeCreditId ⇒ + mutateOrFailures { + CustomerCreditConverter.toGiftCard(storeCreditId, accountId, auth.model) + } + } + } ~ + pathPrefix("customer-groups") { + (post & pathEnd & entity(as[AddCustomerToGroups])) { payload ⇒ + mutateOrFailures { + GroupMemberManager.addCustomerToGroups(accountId, payload.groups) + } } - } - } ~ - pathPrefix("payment-methods" / "credit-cards") { - (get & pathEnd) { - complete { - CreditCardManager.creditCardsInWalletFor(accountId) - } - } ~ - (post & path(IntNumber / "default") & pathEnd) { cardId ⇒ - mutateOrFailures { - CreditCardManager.setDefaultCreditCard(accountId, cardId) - } - } ~ - (post & pathEnd & entity(as[CreateCreditCardFromTokenPayload])) { payload ⇒ - mutateOrFailures { - CreditCardManager.createCardFromToken(accountId, payload, Some(auth.model)) - } - } ~ - (patch & path(IntNumber) & pathEnd & entity(as[EditCreditCard])) { (cardId, payload) ⇒ - mutateOrFailures { - CreditCardManager.editCreditCard(accountId, cardId, payload, Some(auth.model)) - } - } ~ - (delete & path(IntNumber) & pathEnd) { cardId ⇒ - deleteOrFailures { - CreditCardManager.deleteCreditCard(accountId, cardId, Some(auth.model)) - } - } ~ - (delete & path("default") & pathEnd) { - deleteOrFailures { - CreditCardManager.removeDefaultCreditCard(accountId) - } - } - } ~ - pathPrefix("payment-methods" / "store-credit") { - (get & path("totals")) { - getOrFailures { - StoreCreditService.totalsForCustomer(accountId) - } - } ~ - (post & pathEnd & entity(as[CreateManualStoreCredit])) { payload ⇒ - mutateOrFailures { - StoreCreditService.createManual(auth.model, accountId, payload) - } - } ~ - (post & path("custom") & pathEnd & entity(as[CreateExtensionStoreCredit])) { payload ⇒ - mutateOrFailures { - // TODO: prohibit access from non-extensions? by user probably? - StoreCreditService.createFromExtension(auth.model, accountId, payload) - } - } ~ - (post & path(IntNumber / "convert") & pathEnd) { storeCreditId ⇒ - mutateOrFailures { - CustomerCreditConverter.toGiftCard(storeCreditId, accountId, auth.model) - } - } - } ~ - pathPrefix("customer-groups") { - (post & pathEnd & entity(as[AddCustomerToGroups])) { payload ⇒ - mutateOrFailures { - GroupMemberManager.addCustomerToGroups(accountId, payload.groups) } - } } - } } } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/DevRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/DevRoutes.scala index 45f5bf0e2c..907f12e5f7 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/DevRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/DevRoutes.scala @@ -20,7 +20,7 @@ import phoenix.utils.http.JsonSupport._ object DevRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("order-time-machine") { (post & pathEnd & entity(as[OrderTimeMachine])) { payload ⇒ @@ -29,43 +29,44 @@ object DevRoutes { } } } ~ - pathPrefix("set-log-level") { - (post & pathEnd & entity(as[ChangeLogLevel])) { payload ⇒ - complete { - val logger = LoggerFactory.getLogger(payload.logger).asInstanceOf[LogBackLogger] - val oldLevel = logger.getLevel - val newLevel = Level.toLevel(payload.level, oldLevel) - logger.setLevel(newLevel) - ChangeLogLevelResponse(oldLevel = oldLevel.toString, - newLevel = newLevel.toString, - logger = logger.getName) + pathPrefix("set-log-level") { + (post & pathEnd & entity(as[ChangeLogLevel])) { payload ⇒ + complete { + val logger = LoggerFactory.getLogger(payload.logger).asInstanceOf[LogBackLogger] + val oldLevel = logger.getLevel + val newLevel = Level.toLevel(payload.level, oldLevel) + logger.setLevel(newLevel) + ChangeLogLevelResponse(oldLevel = oldLevel.toString, + newLevel = newLevel.toString, + logger = logger.getName) + } } - } - } ~ - pathPrefix("credit-card-token") { - (post & pathEnd & entity(as[CreditCardDetailsPayload])) { payload ⇒ - goodOrFailures { - TestStripeSupport - .createToken(cardNumber = payload.cardNumber, - expMonth = payload.expMonth, - expYear = payload.expYear, - cvv = payload.cvv, - address = Address.fromPayload(payload.address, payload.customerId)) - .map { token ⇒ - CreditCardTokenResponse(token = token.getId, - brand = token.getCard.getBrand, - lastFour = token.getCard.getLast4) - } + } ~ + pathPrefix("credit-card-token") { + (post & pathEnd & entity(as[CreditCardDetailsPayload])) { payload ⇒ + goodOrFailures { + TestStripeSupport + .createToken( + cardNumber = payload.cardNumber, + expMonth = payload.expMonth, + expYear = payload.expYear, + cvv = payload.cvv, + address = Address.fromPayload(payload.address, payload.customerId) + ) + .map { token ⇒ + CreditCardTokenResponse(token = token.getId, + brand = token.getCard.getBrand, + lastFour = token.getCard.getLast4) + } + } + } + } ~ + pathPrefix("version") { + (get & pathEnd) { + complete(renderPlain(version)) } } - } ~ - pathPrefix("version") { - (get & pathEnd) { - complete(renderPlain(version)) - } - } } - } lazy val version: String = { val stream = getClass.getResourceAsStream("/version") diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/DiscountRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/DiscountRoutes.scala index 3c9eb1ca0d..64d0073e87 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/DiscountRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/DiscountRoutes.scala @@ -14,8 +14,7 @@ import phoenix.utils.http.JsonSupport._ object DiscountRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("discounts") { pathPrefix("forms" / IntNumber) { id ⇒ @@ -25,38 +24,37 @@ object DiscountRoutes { } } } ~ - pathPrefix("shadows" / Segment / IntNumber) { (context, id) ⇒ - (get & pathEnd) { - getOrFailures { - DiscountManager.getShadow(id, context) - } - } - } ~ - pathPrefix(Segment) { (context) ⇒ - (post & pathEnd & entity(as[CreateDiscount])) { payload ⇒ - mutateOrFailures { - DiscountManager.create(payload, context) - } - } ~ - pathPrefix(IntNumber) { id ⇒ - (get & path("baked")) { - getOrFailures { - DiscountManager.getIlluminated(id, context) - } - } ~ + pathPrefix("shadows" / Segment / IntNumber) { (context, id) ⇒ (get & pathEnd) { getOrFailures { - DiscountManager.get(id, context) + DiscountManager.getShadow(id, context) } - } ~ - (patch & pathEnd & entity(as[UpdateDiscount])) { payload ⇒ + } + } ~ + pathPrefix(Segment) { (context) ⇒ + (post & pathEnd & entity(as[CreateDiscount])) { payload ⇒ mutateOrFailures { - DiscountManager.update(id, payload, context) + DiscountManager.create(payload, context) + } + } ~ + pathPrefix(IntNumber) { id ⇒ + (get & path("baked")) { + getOrFailures { + DiscountManager.getIlluminated(id, context) + } + } ~ + (get & pathEnd) { + getOrFailures { + DiscountManager.get(id, context) + } + } ~ + (patch & pathEnd & entity(as[UpdateDiscount])) { payload ⇒ + mutateOrFailures { + DiscountManager.update(id, payload, context) + } + } } - } } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/GenericTreeRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/GenericTreeRoutes.scala index b04a81f424..6db06c2d0b 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/GenericTreeRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/GenericTreeRoutes.scala @@ -14,8 +14,7 @@ import phoenix.utils.http.JsonSupport._ object GenericTreeRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("tree" / Segment / Segment) { (context, name) ⇒ (get & pathEnd) { @@ -23,34 +22,33 @@ object GenericTreeRoutes { TreeManager.getFullTree(name, context) } } ~ - (post & pathEnd & entity(as[NodePayload])) { payload ⇒ - mutateOrFailures { - TreeManager.updateTree(name, context, payload) - } - } ~ - pathPrefix(Segment) { (path) ⇒ (post & pathEnd & entity(as[NodePayload])) { payload ⇒ mutateOrFailures { - TreeManager.updateTree(name, context, payload, Some(path)) + TreeManager.updateTree(name, context, payload) } } ~ - (patch & pathEnd & entity(as[NodeValuesPayload])) { payload ⇒ + pathPrefix(Segment) { (path) ⇒ + (post & pathEnd & entity(as[NodePayload])) { payload ⇒ + mutateOrFailures { + TreeManager.updateTree(name, context, payload, Some(path)) + } + } ~ + (patch & pathEnd & entity(as[NodeValuesPayload])) { payload ⇒ + mutateOrFailures { + TreeManager.editNode(name, context, path, payload) + } + } + } ~ + (patch & pathEnd & entity(as[MoveNodePayload])) { payload ⇒ mutateOrFailures { - TreeManager.editNode(name, context, path, payload) + TreeManager.moveNode(name, context, payload) + } + } ~ + (patch & pathEnd & entity(as[MoveNodePayload])) { payload ⇒ + mutateOrFailures { + TreeManager.moveNode(name, context, payload) } } - } ~ - (patch & pathEnd & entity(as[MoveNodePayload])) { payload ⇒ - mutateOrFailures { - TreeManager.moveNode(name, context, payload) - } - } ~ - (patch & pathEnd & entity(as[MoveNodePayload])) { payload ⇒ - mutateOrFailures { - TreeManager.moveNode(name, context, payload) - } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/GiftCardRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/GiftCardRoutes.scala index 360e337826..403025bf59 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/GiftCardRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/GiftCardRoutes.scala @@ -17,69 +17,67 @@ import phoenix.utils.http.JsonSupport._ object GiftCardRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("customer-gift-cards") { path("bulk") { (post & pathEnd & entity(as[Seq[GiftCardCreatedByCustomer]])) { payload ⇒ mutateOrFailures { DbResultT.seqCollectFailures( - payload.map(GiftCardService.createByCustomer(auth.model, _)).toList) + payload.map(GiftCardService.createByCustomer(auth.model, _)).toList) } } } ~ - (post & pathEnd & entity(as[GiftCardCreatedByCustomer])) { payload ⇒ - mutateOrFailures { - GiftCardService.createByCustomer(auth.model, payload) - } - } - } ~ - pathPrefix("gift-cards") { - path("bulk") { - (post & pathEnd & entity(as[GiftCardBulkCreateByCsr])) { payload ⇒ + (post & pathEnd & entity(as[GiftCardCreatedByCustomer])) { payload ⇒ mutateOrFailures { - GiftCardService.createBulkByAdmin(auth.model, payload) - } - } ~ - (patch & pathEnd & entity(as[GiftCardBulkUpdateStateByCsr])) { payload ⇒ - mutateOrFailures { - GiftCardService.bulkUpdateStateByCsr(payload, auth.model) + GiftCardService.createByCustomer(auth.model, payload) } } - } ~ - (post & pathEnd & entity(as[GiftCardCreateByCsr])) { payload ⇒ - mutateOrFailures { - GiftCardService.createByAdmin(auth.model, payload) - } - } } ~ - pathPrefix("gift-cards" / giftCardCodeRegex) { code ⇒ - (get & pathEnd) { - getOrFailures { - GiftCardService.getByCode(code) - } - } ~ - (patch & pathEnd & entity(as[GiftCardUpdateStateByCsr])) { payload ⇒ - mutateOrFailures { - GiftCardService.updateStateByCsr(code, payload, auth.model) - } + pathPrefix("gift-cards") { + path("bulk") { + (post & pathEnd & entity(as[GiftCardBulkCreateByCsr])) { payload ⇒ + mutateOrFailures { + GiftCardService.createBulkByAdmin(auth.model, payload) + } + } ~ + (patch & pathEnd & entity(as[GiftCardBulkUpdateStateByCsr])) { payload ⇒ + mutateOrFailures { + GiftCardService.bulkUpdateStateByCsr(payload, auth.model) + } + } + } ~ + (post & pathEnd & entity(as[GiftCardCreateByCsr])) { payload ⇒ + mutateOrFailures { + GiftCardService.createByAdmin(auth.model, payload) + } + } } ~ - path("transactions") { + pathPrefix("gift-cards" / giftCardCodeRegex) { code ⇒ (get & pathEnd) { getOrFailures { - GiftCardAdjustmentsService.forGiftCard(code) + GiftCardService.getByCode(code) } - } - } ~ - path("convert" / IntNumber) { customerId ⇒ - (post & pathEnd) { - mutateOrFailures { - CustomerCreditConverter.toStoreCredit(code, customerId, auth.model) + } ~ + (patch & pathEnd & entity(as[GiftCardUpdateStateByCsr])) { payload ⇒ + mutateOrFailures { + GiftCardService.updateStateByCsr(code, payload, auth.model) + } + } ~ + path("transactions") { + (get & pathEnd) { + getOrFailures { + GiftCardAdjustmentsService.forGiftCard(code) + } + } + } ~ + path("convert" / IntNumber) { customerId ⇒ + (post & pathEnd) { + mutateOrFailures { + CustomerCreditConverter.toStoreCredit(code, customerId, auth.model) + } + } } - } } - } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/ImageRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/ImageRoutes.scala index 1df2299729..1ffa5e1257 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/ImageRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/ImageRoutes.scala @@ -18,7 +18,7 @@ import phoenix.utils.http.Http._ import phoenix.utils.http.JsonSupport._ object ImageRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis, sys: ActorSystem): Route = { + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis, sys: ActorSystem): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("images" / Segment) { context ⇒ extractRequestContext { ctx ⇒ @@ -32,50 +32,48 @@ object ImageRoutes { } } } ~ - pathPrefix("albums") { - pathPrefix(Segment) { context ⇒ - (post & pathEnd & entity(as[AlbumPayload])) { payload ⇒ - mutateOrFailures { - ImageManager.createAlbum(payload, context) - } - } ~ - pathPrefix(IntNumber) { albumId ⇒ - (get & pathEnd) { - getOrFailures { - ImageManager.getAlbum(albumId, context) - } - } ~ - (patch & pathEnd & entity(as[AlbumPayload])) { payload ⇒ + pathPrefix("albums") { + pathPrefix(Segment) { context ⇒ + (post & pathEnd & entity(as[AlbumPayload])) { payload ⇒ mutateOrFailures { - ImageManager.updateAlbum(albumId, payload, context) + ImageManager.createAlbum(payload, context) } } ~ - (delete & pathEnd) { - mutateOrFailures { - ImageManager.archiveByContextAndId(albumId, context) - } - } ~ - pathPrefix("images") { - extractRequestContext { ctx ⇒ - implicit val materializer = ctx.materializer - implicit val ec = ctx.executionContext - - (post & pathEnd & entityOr(as[Multipart.FormData], ImageNotFoundInPayload)) { - formData ⇒ + pathPrefix(IntNumber) { albumId ⇒ + (get & pathEnd) { + getOrFailures { + ImageManager.getAlbum(albumId, context) + } + } ~ + (patch & pathEnd & entity(as[AlbumPayload])) { payload ⇒ mutateOrFailures { - ImageFacade.uploadImagesFromMultipartToAlbum(albumId, context, formData) + ImageManager.updateAlbum(albumId, payload, context) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + ImageManager.archiveByContextAndId(albumId, context) + } + } ~ + pathPrefix("images") { + extractRequestContext { ctx ⇒ + implicit val materializer = ctx.materializer + implicit val ec = ctx.executionContext + + (post & pathEnd & entityOr(as[Multipart.FormData], ImageNotFoundInPayload)) { formData ⇒ + mutateOrFailures { + ImageFacade.uploadImagesFromMultipartToAlbum(albumId, context, formData) + } + } ~ + (path("byUrl") & post & entity(as[ImagePayload])) { payload ⇒ + mutateOrFailures { + ImageFacade.uploadImagesFromPayloadToAlbum(albumId, context, payload) + } + } } - } ~ - (path("byUrl") & post & entity(as[ImagePayload])) { payload ⇒ - mutateOrFailures { - ImageFacade.uploadImagesFromPayloadToAlbum(albumId, context, payload) } - } } - } } } - } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/NotificationRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/NotificationRoutes.scala index 9184c24966..1dbecf9215 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/NotificationRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/NotificationRoutes.scala @@ -21,7 +21,7 @@ object NotificationRoutes { mat: Mat, auth: AuthData[User], apis: Apis, - system: akka.actor.ActorSystem): Route = { + system: akka.actor.ActorSystem): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("notifications") { (get & pathEnd) { @@ -29,17 +29,16 @@ object NotificationRoutes { NotificationFacade.streamByAdminId(auth.account.id) } } ~ - (post & pathEnd & entity(as[CreateNotification])) { payload ⇒ - mutateOrFailures { - NotificationManager.createNotification(payload) + (post & pathEnd & entity(as[CreateNotification])) { payload ⇒ + mutateOrFailures { + NotificationManager.createNotification(payload) + } + } ~ + (post & path("last-seen" / IntNumber) & pathEnd) { notificationId ⇒ + mutateOrFailures { + NotificationManager.updateLastSeen(auth.account.id, notificationId) + } } - } ~ - (post & path("last-seen" / IntNumber) & pathEnd) { notificationId ⇒ - mutateOrFailures { - NotificationManager.updateLastSeen(auth.account.id, notificationId) - } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/ObjectRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/ObjectRoutes.scala index dc30e8bf40..25b3bef06f 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/ObjectRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/ObjectRoutes.scala @@ -13,7 +13,7 @@ import phoenix.utils.http.Http._ import phoenix.utils.http.JsonSupport._ object ObjectRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("object" / "schemas") { (get & pathEnd) { @@ -21,26 +21,25 @@ object ObjectRoutes { ObjectSchemasManager.getAllSchemas() } } ~ - pathPrefix("byKind") { - (get & path(Segment)) { kind ⇒ - getOrFailures { - ObjectSchemasManager.getSchemasForKind(kind) - } - } - } ~ - (pathPrefix("byName") & path(Segment)) { schemaName ⇒ - (get & pathEnd) { - getOrFailures { - ObjectSchemasManager.getSchema(schemaName) + pathPrefix("byKind") { + (get & path(Segment)) { kind ⇒ + getOrFailures { + ObjectSchemasManager.getSchemasForKind(kind) + } } } ~ - (post & entity(as[UpdateObjectSchema])) { payload ⇒ - mutateOrFailures { - ObjectSchemasManager.update(schemaName, payload) - } + (pathPrefix("byName") & path(Segment)) { schemaName ⇒ + (get & pathEnd) { + getOrFailures { + ObjectSchemasManager.getSchema(schemaName) + } + } ~ + (post & entity(as[UpdateObjectSchema])) { payload ⇒ + mutateOrFailures { + ObjectSchemasManager.update(schemaName, payload) + } + } } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/OrderRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/OrderRoutes.scala index 19ebbd89c7..048c5b2069 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/OrderRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/OrderRoutes.scala @@ -35,172 +35,170 @@ object OrderRoutes { CartCreator.createCart(auth.model, payload) } } ~ - (patch & pathEnd & entity(as[BulkUpdateOrdersPayload])) { payload ⇒ - mutateOrFailures { - OrderStateUpdater.updateStates(auth.model, payload.referenceNumbers, payload.state) - } - } - } ~ - pathPrefix("orders" / cordRefNumRegex) { refNum ⇒ - (get & pathEnd) { - getOrFailures { - OrderQueries.findOne(refNum) - } - } ~ - pathPrefix("line-items") { - (patch & pathEnd & entity(as[Seq[UpdateOrderLineItemsPayload]])) { reqItems ⇒ - mutateOrFailures { - LineItemUpdater.updateOrderLineItems(auth.model, reqItems, refNum) - } - } - } ~ - // deprecated in favor of /orders/line-items - pathPrefix("order-line-items") { - (patch & pathEnd & entity(as[Seq[UpdateOrderLineItemsPayload]])) { reqItems ⇒ + (patch & pathEnd & entity(as[BulkUpdateOrdersPayload])) { payload ⇒ mutateOrFailures { - LineItemUpdater.updateOrderLineItems(auth.model, reqItems, refNum) + OrderStateUpdater.updateStates(auth.model, payload.referenceNumbers, payload.state) } } - } ~ - (patch & pathEnd & entity(as[UpdateOrderPayload])) { payload ⇒ - mutateOrFailures { - OrderStateUpdater.updateState(auth.model, refNum, payload.state) - } - } ~ - // deprecated in favor of /carts route - (post & path("coupon" / Segment) & pathEnd) { code ⇒ - mutateOrFailures { - CartPromotionUpdater.attachCoupon(auth.model, refNum.some, code) - } - } ~ - // deprecated in favor of /carts route - (delete & path("coupon") & pathEnd) { - mutateOrFailures { - CartPromotionUpdater.detachCoupon(auth.model, refNum.some) - } - } ~ - (post & path("increase-remorse-period") & pathEnd) { - mutateOrFailures { - OrderUpdater.increaseRemorsePeriod(refNum, auth.model) - } - } ~ - // deprecated in favor of /carts route - (post & path("checkout")) { - mutateOrFailures { - Checkout.fromCart(refNum) - } - } ~ - // deprecated in favor of /carts route - (post & path("line-items") & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { - reqItems ⇒ - mutateOrFailures { - LineItemUpdater.updateQuantitiesOnCart(auth.model, refNum, reqItems) - } - } ~ - // deprecated in favor of /carts route - (patch & path("line-items") & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { - reqItems ⇒ - mutateOrFailures { - LineItemUpdater.addQuantitiesOnCart(auth.model, refNum, reqItems) - } - } ~ - // deprecated in favor of /carts route - pathPrefix("payment-methods" / "credit-cards") { - (post & pathEnd & entity(as[CreditCardPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addCreditCard(auth.model, payload.creditCardId, refNum.some) - } - } ~ - // deprecated in favor of /carts route - (delete & pathEnd) { - mutateOrFailures { - CartPaymentUpdater.deleteCreditCard(auth.model, refNum.some) - } - } - } ~ - pathPrefix("payment-methods" / "gift-cards") { - // deprecated in favor of /carts route - (post & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addGiftCard(auth.model, payload, refNum.some) - } - } ~ - // deprecated in favor of /carts route - (patch & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.editGiftCard(auth.model, payload, refNum.some) - } - } ~ - // deprecated in favor of /carts route - (delete & path(GiftCard.giftCardCodeRegex) & pathEnd) { code ⇒ - mutateOrFailures { - CartPaymentUpdater.deleteGiftCard(auth.model, code, refNum.some) - } - } - } ~ - pathPrefix("payment-methods" / "store-credit") { - // deprecated in favor of /carts route - (post & pathEnd & entity(as[StoreCreditPayment])) { payload ⇒ - mutateOrFailures { - CartPaymentUpdater.addStoreCredit(auth.model, payload, refNum.some) - } - } ~ - // deprecated in favor of /carts route - (delete & pathEnd) { - mutateOrFailures { - CartPaymentUpdater.deleteStoreCredit(auth.model, refNum.some) - } - } - } ~ - pathPrefix("shipping-address") { - // deprecated in favor of /carts route - (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ - mutateOrFailures { - CartShippingAddressUpdater.createShippingAddressFromPayload(auth.model, - payload, - Some(refNum)) - } - } ~ - // deprecated in favor of /carts route - (patch & path(IntNumber) & pathEnd) { addressId ⇒ - mutateOrFailures { - CartShippingAddressUpdater.createShippingAddressFromAddressId(auth.model, - addressId, - Some(refNum)) - } - } ~ - // deprecated in favor of /carts route - (patch & pathEnd & entity(as[UpdateAddressPayload])) { payload ⇒ - mutateOrFailures { - CartShippingAddressUpdater.updateShippingAddressFromPayload(auth.model, - payload, - Some(refNum)) - } - } ~ - // deprecated in favor of /carts route - (delete & pathEnd) { - mutateOrFailures { - CartShippingAddressUpdater.removeShippingAddress(auth.model, Some(refNum)) - } - } - } ~ - pathPrefix("shipping-method") { - // deprecated in favor of /carts route - (patch & pathEnd & entity(as[UpdateShippingMethod])) { payload ⇒ - mutateOrFailures { - CartShippingMethodUpdater.updateShippingMethod(auth.model, - payload.shippingMethodId, - Some(refNum)) + } ~ + pathPrefix("orders" / cordRefNumRegex) { refNum ⇒ + (get & pathEnd) { + getOrFailures { + OrderQueries.findOne(refNum) } } ~ - // deprecated in favor of /carts route - (delete & pathEnd) { - mutateOrFailures { - CartShippingMethodUpdater.deleteShippingMethod(auth.model, Some(refNum)) + pathPrefix("line-items") { + (patch & pathEnd & entity(as[Seq[UpdateOrderLineItemsPayload]])) { reqItems ⇒ + mutateOrFailures { + LineItemUpdater.updateOrderLineItems(auth.model, reqItems, refNum) + } + } + } ~ + // deprecated in favor of /orders/line-items + pathPrefix("order-line-items") { + (patch & pathEnd & entity(as[Seq[UpdateOrderLineItemsPayload]])) { reqItems ⇒ + mutateOrFailures { + LineItemUpdater.updateOrderLineItems(auth.model, reqItems, refNum) + } + } + } ~ + (patch & pathEnd & entity(as[UpdateOrderPayload])) { payload ⇒ + mutateOrFailures { + OrderStateUpdater.updateState(auth.model, refNum, payload.state) + } + } ~ + // deprecated in favor of /carts route + (post & path("coupon" / Segment) & pathEnd) { code ⇒ + mutateOrFailures { + CartPromotionUpdater.attachCoupon(auth.model, refNum.some, code) + } + } ~ + // deprecated in favor of /carts route + (delete & path("coupon") & pathEnd) { + mutateOrFailures { + CartPromotionUpdater.detachCoupon(auth.model, refNum.some) + } + } ~ + (post & path("increase-remorse-period") & pathEnd) { + mutateOrFailures { + OrderUpdater.increaseRemorsePeriod(refNum, auth.model) + } + } ~ + // deprecated in favor of /carts route + (post & path("checkout")) { + mutateOrFailures { + Checkout.fromCart(refNum) + } + } ~ + // deprecated in favor of /carts route + (post & path("line-items") & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { reqItems ⇒ + mutateOrFailures { + LineItemUpdater.updateQuantitiesOnCart(auth.model, refNum, reqItems) + } + } ~ + // deprecated in favor of /carts route + (patch & path("line-items") & pathEnd & entity(as[Seq[UpdateLineItemsPayload]])) { reqItems ⇒ + mutateOrFailures { + LineItemUpdater.addQuantitiesOnCart(auth.model, refNum, reqItems) + } + } ~ + // deprecated in favor of /carts route + pathPrefix("payment-methods" / "credit-cards") { + (post & pathEnd & entity(as[CreditCardPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addCreditCard(auth.model, payload.creditCardId, refNum.some) + } + } ~ + // deprecated in favor of /carts route + (delete & pathEnd) { + mutateOrFailures { + CartPaymentUpdater.deleteCreditCard(auth.model, refNum.some) + } + } + } ~ + pathPrefix("payment-methods" / "gift-cards") { + // deprecated in favor of /carts route + (post & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addGiftCard(auth.model, payload, refNum.some) + } + } ~ + // deprecated in favor of /carts route + (patch & pathEnd & entity(as[GiftCardPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.editGiftCard(auth.model, payload, refNum.some) + } + } ~ + // deprecated in favor of /carts route + (delete & path(GiftCard.giftCardCodeRegex) & pathEnd) { code ⇒ + mutateOrFailures { + CartPaymentUpdater.deleteGiftCard(auth.model, code, refNum.some) + } + } + } ~ + pathPrefix("payment-methods" / "store-credit") { + // deprecated in favor of /carts route + (post & pathEnd & entity(as[StoreCreditPayment])) { payload ⇒ + mutateOrFailures { + CartPaymentUpdater.addStoreCredit(auth.model, payload, refNum.some) + } + } ~ + // deprecated in favor of /carts route + (delete & pathEnd) { + mutateOrFailures { + CartPaymentUpdater.deleteStoreCredit(auth.model, refNum.some) + } + } + } ~ + pathPrefix("shipping-address") { + // deprecated in favor of /carts route + (post & pathEnd & entity(as[CreateAddressPayload])) { payload ⇒ + mutateOrFailures { + CartShippingAddressUpdater.createShippingAddressFromPayload(auth.model, + payload, + Some(refNum)) + } + } ~ + // deprecated in favor of /carts route + (patch & path(IntNumber) & pathEnd) { addressId ⇒ + mutateOrFailures { + CartShippingAddressUpdater.createShippingAddressFromAddressId(auth.model, + addressId, + Some(refNum)) + } + } ~ + // deprecated in favor of /carts route + (patch & pathEnd & entity(as[UpdateAddressPayload])) { payload ⇒ + mutateOrFailures { + CartShippingAddressUpdater.updateShippingAddressFromPayload(auth.model, + payload, + Some(refNum)) + } + } ~ + // deprecated in favor of /carts route + (delete & pathEnd) { + mutateOrFailures { + CartShippingAddressUpdater.removeShippingAddress(auth.model, Some(refNum)) + } + } + } ~ + pathPrefix("shipping-method") { + // deprecated in favor of /carts route + (patch & pathEnd & entity(as[UpdateShippingMethod])) { payload ⇒ + mutateOrFailures { + CartShippingMethodUpdater.updateShippingMethod(auth.model, + payload.shippingMethodId, + Some(refNum)) + } + } ~ + // deprecated in favor of /carts route + (delete & pathEnd) { + mutateOrFailures { + CartShippingMethodUpdater.deleteShippingMethod(auth.model, Some(refNum)) + } + } } - } } - } } } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/PluginRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/PluginRoutes.scala index 649cb8a550..fbef28b45f 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/PluginRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/PluginRoutes.scala @@ -12,7 +12,7 @@ import phoenix.utils.http.JsonSupport._ object PluginRoutes { - def routes(implicit ec: EC, db: DB, auth: AU, apis: Apis): Route = { + def routes(implicit ec: EC, db: DB, auth: AU, apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("plugins") { (get & pathEnd) { @@ -20,31 +20,30 @@ object PluginRoutes { listPlugins() } } ~ - pathPrefix("register") { - (post & pathEnd & entity(as[RegisterPluginPayload])) { payload ⇒ - mutateOrFailures { - registerPlugin(payload) - } - } - } ~ - (pathPrefix("settings") & pathPrefix(Segment)) { pluginName ⇒ - (get & pathEnd) { - getOrFailures { - listSettings(pluginName) + pathPrefix("register") { + (post & pathEnd & entity(as[RegisterPluginPayload])) { payload ⇒ + mutateOrFailures { + registerPlugin(payload) + } } } ~ - (get & path("detailed")) { - getOrFailures { - getSettingsWithSchema(pluginName) - } - } ~ - (post & pathEnd & entity(as[UpdateSettingsPayload])) { payload ⇒ - mutateOrFailures { - updateSettings(pluginName, payload) - } + (pathPrefix("settings") & pathPrefix(Segment)) { pluginName ⇒ + (get & pathEnd) { + getOrFailures { + listSettings(pluginName) + } + } ~ + (get & path("detailed")) { + getOrFailures { + getSettingsWithSchema(pluginName) + } + } ~ + (post & pathEnd & entity(as[UpdateSettingsPayload])) { payload ⇒ + mutateOrFailures { + updateSettings(pluginName, payload) + } + } } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/ProductReviewRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/ProductReviewRoutes.scala index 7833669c43..972658dee5 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/ProductReviewRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/ProductReviewRoutes.scala @@ -14,8 +14,7 @@ import phoenix.utils.http.JsonSupport._ object ProductReviewRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User]): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User]): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("review") { pathPrefix(Segment) { contextName ⇒ @@ -25,26 +24,24 @@ object ProductReviewRoutes { ProductReviewManager.getReview(reviewId) } } ~ - (post & entity(as[CreateProductReviewByAdminPayload]) & pathEnd) { payload ⇒ - mutateOrFailures { - ProductReviewManager.createProductReview(payload.userId.getOrElse(auth.account.id), - payload) - } - } ~ - (path(IntNumber) & patch & entity(as[UpdateProductReviewPayload]) & pathEnd) { - (reviewId, payload) ⇒ + (post & entity(as[CreateProductReviewByAdminPayload]) & pathEnd) { payload ⇒ mutateOrFailures { - ProductReviewManager.updateProductReview(reviewId, payload) + ProductReviewManager.createProductReview(payload.userId.getOrElse(auth.account.id), payload) + } + } ~ + (path(IntNumber) & patch & entity(as[UpdateProductReviewPayload]) & pathEnd) { + (reviewId, payload) ⇒ + mutateOrFailures { + ProductReviewManager.updateProductReview(reviewId, payload) + } + } ~ + (delete & path(IntNumber) & pathEnd) { id ⇒ + deleteOrFailures { + ProductReviewManager.archiveByContextAndId(id) } - } ~ - (delete & path(IntNumber) & pathEnd) { id ⇒ - deleteOrFailures { - ProductReviewManager.archiveByContextAndId(id) } - } } } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/ProductRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/ProductRoutes.scala index 7e7bb9f192..3f8e16cd88 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/ProductRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/ProductRoutes.scala @@ -20,55 +20,49 @@ import phoenix.utils.http.JsonSupport._ object ProductRoutes { - private def productRoutes(productRef: ProductReference)(implicit ec: EC, - db: DB, - oc: OC, - ac: AC, - apis: Apis, - auth: AU): Route = { + private def productRoutes( + productRef: ProductReference)(implicit ec: EC, db: DB, oc: OC, ac: AC, apis: Apis, auth: AU): Route = (get & pathEnd) { getOrFailures { ProductManager.getProduct(productRef, checkActive = false) } } ~ - (patch & pathEnd & entity(as[UpdateProductPayload])) { payload ⇒ - mutateOrFailures { - ProductManager.updateProduct(productRef, payload) - } - } ~ - (delete & pathEnd) { - mutateOrFailures { - ProductManager.archiveByContextAndId(productRef) - } - } ~ - (pathPrefix("taxons") & get & pathEnd) { - getOrFailures { - TaxonomyManager.getAssignedTaxons(productRef) - } - } ~ - pathPrefix("albums") { - (get & pathEnd) { - getOrFailures { - ImageManager.getAlbumsForProduct(productRef) + (patch & pathEnd & entity(as[UpdateProductPayload])) { payload ⇒ + mutateOrFailures { + ProductManager.updateProduct(productRef, payload) } } ~ - (post & pathEnd & entity(as[AlbumPayload])) { payload ⇒ + (delete & pathEnd) { mutateOrFailures { - ImageManager.createAlbumForProduct(auth.model, productRef, payload) + ProductManager.archiveByContextAndId(productRef) } } ~ - pathPrefix("position") { - (post & pathEnd & entity(as[UpdateAlbumPositionPayload])) { payload ⇒ - mutateOrFailures { - ImageManager.updateProductAlbumPosition(payload.albumId, productRef, payload.position) - } + (pathPrefix("taxons") & get & pathEnd) { + getOrFailures { + TaxonomyManager.getAssignedTaxons(productRef) } + } ~ + pathPrefix("albums") { + (get & pathEnd) { + getOrFailures { + ImageManager.getAlbumsForProduct(productRef) + } + } ~ + (post & pathEnd & entity(as[AlbumPayload])) { payload ⇒ + mutateOrFailures { + ImageManager.createAlbumForProduct(auth.model, productRef, payload) + } + } ~ + pathPrefix("position") { + (post & pathEnd & entity(as[UpdateAlbumPositionPayload])) { payload ⇒ + mutateOrFailures { + ImageManager.updateProductAlbumPosition(payload.albumId, productRef, payload.position) + } + } + } } - } - } - - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("products") { pathPrefix(Segment) { contextName ⇒ @@ -78,38 +72,37 @@ object ProductRoutes { ProductManager.createProduct(auth.model, payload) } } ~ - pathPrefix(ProductRef) { productId ⇒ - productRoutes(productId) - } + pathPrefix(ProductRef) { productId ⇒ + productRoutes(productId) + } } } ~ - pathPrefix("contexts" / Segment) { name ⇒ - (get & pathEnd) { - getOrFailures { - ObjectManager.getContextByName(name) - } + pathPrefix("contexts" / Segment) { name ⇒ + (get & pathEnd) { + getOrFailures { + ObjectManager.getContextByName(name) + } + } ~ + (patch & pathEnd & entity(as[UpdateObjectContext])) { payload ⇒ + mutateOrFailures { + ObjectManager.updateContextByName(name, payload) + } + } } ~ - (patch & pathEnd & entity(as[UpdateObjectContext])) { payload ⇒ - mutateOrFailures { - ObjectManager.updateContextByName(name, payload) - } - } - } ~ - pathPrefix("contexts") { - (post & pathEnd & entity(as[CreateObjectContext])) { payload ⇒ - mutateOrFailures { - ObjectManager.createContext(payload) + pathPrefix("contexts") { + (post & pathEnd & entity(as[CreateObjectContext])) { payload ⇒ + mutateOrFailures { + ObjectManager.createContext(payload) + } } - } - } ~ - pathPrefix(IntNumber / "contexts") { formId ⇒ - (get & pathEnd) { - getOrFailures { - ProductManager.getContextsForProduct(formId) + } ~ + pathPrefix(IntNumber / "contexts") { formId ⇒ + (get & pathEnd) { + getOrFailures { + ProductManager.getContextsForProduct(formId) + } } } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/PromotionRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/PromotionRoutes.scala index b575da0c1f..3a93e0aecc 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/PromotionRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/PromotionRoutes.scala @@ -13,7 +13,7 @@ import phoenix.utils.http.Http._ import phoenix.utils.http.JsonSupport._ object PromotionRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("promotions") { pathPrefix(Segment) { (context) ⇒ @@ -22,25 +22,24 @@ object PromotionRoutes { PromotionManager.create(payload, context, Some(auth.model)) } } ~ - pathPrefix(IntNumber) { id ⇒ - (get & pathEnd) { - getOrFailures { - PromotionManager.getIlluminated(id, context) - } - } ~ - (patch & pathEnd & entity(as[UpdatePromotion])) { payload ⇒ - mutateOrFailures { - PromotionManager.update(id, payload, context, Some(auth.model)) - } - } ~ - (delete & pathEnd) { - mutateOrFailures { - PromotionManager.archiveByContextAndId(context, id) - } + pathPrefix(IntNumber) { id ⇒ + (get & pathEnd) { + getOrFailures { + PromotionManager.getIlluminated(id, context) + } + } ~ + (patch & pathEnd & entity(as[UpdatePromotion])) { payload ⇒ + mutateOrFailures { + PromotionManager.update(id, payload, context, Some(auth.model)) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + PromotionManager.archiveByContextAndId(context, id) + } + } } - } } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/ReturnRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/ReturnRoutes.scala index cc2c8beb85..666781e333 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/ReturnRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/ReturnRoutes.scala @@ -28,100 +28,99 @@ object ReturnRoutes { ReturnService.createByAdmin(auth.model, payload) } } ~ - (get & pathEnd) { - getOrFailures { - ReturnService.list - } - } ~ - pathPrefix("customer") { - (get & path(IntNumber) & pathEnd) { customerId ⇒ - getOrFailures { - ReturnService.getByCustomer(customerId) - } - } - } ~ - pathPrefix("order" / Cord.cordRefNumRegex) { refNum ⇒ (get & pathEnd) { getOrFailures { - ReturnService.getByOrder(refNum) - } - } - } ~ - pathPrefix("reasons") { - (get & pathEnd) { - getOrFailures { - ReturnReasonsManager.reasonsList - } - } ~ - (post & pathEnd & entity(as[ReturnReasonPayload])) { payload ⇒ - mutateOrFailures { - ReturnReasonsManager.addReason(payload) + ReturnService.list } } ~ - (delete & path(IntNumber) & pathEnd) { id ⇒ - deleteOrFailures { - ReturnReasonsManager.deleteReason(id) - } - } - } - } ~ - pathPrefix("returns" / Return.returnRefNumRegex) { refNum ⇒ - (get & pathEnd) { - getOrFailures { - ReturnService.getByRefNum(refNum) - } - } ~ - (patch & pathEnd & entity(as[ReturnUpdateStatePayload])) { payload ⇒ - mutateOrFailures { - ReturnService.updateStateByCsr(refNum, payload) - } - } ~ - (post & path("message") & pathEnd & entity(as[ReturnMessageToCustomerPayload])) { - payload ⇒ - mutateOrFailures { - ReturnService.updateMessageToCustomer(refNum, payload) - } - } ~ - pathPrefix("line-items") { - (post & path("skus") & entity(as[List[ReturnSkuLineItemPayload]])) { payload ⇒ - mutateOrFailures { - ReturnLineItemManager.updateSkuLineItems(refNum, payload) + pathPrefix("customer") { + (get & path(IntNumber) & pathEnd) { customerId ⇒ + getOrFailures { + ReturnService.getByCustomer(customerId) + } } } ~ - (post & pathEnd & entity(as[ReturnLineItemPayload])) { payload ⇒ - mutateOrFailures { - ReturnLineItemManager.addLineItem(refNum, payload) + pathPrefix("order" / Cord.cordRefNumRegex) { refNum ⇒ + (get & pathEnd) { + getOrFailures { + ReturnService.getByOrder(refNum) + } } } ~ - (delete & path(IntNumber) & pathEnd) { lineItemId ⇒ - deleteOrFailures { - ReturnLineItemManager.deleteLineItem(refNum, lineItemId) - } + pathPrefix("reasons") { + (get & pathEnd) { + getOrFailures { + ReturnReasonsManager.reasonsList + } + } ~ + (post & pathEnd & entity(as[ReturnReasonPayload])) { payload ⇒ + mutateOrFailures { + ReturnReasonsManager.addReason(payload) + } + } ~ + (delete & path(IntNumber) & pathEnd) { id ⇒ + deleteOrFailures { + ReturnReasonsManager.deleteReason(id) + } + } } - } ~ - pathPrefix("payment-methods") { - (post & pathEnd & entity(as[ReturnPaymentsPayload])) { payload ⇒ - mutateOrFailures { - ReturnPaymentManager.updatePayments(refNum, payload.payments, overwrite = true) + } ~ + pathPrefix("returns" / Return.returnRefNumRegex) { refNum ⇒ + (get & pathEnd) { + getOrFailures { + ReturnService.getByRefNum(refNum) } } ~ - (post & path(PaymentMethodMatcher) & pathEnd & entity(as[ReturnPaymentPayload])) { - case (paymentMethod, payload) ⇒ + (patch & pathEnd & entity(as[ReturnUpdateStatePayload])) { payload ⇒ mutateOrFailures { - ReturnPaymentManager.updatePayments( - refNum, - Map(paymentMethod → payload.amount), - overwrite = false - ) + ReturnService.updateStateByCsr(refNum, payload) } - } ~ - (delete & path(PaymentMethodMatcher) & pathEnd) { paymentMethod ⇒ - deleteOrFailures { - ReturnPaymentManager.deletePayment(refNum, paymentMethod) + } ~ + (post & path("message") & pathEnd & entity(as[ReturnMessageToCustomerPayload])) { payload ⇒ + mutateOrFailures { + ReturnService.updateMessageToCustomer(refNum, payload) + } + } ~ + pathPrefix("line-items") { + (post & path("skus") & entity(as[List[ReturnSkuLineItemPayload]])) { payload ⇒ + mutateOrFailures { + ReturnLineItemManager.updateSkuLineItems(refNum, payload) + } + } ~ + (post & pathEnd & entity(as[ReturnLineItemPayload])) { payload ⇒ + mutateOrFailures { + ReturnLineItemManager.addLineItem(refNum, payload) + } + } ~ + (delete & path(IntNumber) & pathEnd) { lineItemId ⇒ + deleteOrFailures { + ReturnLineItemManager.deleteLineItem(refNum, lineItemId) + } + } + } ~ + pathPrefix("payment-methods") { + (post & pathEnd & entity(as[ReturnPaymentsPayload])) { payload ⇒ + mutateOrFailures { + ReturnPaymentManager.updatePayments(refNum, payload.payments, overwrite = true) + } + } ~ + (post & path(PaymentMethodMatcher) & pathEnd & entity(as[ReturnPaymentPayload])) { + case (paymentMethod, payload) ⇒ + mutateOrFailures { + ReturnPaymentManager.updatePayments( + refNum, + Map(paymentMethod → payload.amount), + overwrite = false + ) + } + } ~ + (delete & path(PaymentMethodMatcher) & pathEnd) { paymentMethod ⇒ + deleteOrFailures { + ReturnPaymentManager.deletePayment(refNum, paymentMethod) + } + } } - } } - } } } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/ShippingMethodRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/ShippingMethodRoutes.scala index b4db9f8ffd..8e5deb266c 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/ShippingMethodRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/ShippingMethodRoutes.scala @@ -12,7 +12,7 @@ import phoenix.utils.apis.Apis import phoenix.utils.http.CustomDirectives._ object ShippingMethodRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("shipping-methods") { (post & path(IntNumber / "default") & pathEnd) { shippingMethodId ⇒ @@ -20,31 +20,30 @@ object ShippingMethodRoutes { ShippingManager.setDefault(shippingMethodId = shippingMethodId) } } ~ - pathPrefix("default") { + pathPrefix("default") { + (get & pathEnd) { + getOrFailures { + ShippingManager.getDefault + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + ShippingManager.removeDefault() + } + } + } ~ (get & pathEnd) { getOrFailures { - ShippingManager.getDefault + ShippingManager.getActive } } ~ - (delete & pathEnd) { - deleteOrFailures { - ShippingManager.removeDefault() - } - } - } ~ - (get & pathEnd) { - getOrFailures { - ShippingManager.getActive - } - } ~ - path(cordRefNumRegex) { refNum ⇒ - (get & pathEnd) { - getOrFailures { - ShippingManager.getShippingMethodsForCart(refNum) + path(cordRefNumRegex) { refNum ⇒ + (get & pathEnd) { + getOrFailures { + ShippingManager.getShippingMethodsForCart(refNum) + } } } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/SkuRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/SkuRoutes.scala index 9a73544a17..e503264afa 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/SkuRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/SkuRoutes.scala @@ -16,8 +16,7 @@ import phoenix.utils.http.JsonSupport._ object SkuRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("skus") { pathPrefix(Segment) { contextName ⇒ @@ -27,38 +26,37 @@ object SkuRoutes { SkuManager.createSku(auth.model, payload) } } ~ - pathPrefix(Segment) { code ⇒ - (get & pathEnd) { - getOrFailures { - SkuManager.getSku(code) - } - } ~ - (patch & pathEnd & entity(as[SkuPayload])) { payload ⇒ - mutateOrFailures { - SkuManager.updateSku(auth.model, code, payload) - } - } ~ - (delete & pathEnd) { - mutateOrFailures { - SkuManager.archiveByCode(code) - } - } ~ - pathPrefix("albums") { + pathPrefix(Segment) { code ⇒ (get & pathEnd) { getOrFailures { - ImageManager.getAlbumsForSku(code) + SkuManager.getSku(code) } } ~ - (post & pathEnd & entity(as[AlbumPayload])) { payload ⇒ - mutateOrFailures { - ImageManager.createAlbumForSku(auth.model, code, payload) + (patch & pathEnd & entity(as[SkuPayload])) { payload ⇒ + mutateOrFailures { + SkuManager.updateSku(auth.model, code, payload) + } + } ~ + (delete & pathEnd) { + mutateOrFailures { + SkuManager.archiveByCode(code) + } + } ~ + pathPrefix("albums") { + (get & pathEnd) { + getOrFailures { + ImageManager.getAlbumsForSku(code) + } + } ~ + (post & pathEnd & entity(as[AlbumPayload])) { payload ⇒ + mutateOrFailures { + ImageManager.createAlbumForSku(auth.model, code, payload) + } + } } - } } - } } } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/StoreAdminRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/StoreAdminRoutes.scala index 666b1dd2b1..0449eb11cd 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/StoreAdminRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/StoreAdminRoutes.scala @@ -14,7 +14,7 @@ import phoenix.utils.http.JsonSupport._ object StoreAdminRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("store-admins") { (post & pathEnd & entity(as[CreateStoreAdminPayload])) { payload ⇒ @@ -22,31 +22,30 @@ object StoreAdminRoutes { StoreAdminManager.create(payload, Some(auth.model)) } } ~ - pathPrefix(IntNumber) { saId ⇒ - (get & pathEnd) { - getOrFailures { - StoreAdminManager.getById(saId) - } - } ~ - (patch & pathEnd & entity(as[UpdateStoreAdminPayload])) { payload ⇒ - mutateOrFailures { - StoreAdminManager.update(saId, payload, auth.model) - } - } ~ - (delete & pathEnd) { - deleteOrFailures { - StoreAdminManager.delete(saId, auth.model) - } - } ~ - pathPrefix("state") { - (patch & pathEnd & entity(as[StateChangeStoreAdminPayload])) { payload ⇒ - mutateOrFailures { - StoreAdminManager.changeState(saId, payload, auth.model) + pathPrefix(IntNumber) { saId ⇒ + (get & pathEnd) { + getOrFailures { + StoreAdminManager.getById(saId) + } + } ~ + (patch & pathEnd & entity(as[UpdateStoreAdminPayload])) { payload ⇒ + mutateOrFailures { + StoreAdminManager.update(saId, payload, auth.model) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + StoreAdminManager.delete(saId, auth.model) + } + } ~ + pathPrefix("state") { + (patch & pathEnd & entity(as[StateChangeStoreAdminPayload])) { payload ⇒ + mutateOrFailures { + StoreAdminManager.changeState(saId, payload, auth.model) + } + } } - } } - } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/StoreCreditRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/StoreCreditRoutes.scala index b23a304f52..cce8029006 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/StoreCreditRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/StoreCreditRoutes.scala @@ -17,7 +17,7 @@ object StoreCreditRoutes { db: DB, ac: AC, apis: Apis, - auth: AuthData[User]): Route = { + auth: AuthData[User]): Route = pathPrefix("store-credits") { (patch & pathEnd & entity(as[StoreCreditBulkUpdateStateByCsr])) { payload ⇒ mutateOrFailures { @@ -25,17 +25,16 @@ object StoreCreditRoutes { } } } ~ - pathPrefix("store-credits" / IntNumber) { storeCreditId ⇒ - (get & pathEnd) { - getOrFailures { - StoreCreditService.getById(storeCreditId) - } - } ~ - (patch & pathEnd & entity(as[StoreCreditUpdateStateByCsr])) { payload ⇒ - mutateOrFailures { - StoreCreditService.updateStateByCsr(storeCreditId, payload, auth.model) - } + pathPrefix("store-credits" / IntNumber) { storeCreditId ⇒ + (get & pathEnd) { + getOrFailures { + StoreCreditService.getById(storeCreditId) + } + } ~ + (patch & pathEnd & entity(as[StoreCreditUpdateStateByCsr])) { payload ⇒ + mutateOrFailures { + StoreCreditService.updateStateByCsr(storeCreditId, payload, auth.model) + } + } } - } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/TaxonomyRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/TaxonomyRoutes.scala index 94b88f5f52..e4cae9c223 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/TaxonomyRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/TaxonomyRoutes.scala @@ -15,8 +15,7 @@ import phoenix.utils.http.JsonSupport._ object TaxonomyRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("taxonomies") { pathPrefix(Segment) { contextName ⇒ @@ -24,65 +23,64 @@ object TaxonomyRoutes { (post & pathEnd & entity(as[CreateTaxonomyPayload])) { payload ⇒ mutateOrFailures(TaxonomyManager.createTaxonomy(payload)) } ~ - pathPrefix(IntNumber) { taxonomyFormId ⇒ - (get & pathEnd) { - getOrFailures { - TaxonomyManager.getTaxonomy(taxonomyFormId) - } - } ~ - (patch & pathEnd & entity(as[UpdateTaxonomyPayload])) { (payload) ⇒ - mutateOrFailures { - TaxonomyManager.updateTaxonomy(taxonomyFormId, payload) - } - } ~ - (delete & pathEnd) { - deleteOrFailures { - TaxonomyManager.archiveByContextAndId(taxonomyFormId) - } - } ~ - pathPrefix("taxons") { - (post & pathEnd & entity(as[CreateTaxonPayload])) { payload ⇒ - mutateOrFailures { - TaxonomyManager.createTaxon(taxonomyFormId, payload) + pathPrefix(IntNumber) { taxonomyFormId ⇒ + (get & pathEnd) { + getOrFailures { + TaxonomyManager.getTaxonomy(taxonomyFormId) + } + } ~ + (patch & pathEnd & entity(as[UpdateTaxonomyPayload])) { (payload) ⇒ + mutateOrFailures { + TaxonomyManager.updateTaxonomy(taxonomyFormId, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + TaxonomyManager.archiveByContextAndId(taxonomyFormId) + } + } ~ + pathPrefix("taxons") { + (post & pathEnd & entity(as[CreateTaxonPayload])) { payload ⇒ + mutateOrFailures { + TaxonomyManager.createTaxon(taxonomyFormId, payload) + } + } } - } } - } } } } ~ - pathPrefix("taxons") { + pathPrefix("taxons") { - pathPrefix(Segment) { contextName ⇒ - adminObjectContext(contextName) { implicit context ⇒ - pathPrefix(IntNumber) { taxonFormId ⇒ - (get & pathEnd) { - getOrFailures { - TaxonomyManager.getTaxon(taxonFormId) - } - } ~ - (patch & pathEnd & entity(as[UpdateTaxonPayload])) { payload ⇒ - mutateOrFailures { - TaxonomyManager.updateTaxon(taxonFormId, payload) - } - } ~ - (delete & pathEnd) { - deleteOrFailures { - TaxonomyManager.archiveTaxonByContextAndId(taxonFormId) - } - } ~ - pathPrefix("product" / IntNumber) { productFormId ⇒ - (patch & pathEnd) { - mutateOrFailures(TaxonomyManager.assignProduct(taxonFormId, productFormId)) + pathPrefix(Segment) { contextName ⇒ + adminObjectContext(contextName) { implicit context ⇒ + pathPrefix(IntNumber) { taxonFormId ⇒ + (get & pathEnd) { + getOrFailures { + TaxonomyManager.getTaxon(taxonFormId) + } } ~ - (delete & pathEnd) { - mutateOrFailures(TaxonomyManager.unassignProduct(taxonFormId, productFormId)) - } + (patch & pathEnd & entity(as[UpdateTaxonPayload])) { payload ⇒ + mutateOrFailures { + TaxonomyManager.updateTaxon(taxonFormId, payload) + } + } ~ + (delete & pathEnd) { + deleteOrFailures { + TaxonomyManager.archiveTaxonByContextAndId(taxonFormId) + } + } ~ + pathPrefix("product" / IntNumber) { productFormId ⇒ + (patch & pathEnd) { + mutateOrFailures(TaxonomyManager.assignProduct(taxonFormId, productFormId)) + } ~ + (delete & pathEnd) { + mutateOrFailures(TaxonomyManager.unassignProduct(taxonFormId, productFormId)) + } + } } } } } - } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/admin/VariantRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/admin/VariantRoutes.scala index 3b2bb63397..8e0cb56f78 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/admin/VariantRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/admin/VariantRoutes.scala @@ -14,8 +14,7 @@ import phoenix.utils.http.JsonSupport._ object VariantRoutes { - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("variants") { pathPrefix(Segment) { context ⇒ @@ -24,27 +23,26 @@ object VariantRoutes { VariantManager.createVariant(context, payload) } } ~ - pathPrefix(IntNumber) { variantId ⇒ - (get & pathEnd) { - getOrFailures { - VariantManager.getVariant(context, variantId) - } - } ~ - (patch & pathEnd & entity(as[VariantPayload])) { payload ⇒ - mutateOrFailures { - VariantManager.updateVariant(context, variantId, payload) - } - } ~ - pathPrefix("values") { - (post & pathEnd & entity(as[VariantValuePayload])) { payload ⇒ - mutateOrFailures { - VariantManager.createVariantValue(context, variantId, payload) + pathPrefix(IntNumber) { variantId ⇒ + (get & pathEnd) { + getOrFailures { + VariantManager.getVariant(context, variantId) + } + } ~ + (patch & pathEnd & entity(as[VariantPayload])) { payload ⇒ + mutateOrFailures { + VariantManager.updateVariant(context, variantId, payload) + } + } ~ + pathPrefix("values") { + (post & pathEnd & entity(as[VariantValuePayload])) { payload ⇒ + mutateOrFailures { + VariantManager.createVariantValue(context, variantId, payload) + } + } } - } } - } } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/service/CustomerGroupRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/service/CustomerGroupRoutes.scala index 87b7fff497..2f14da46e9 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/service/CustomerGroupRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/service/CustomerGroupRoutes.scala @@ -14,7 +14,7 @@ import phoenix.utils.http.Http._ object CustomerGroupRoutes { - def routes(implicit ec: EC, db: DB, apis: Apis, auth: AuthData[User]): Route = { + def routes(implicit ec: EC, db: DB, apis: Apis, auth: AuthData[User]): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("customer-groups") { (get & pathEnd) { @@ -23,15 +23,14 @@ object CustomerGroupRoutes { } } } ~ - pathPrefix("customer-groups" / IntNumber) { groupId ⇒ - pathPrefix("customers") { - (post & pathEnd & entity(as[CustomerGroupMemberServiceSyncPayload])) { payload ⇒ - doOrFailures( + pathPrefix("customer-groups" / IntNumber) { groupId ⇒ + pathPrefix("customers") { + (post & pathEnd & entity(as[CustomerGroupMemberServiceSyncPayload])) { payload ⇒ + doOrFailures( GroupMemberManager.sync(groupId, payload) - ) + ) + } } } - } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/service/MigrationRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/service/MigrationRoutes.scala index 1f3f85acc6..5ce8e8fe4b 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/service/MigrationRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/service/MigrationRoutes.scala @@ -14,8 +14,7 @@ import phoenix.utils.http.JsonSupport._ object MigrationRoutes { def routes(customerCreateContext: AccountCreateContext, - defaultScope: LTree)(implicit ec: EC, db: DB, apis: Apis): Route = { - + defaultScope: LTree)(implicit ec: EC, db: DB, apis: Apis): Route = activityContext(defaultScope) { implicit ac ⇒ pathPrefix("migration") { pathPrefix("customers") { @@ -27,5 +26,4 @@ object MigrationRoutes { } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/routes/service/PaymentRoutes.scala b/phoenix-scala/phoenix/app/phoenix/routes/service/PaymentRoutes.scala index a6cf3354c1..ba456866d4 100644 --- a/phoenix-scala/phoenix/app/phoenix/routes/service/PaymentRoutes.scala +++ b/phoenix-scala/phoenix/app/phoenix/routes/service/PaymentRoutes.scala @@ -15,8 +15,7 @@ import phoenix.utils.http.JsonSupport._ object PaymentRoutes { //TODO: Instead of store auth.model, add service accounts and require service JWT tokens. - def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = { - + def routes(implicit ec: EC, db: DB, auth: AuthData[User], apis: Apis): Route = activityContext(auth) { implicit ac ⇒ pathPrefix("capture") { (post & pathEnd & entity(as[CapturePayloads.Capture])) { payload ⇒ @@ -26,5 +25,4 @@ object PaymentRoutes { } } } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/server/Main.scala b/phoenix-scala/phoenix/app/phoenix/server/Main.scala index b88120dbd2..bb6effdbf3 100644 --- a/phoenix-scala/phoenix/app/phoenix/server/Main.scala +++ b/phoenix-scala/phoenix/app/phoenix/server/Main.scala @@ -19,7 +19,7 @@ import org.json4s._ import org.json4s.jackson._ import phoenix.models.account.{AccountAccessMethod, Scope, Scopes} import phoenix.services.Authenticator -import phoenix.services.Authenticator.{UserAuthenticator, requireAdminAuth} +import phoenix.services.Authenticator.{requireAdminAuth, UserAuthenticator} import phoenix.services.account.AccountCreateContext import phoenix.services.actors._ import phoenix.utils.FoxConfig.config @@ -92,12 +92,11 @@ object Setup extends LazyLogging { } } -class Service( - systemOverride: Option[ActorSystem] = None, - dbOverride: Option[Database] = None, - apisOverride: Option[Apis] = None, - esOverride: Option[ElasticsearchApi] = None, - addRoutes: immutable.Seq[Route] = immutable.Seq.empty)(implicit val env: Environment) { +class Service(systemOverride: Option[ActorSystem] = None, + dbOverride: Option[Database] = None, + apisOverride: Option[Apis] = None, + esOverride: Option[ElasticsearchApi] = None, + addRoutes: immutable.Seq[Route] = immutable.Seq.empty)(implicit val env: Environment) { import FoxConfig.config import phoenix.utils.JsonFormatters._ @@ -132,40 +131,40 @@ class Service( val defaultRoutes: Route = { pathPrefix("v1") { phoenix.routes.AuthRoutes.routes(scope.ltree) ~ - phoenix.routes.Public.routes(customerCreateContext, scope.ltree) ~ - phoenix.routes.Customer.routes ~ - requireAdminAuth(userAuth) { implicit auth ⇒ - phoenix.routes.admin.AdminRoutes.routes ~ - phoenix.routes.admin.NotificationRoutes.routes ~ - phoenix.routes.admin.AssignmentsRoutes.routes ~ - phoenix.routes.admin.OrderRoutes.routes ~ - phoenix.routes.admin.AmazonOrderRoutes.routes ~ - phoenix.routes.admin.CartRoutes.routes ~ - phoenix.routes.admin.CustomerRoutes.routes ~ - phoenix.routes.admin.CustomerGroupsRoutes.routes ~ - phoenix.routes.admin.GiftCardRoutes.routes ~ - phoenix.routes.admin.ReturnRoutes.routes ~ - phoenix.routes.admin.ProductRoutes.routes ~ - phoenix.routes.admin.SkuRoutes.routes ~ - phoenix.routes.admin.VariantRoutes.routes ~ - phoenix.routes.admin.DiscountRoutes.routes ~ - phoenix.routes.admin.PromotionRoutes.routes ~ - phoenix.routes.admin.ImageRoutes.routes ~ - phoenix.routes.admin.CouponRoutes.routes ~ - phoenix.routes.admin.CategoryRoutes.routes ~ - phoenix.routes.admin.GenericTreeRoutes.routes ~ - phoenix.routes.admin.StoreAdminRoutes.routes ~ - phoenix.routes.admin.ObjectRoutes.routes ~ - phoenix.routes.admin.PluginRoutes.routes ~ - phoenix.routes.admin.TaxonomyRoutes.routes ~ - phoenix.routes.admin.ProductReviewRoutes.routes ~ - phoenix.routes.admin.ShippingMethodRoutes.routes ~ - phoenix.routes.service.MigrationRoutes.routes(customerCreateContext, scope.ltree) ~ - pathPrefix("service") { - phoenix.routes.service.PaymentRoutes.routes ~ //Migrate this to auth with service tokens once we have them - phoenix.routes.service.CustomerGroupRoutes.routes + phoenix.routes.Public.routes(customerCreateContext, scope.ltree) ~ + phoenix.routes.Customer.routes ~ + requireAdminAuth(userAuth) { implicit auth ⇒ + phoenix.routes.admin.AdminRoutes.routes ~ + phoenix.routes.admin.NotificationRoutes.routes ~ + phoenix.routes.admin.AssignmentsRoutes.routes ~ + phoenix.routes.admin.OrderRoutes.routes ~ + phoenix.routes.admin.AmazonOrderRoutes.routes ~ + phoenix.routes.admin.CartRoutes.routes ~ + phoenix.routes.admin.CustomerRoutes.routes ~ + phoenix.routes.admin.CustomerGroupsRoutes.routes ~ + phoenix.routes.admin.GiftCardRoutes.routes ~ + phoenix.routes.admin.ReturnRoutes.routes ~ + phoenix.routes.admin.ProductRoutes.routes ~ + phoenix.routes.admin.SkuRoutes.routes ~ + phoenix.routes.admin.VariantRoutes.routes ~ + phoenix.routes.admin.DiscountRoutes.routes ~ + phoenix.routes.admin.PromotionRoutes.routes ~ + phoenix.routes.admin.ImageRoutes.routes ~ + phoenix.routes.admin.CouponRoutes.routes ~ + phoenix.routes.admin.CategoryRoutes.routes ~ + phoenix.routes.admin.GenericTreeRoutes.routes ~ + phoenix.routes.admin.StoreAdminRoutes.routes ~ + phoenix.routes.admin.ObjectRoutes.routes ~ + phoenix.routes.admin.PluginRoutes.routes ~ + phoenix.routes.admin.TaxonomyRoutes.routes ~ + phoenix.routes.admin.ProductReviewRoutes.routes ~ + phoenix.routes.admin.ShippingMethodRoutes.routes ~ + phoenix.routes.service.MigrationRoutes.routes(customerCreateContext, scope.ltree) ~ + pathPrefix("service") { + phoenix.routes.service.PaymentRoutes.routes ~ //Migrate this to auth with service tokens once we have them + phoenix.routes.service.CustomerGroupRoutes.routes + } } - } } } diff --git a/phoenix-scala/phoenix/app/phoenix/services/AddressManager.scala b/phoenix-scala/phoenix/app/phoenix/services/AddressManager.scala index 49e2df7b68..7939114ef1 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/AddressManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/AddressManager.scala @@ -14,8 +14,7 @@ import slick.jdbc.PostgresProfile.api._ object AddressManager { - def findAllByAccountId(accountId: Int)(implicit ec: EC, - db: DB): DbResultT[Seq[AddressResponse]] = { + def findAllByAccountId(accountId: Int)(implicit ec: EC, db: DB): DbResultT[Seq[AddressResponse]] = { val query = Addresses.findAllActiveByAccountIdWithRegions(accountId) for (records ← * <~ query.result) yield AddressResponse.buildMulti(records) } @@ -67,9 +66,8 @@ object AddressManager { _ ← * <~ LogActivity().addressDeleted(originator, customer, response) } yield {} - def setDefaultShippingAddress(addressId: Int, accountId: Int)( - implicit ec: EC, - db: DB): DbResultT[AddressResponse] = + def setDefaultShippingAddress(addressId: Int, accountId: Int)(implicit ec: EC, + db: DB): DbResultT[AddressResponse] = for { customer ← * <~ Users.mustFindByAccountId(accountId) _ ← * <~ removeDefaultShippingAddress(accountId) diff --git a/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala b/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala index ce9e1e20e7..043c97dd98 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala @@ -11,11 +11,8 @@ import core.failures._ object AmazonOrderManager { - def createAmazonOrder(payload: CreateAmazonOrderPayload)( - implicit ec: EC, - db: DB, - au: AU): DbResultT[AmazonOrderResponse] = { - + def createAmazonOrder( + payload: CreateAmazonOrderPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrderResponse] = for { user ← * <~ Users .findByEmail(payload.customerEmail) @@ -25,7 +22,6 @@ object AmazonOrderManager { .findOneByAmazonOrderId(payload.amazonOrderId) .findOrCreate(inner) } yield AmazonOrderResponse.build(amazonOrder) - } private def createInner( payload: CreateAmazonOrderPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrder] = @@ -36,13 +32,11 @@ object AmazonOrderManager { amazonOrder ← * <~ AmazonOrders.create(AmazonOrder.build(payload, user.accountId)) } yield amazonOrder - def updateAmazonOrder(amazonOrderId: String, payload: UpdateAmazonOrderPayload)( - implicit ec: EC, - db: DB, - au: AU): DbResultT[AmazonOrderResponse] = + def updateAmazonOrder( + amazonOrderId: String, + payload: UpdateAmazonOrderPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrderResponse] = for { amazonOrder ← * <~ AmazonOrders.mustFindOneOr(amazonOrderId) - up ← * <~ AmazonOrders.update(amazonOrder, - amazonOrder.copy(orderStatus = payload.orderStatus)) + up ← * <~ AmazonOrders.update(amazonOrder, amazonOrder.copy(orderStatus = payload.orderStatus)) } yield AmazonOrderResponse.build(up) } diff --git a/phoenix-scala/phoenix/app/phoenix/services/Authenticators.scala b/phoenix-scala/phoenix/app/phoenix/services/Authenticators.scala index db0d8e508f..bf5372d8a7 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/Authenticators.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/Authenticators.scala @@ -31,9 +31,7 @@ import scala.concurrent.Future object FailureChallenge { def apply(realm: String, failures: Failures, scheme: String = "xBasic"): HttpChallenge = - HttpChallenge(scheme = scheme, - realm = realm, - params = Map("error" → failures.flatten.mkString)) + HttpChallenge(scheme = scheme, realm = realm, params = Map("error" → failures.flatten.mkString)) } object AuthRejections { @@ -51,15 +49,15 @@ object AuthRejections { object JwtCookie { def apply(authPayload: AuthPayload): HttpCookie = HttpCookie( - name = "JWT", - value = authPayload.jwt, - secure = config.auth.cookie.secure, - httpOnly = true, - expires = config.auth.cookie.ttl.map { ttl ⇒ - DateTime.now + ttl * 1000 - }, - path = Some("/"), - domain = config.auth.cookie.domain + name = "JWT", + value = authPayload.jwt, + secure = config.auth.cookie.secure, + httpOnly = true, + expires = config.auth.cookie.ttl.map { ttl ⇒ + DateTime.now + ttl * 1000 + }, + path = Some("/"), + domain = config.auth.cookie.domain ) } @@ -72,16 +70,14 @@ object Authenticator { trait UserAuthenticator { def readCredentials(): Directive1[Option[String]] def checkAuthUser(credentials: Option[String]): Future[AuthenticationResult[AuthData[User]]] - def checkAuthCustomer( - credentials: Option[String]): Future[AuthenticationResult[AuthData[User]]] + def checkAuthCustomer(credentials: Option[String]): Future[AuthenticationResult[AuthData[User]]] } class JwtAuthenticator(guestCreateContext: AccountCreateContext)(implicit ec: EC, db: DB) extends UserAuthenticator { - def readCredentials(): Directive1[Option[String]] = { + def readCredentials(): Directive1[Option[String]] = readCookieOrHeader(headerName = "JWT") - } def toUserToken(token: String): Either[Failures, Token] = Token.fromString(token, Identity.User) @@ -89,16 +85,14 @@ object Authenticator { def checkAuthUser(credentials: Option[String]): Future[AuthenticationResult[AuthData[User]]] = jwtAuthUser("user")(credentials) - def checkAuthCustomer( - credentials: Option[String]): Future[AuthenticationResult[AuthData[User]]] = + def checkAuthCustomer(credentials: Option[String]): Future[AuthenticationResult[AuthData[User]]] = credentials match { case None ⇒ jwtAuthGuest("customer") case _ ⇒ jwtAuthUser("customer")(credentials) } - def jwtAuthUser(realm: String)(credentials: Option[String])( - implicit ec: EC, - db: DB): Future[AuthenticationResult[AuthData[User]]] = + def jwtAuthUser(realm: String)( + credentials: Option[String])(implicit ec: EC, db: DB): Future[AuthenticationResult[AuthData[User]]] = (for { jwtCredentials ← * <~ credentials.toEither(AuthFailed("missing credentials").single) token ← * <~ toUserToken(jwtCredentials) @@ -106,46 +100,37 @@ object Authenticator { .findByIdAndRatchet(token.id, token.ratchet) .mustFindOr(AuthFailed("account not found")) user ← * <~ Users.mustFindByAccountId(token.id) - } yield - AuthData[User](token, user, account)).runDBIO.runEmptyA.value.map { // TODO: rethink discarding warnings here @michalrus - case Right(data) ⇒ AuthenticationResult.success(data) - case Left(f) ⇒ AuthenticationResult.failWithChallenge(FailureChallenge(realm, f)) - } + } yield AuthData[User](token, user, account)).runDBIO.runEmptyA.value + .map { // TODO: rethink discarding warnings here @michalrus + case Right(data) ⇒ AuthenticationResult.success(data) + case Left(f) ⇒ AuthenticationResult.failWithChallenge(FailureChallenge(realm, f)) + } - def jwtAuthGuest(realm: String)(implicit ec: EC, - db: DB): Future[AuthenticationResult[AuthData[User]]] = { + def jwtAuthGuest(realm: String)(implicit ec: EC, db: DB): Future[AuthenticationResult[AuthData[User]]] = (for { guest ← * <~ CustomerManager.createGuest(guestCreateContext) (user, custData) = guest account ← * <~ Accounts.mustFindById404(user.accountId) claims ← * <~ AccountManager.getClaims(user.accountId, guestCreateContext.scopeId) } yield - AuthData[User]( - UserToken.fromUserAccount(user, account, claims), - user, - account, - isGuest = true)).runDBIO.runEmptyA.value.map { // TODO: rethink discarding warnings here @michalrus - case Right(data) ⇒ AuthenticationResult.success(data) - case Left(f) ⇒ AuthenticationResult.failWithChallenge(FailureChallenge(realm, f)) - } - } + AuthData[User](UserToken.fromUserAccount(user, account, claims), user, account, isGuest = true)).runDBIO.runEmptyA.value + .map { // TODO: rethink discarding warnings here @michalrus + case Right(data) ⇒ AuthenticationResult.success(data) + case Left(f) ⇒ AuthenticationResult.failWithChallenge(FailureChallenge(realm, f)) + } } - def forUser(guestCreateContext: AccountCreateContext)(implicit ec: EC, - db: DB): JwtAuthenticator = + def forUser(guestCreateContext: AccountCreateContext)(implicit ec: EC, db: DB): JwtAuthenticator = new JwtAuthenticator(guestCreateContext) - private def readCookie(): Directive1[Option[String]] = { + private def readCookie(): Directive1[Option[String]] = optionalCookie("JWT").map(_.map(_.value)) - } - private def readHeader(name: String): Directive1[Option[String]] = { + private def readHeader(name: String): Directive1[Option[String]] = optionalHeaderValueByName(name) - } - private def readCookieOrHeader(headerName: String): Directive1[Option[String]] = { + private def readCookieOrHeader(headerName: String): Directive1[Option[String]] = readCookie().flatMap(_.fold(readHeader(headerName))(v ⇒ provide(Some(v)))) - } //TODO //This will be replaced with claims specific require functions for admins inside @@ -153,7 +138,7 @@ object Authenticator { //"admin" within the token. This is to bring back feature parity with the old code. val ADMIN_ROLE = "admin" - def requireAdminAuth(auth: UserAuthenticator): AuthenticationDirective[AuthData[User]] = { + def requireAdminAuth(auth: UserAuthenticator): AuthenticationDirective[AuthData[User]] = (for { optCreds ← auth.readCredentials() result ← onSuccess(auth.checkAuthUser(optCreds)) @@ -162,14 +147,13 @@ object Authenticator { if (authData.token.hasRole(ADMIN_ROLE)) provide(authData) else AuthRejections.credentialsRejected[AuthData[User]]( - FailureChallenge("admin", AuthFailed("Does not have admin role").single)) + FailureChallenge("admin", AuthFailed("Does not have admin role").single)) } case (Left(challenge), Some(creds)) ⇒ AuthRejections.credentialsRejected[AuthData[User]](challenge) case (Left(challenge), _) ⇒ AuthRejections.credentialsMissing[AuthData[User]](challenge) } - } //TODO //same as above, should have check for claims. The services should @@ -182,14 +166,13 @@ object Authenticator { case (Right(authData), _) ⇒ if (!authData.isGuest) provide(authData) else { - Console.out.println(s"AUTH ${authData}") + Console.out.println(s"AUTH $authData") AuthPayload( - token = UserToken.fromUserAccount( - authData.model, - authData.account, - Account.ClaimSet(scope = authData.token.scope, - roles = authData.token.roles, - claims = authData.token.claims))) match { + token = UserToken.fromUserAccount(authData.model, + authData.account, + Account.ClaimSet(scope = authData.token.scope, + roles = authData.token.roles, + claims = authData.token.claims))) match { case Right(authPayload) ⇒ val header = respondWithHeader(RawHeader("JWT", authPayload.jwt)) val cookie = setCookie(JwtCookie(authPayload)) @@ -205,29 +188,23 @@ object Authenticator { AuthRejections.credentialsMissing[AuthData[User]](challenge) } - def authTokenBaseResponse(token: Token, - response: AuthPayload ⇒ StandardRoute): Either[Failures, Route] = { + def authTokenBaseResponse(token: Token, response: AuthPayload ⇒ StandardRoute): Either[Failures, Route] = for { authPayload ← AuthPayload(token) } yield respondWithHeader(RawHeader("JWT", authPayload.jwt)).&(setCookie(JwtCookie(authPayload))) { response(authPayload) } - } - def authTokenLoginResponse(token: Token): Either[Failures, Route] = { + def authTokenLoginResponse(token: Token): Either[Failures, Route] = authTokenBaseResponse(token, { payload ⇒ - complete( - HttpResponse( - entity = HttpEntity(ContentTypes.`application/json`, payload.claims.toJson))) + complete(HttpResponse(entity = HttpEntity(ContentTypes.`application/json`, payload.claims.toJson))) }) - } - def oauthTokenLoginResponse(redirectUri: Uri)(token: Token): Either[Failures, Route] = { + def oauthTokenLoginResponse(redirectUri: Uri)(token: Token): Either[Failures, Route] = authTokenBaseResponse(token, { _ ⇒ redirect(redirectUri, StatusCodes.Found) }) - } def authenticate(payload: LoginPayload)(implicit ec: EC, db: DB): Result[Route] = { val tokenResult = for { @@ -266,8 +243,7 @@ object Authenticator { else Either.right(Unit) - private def checkState(adminData: AdminData): Either[Failures, AdminData] = { + private def checkState(adminData: AdminData): Either[Failures, AdminData] = if (adminData.canLogin) Either.right(adminData) else Either.left(AuthFailed(reason = "Store admin is Inactive or Archived").single) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/services/Capture.scala b/phoenix-scala/phoenix/app/phoenix/services/Capture.scala index 4f4222d554..f08333f28b 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/Capture.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/Capture.scala @@ -35,9 +35,8 @@ object Capture { def capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, apis: Apis, - ac: AC): DbResultT[CaptureResponse] = { + ac: AC): DbResultT[CaptureResponse] = Capture(payload).capture - } } case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, apis: Apis, ac: AC) { @@ -65,8 +64,7 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap //get total line item price. linePrices ← * <~ getPrices(lineItemData) adjustments ← * <~ CartLineItemAdjustments.findByCordRef(payload.order).result - lineItemAdjustments = adjustments.filter( - _.adjustmentType == CartLineItemAdjustment.LineItemAdjustment) + lineItemAdjustments = adjustments.filter(_.adjustmentType == CartLineItemAdjustment.LineItemAdjustment) adjustedPrices ← * <~ adjust(linePrices, lineItemAdjustments) totalLineItemPrice ← * <~ aggregatePrices(adjustedPrices) @@ -83,11 +81,9 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap .forCordRef(payload.order) .mustFindOneOr(ShippingMethodNotFoundInOrder(payload.order)) shippingAdjustments = adjustments.filter(a ⇒ - a.adjustmentType == CartLineItemAdjustment.ShippingAdjustment) + a.adjustmentType == CartLineItemAdjustment.ShippingAdjustment) - adjustedShippingCost ← * <~ adjustShippingCost(shippingMethod, - shippingAdjustments, - payload.shipping) + adjustedShippingCost ← * <~ adjustShippingCost(shippingMethod, shippingAdjustments, payload.shipping) //we compute the total by adding the three price components together. The //actual total should be less than or equal to the original grandTotal. @@ -104,22 +100,21 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap gcPayments ← * <~ OrderPayments.findAllGiftCardsByCordRef(payload.order).result scPayments ← * <~ OrderPayments.findAllStoreCreditsByCordRef(payload.order).result - externalCaptureTotal ← * <~ determineExternalCapture(total, - gcPayments, - scPayments, - order.currency) + externalCaptureTotal ← * <~ determineExternalCapture(total, gcPayments, scPayments, order.currency) internalCaptureTotal = total - externalCaptureTotal _ ← * <~ internalCapture(internalCaptureTotal, order, customer, gcPayments, scPayments) _ ← * <~ doOrMeh(externalCaptureTotal > 0, externalCapture(externalCaptureTotal, order)) - resp = CaptureResponse(order = order.refNum, - captured = total, - external = externalCaptureTotal, - internal = internalCaptureTotal, - lineItems = totalLineItemPrice, - taxes = order.taxesTotal, - shipping = adjustedShippingCost, - currency = order.currency) + resp = CaptureResponse( + order = order.refNum, + captured = total, + external = externalCaptureTotal, + internal = internalCaptureTotal, + lineItems = totalLineItemPrice, + taxes = order.taxesTotal, + shipping = adjustedShippingCost, + currency = order.currency + ) _ ← * <~ LogActivity().orderCaptured(order, resp) //return Capture table tuple id? @@ -133,10 +128,10 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap for { scTotal ← * <~ PaymentHelper.paymentTransaction( - scPayments, - total, - StoreCredits.captureOrderPayment, - (a: StoreCreditAdjustment) ⇒ a.getAmount.abs + scPayments, + total, + StoreCredits.captureOrderPayment, + (a: StoreCreditAdjustment) ⇒ a.getAmount.abs ) gcTotal ← * <~ PaymentHelper.paymentTransaction(gcPayments, @@ -148,8 +143,7 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap gcCodes = gcPayments.map { case (_, gc) ⇒ gc.code }.distinct _ ← * <~ doOrMeh(scTotal > 0, LogActivity().scFundsCaptured(customer, order, scIds, scTotal)) - _ ← * <~ doOrMeh(gcTotal > 0, - LogActivity().gcFundsCaptured(customer, order, gcCodes, gcTotal)) + _ ← * <~ doOrMeh(gcTotal > 0, LogActivity().gcFundsCaptured(customer, order, gcCodes, gcTotal)) } yield {} private def externalCapture(total: Long, order: Order): DbResultT[Unit] = { @@ -172,16 +166,12 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap } yield () } - private def captureFromStripe(total: Long, - charge: ExternalCharge[_], - order: Order): DbResultT[Unit] = { - + private def captureFromStripe(total: Long, charge: ExternalCharge[_], order: Order): DbResultT[Unit] = for { _ ← * <~ failIfNot(charge.state == Auth, CaptureFailures.ChargeNotInAuth(charge)) _ ← * <~ apis.stripe.captureCharge(charge.stripeChargeId, total) _ ← * <~ charge.updateModelState(FullCapture) } yield () - } private def determineExternalCapture(total: Long, gcPayments: Seq[(OrderPayment, GiftCard)], @@ -262,8 +252,7 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap } - private def adjustPrice(line: LineItemPrice, - adjMap: Map[String, CartLineItemAdjustment]): LineItemPrice = + private def adjustPrice(line: LineItemPrice, adjMap: Map[String, CartLineItemAdjustment]): LineItemPrice = adjMap.get(line.referenceNumber) match { case Some(adj) ⇒ { require(line.price >= 0) @@ -286,8 +275,7 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap private def getPrice(item: OrderLineItemProductData): DbResultT[LineItemPrice] = FormShadowGet.price(item.skuForm, item.skuShadow) match { case Some((price, currency)) ⇒ - DbResultT.pure( - LineItemPrice(item.lineItem.referenceNumber, item.sku.code, price, currency)) + DbResultT.pure(LineItemPrice(item.lineItem.referenceNumber, item.sku.code, price, currency)) case None ⇒ DbResultT.failure(CaptureFailures.SkuMissingPrice(item.sku.code)) } @@ -306,14 +294,12 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap //Future validation goes here. } yield Unit - private def paymentStateMustBeInAuth(order: Order, - paymentState: CordPaymentState.State): DbResultT[Unit] = + private def paymentStateMustBeInAuth(order: Order, paymentState: CordPaymentState.State): DbResultT[Unit] = if (paymentState != CordPaymentState.Auth) DbResultT.failure(CaptureFailures.OrderMustBeInAuthState(order.refNum)) else DbResultT.pure(Unit) - private def mustHavePositiveShippingCost( - shippingCost: CapturePayloads.ShippingCost): DbResultT[Unit] = + private def mustHavePositiveShippingCost(shippingCost: CapturePayloads.ShippingCost): DbResultT[Unit] = if (shippingCost.total < 0) DbResultT.failure(CaptureFailures.ShippingCostNegative(shippingCost.total)) else DbResultT.pure(Unit) diff --git a/phoenix-scala/phoenix/app/phoenix/services/CartValidator.scala b/phoenix-scala/phoenix/app/phoenix/services/CartValidator.scala index 21b53d31a9..0edacb61bb 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/CartValidator.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/CartValidator.scala @@ -16,15 +16,12 @@ import slick.jdbc.PostgresProfile.api._ import core.utils.Money._ trait CartValidation { - def validate(isCheckout: Boolean = false, - fatalWarnings: Boolean = false): DbResultT[CartValidatorResponse] + def validate(isCheckout: Boolean = false, fatalWarnings: Boolean = false): DbResultT[CartValidatorResponse] } // warnings would be turned into `errors` during checkout but if we're still in cart mode // then we'll display to end-user as warnings/alerts since they are not "done" with their cart -case class CartValidatorResponse( - alerts: Option[Failures] = None, - warnings: Option[Failures] = None) {} // TODO: use real warnings from StateT. What’s with not used alerts? @michalrus +case class CartValidatorResponse(alerts: Option[Failures] = None, warnings: Option[Failures] = None) {} // TODO: use real warnings from StateT. What’s with not used alerts? @michalrus case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends CartValidation { @@ -60,8 +57,7 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C // TODO: check if SKUs are not archived/deactivated @michalrus // TODO: check VariantValue, Variant? — this feels as if duplicating `LineItemUpdater.mustFindProductIdForSku` a bit. @michalrus // TODO: check if their Products are not archived/deactivated @michalrus - private def hasActiveLineItems( - response: CartValidatorResponse): DbResultT[CartValidatorResponse] = { + private def hasActiveLineItems(response: CartValidatorResponse): DbResultT[CartValidatorResponse] = for { skus ← * <~ CartLineItems .byCordRef(cart.referenceNumber) @@ -73,7 +69,6 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C illuminatedSkus = fullSkus.map(IlluminatedSku.illuminate(ctx, _)) // TODO: use .mustBeActive instead and proper StateT warnings @michalrus } yield warnings(response, illuminatedSkus.filterNot(_.isActive).map(_.inactiveError)) - } //todo: do we need alway have sku or at least sku or gc private def hasItems(response: CartValidatorResponse, @@ -83,13 +78,12 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C response ← * <~ (if (numItems == 0) warning(response, EmptyCart(cart.refNum)) else response) // FIXME: use FoxyT @michalrus } yield response - private def hasShipAddress(response: CartValidatorResponse): DBIO[CartValidatorResponse] = { + private def hasShipAddress(response: CartValidatorResponse): DBIO[CartValidatorResponse] = OrderShippingAddresses.findByOrderRef(cart.refNum).one.map { shipAddress ⇒ shipAddress.fold(warning(response, NoShipAddress(cart.refNum))) { _ ⇒ response } } - } private def validShipMethod(response: CartValidatorResponse)( implicit db: DB): DbResultT[CartValidatorResponse] = @@ -99,22 +93,22 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C sm ← osm.shippingMethod } yield (osm, sm)).one validatedResponse ← * <~ (shipping match { - case Some((osm, sm)) ⇒ - ShippingManager - .evaluateShippingMethodForCart(sm, cart) - .map(_ ⇒ response) - .recover { - case _ ⇒ warning(response, InvalidShippingMethod(cart.refNum)) - } // FIXME validator warning and actual failure differ - case None ⇒ - DbResultT(warning(response, NoShipMethod(cart.refNum))) - }) + case Some((osm, sm)) ⇒ + ShippingManager + .evaluateShippingMethodForCart(sm, cart) + .map(_ ⇒ response) + .recover { + case _ ⇒ warning(response, InvalidShippingMethod(cart.refNum)) + } // FIXME validator warning and actual failure differ + case None ⇒ + DbResultT(warning(response, NoShipMethod(cart.refNum))) + }) } yield validatedResponse private def sufficientPayments(response: CartValidatorResponse, isCheckout: Boolean): DBIO[CartValidatorResponse] = { - def cartFunds(payments: Seq[OrderPayment]): DBIO[Option[Long]] = { + def cartFunds(payments: Seq[OrderPayment]): DBIO[Option[Long]] = if (isCheckout) { val paymentIds = payments.map(_.id) @@ -146,10 +140,8 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C availableStoreCredits.unionAll(availableGiftCards).sum.result } - } - def availableFunds(grandTotal: Long, - payments: Seq[OrderPayment]): DBIO[CartValidatorResponse] = { + def availableFunds(grandTotal: Long, payments: Seq[OrderPayment]): DBIO[CartValidatorResponse] = // we'll find out if the `ExternalFunds` doesn't auth at checkout but we presume sufficient funds if we have a // `ExternalFunds` regardless of GC/SC funds availability if (payments.exists(_.isExternalFunds)) { @@ -165,7 +157,6 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C } else { lift(warning(response, InsufficientFunds(cart.refNum))) } - } if (cart.grandTotal > 0 || cart.subTotal > 0) { OrderPayments @@ -181,8 +172,7 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C warnings(response, Seq(failure)) // FIXME: wat @michalrus - private def warnings(response: CartValidatorResponse, - failures: Seq[Failure]): CartValidatorResponse = + private def warnings(response: CartValidatorResponse, failures: Seq[Failure]): CartValidatorResponse = response.copy(warnings = response.warnings.fold(Failures(failures: _*))(current ⇒ - Failures(current.toList ++ failures: _*))) + Failures(current.toList ++ failures: _*))) } diff --git a/phoenix-scala/phoenix/app/phoenix/services/Checkout.scala b/phoenix-scala/phoenix/app/phoenix/services/Checkout.scala index c199f08472..f88c3258df 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/Checkout.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/Checkout.scala @@ -54,8 +54,7 @@ object PaymentHelper { getAdjustmentAmount: (Adjustment) ⇒ Long)(implicit ec: EC, db: DB, apis: Apis, - ac: AC): DbResultT[Long] = { - + ac: AC): DbResultT[Long] = if (payments.isEmpty) { DbResultT.pure(0L) } else { @@ -77,7 +76,6 @@ object PaymentHelper { total = adjustments.map(getAdjustmentAmount).sum.ensuring(_ <= maxPaymentAmount) } yield total } - } } object Checkout { @@ -103,8 +101,8 @@ object Checkout { result ← * <~ Carts .findByAccountId(customer.accountId) .one - .findOrCreateExtended(Carts.create( - Cart(accountId = customer.accountId, scope = LTree(au.token.scope)))) + .findOrCreateExtended( + Carts.create(Cart(accountId = customer.accountId, scope = LTree(au.token.scope)))) (cart, _) = result order ← * <~ Checkout(cart, CartValidator(cart)).checkout } yield order @@ -120,13 +118,12 @@ object Checkout { order ← * <~ oneClickCheckout(customer, au.model.some, payload) } yield order - def applePayCheckout(customer: User, stripeToken: CreateApplePayPayment)( - implicit ec: EC, - db: DB, - apis: Apis, - ac: AC, - ctx: OC, - au: AU): DbResultT[OrderResponse] = + def applePayCheckout(customer: User, stripeToken: CreateApplePayPayment)(implicit ec: EC, + db: DB, + apis: Apis, + ac: AC, + ctx: OC, + au: AU): DbResultT[OrderResponse] = for { _ ← * <~ CartPaymentUpdater.addApplePayPayment(customer, stripeToken) cart ← * <~ Carts @@ -247,10 +244,9 @@ case class Checkout( liSkus ← * <~ CartLineItems.byCordRef(cart.refNum).countSkus inventoryTrackedSkus ← * <~ filterInventoryTrackingSkus(liSkus) skusToHold ← * <~ inventoryTrackedSkus.map(sku ⇒ SkuInventoryHold(sku.code, sku.qty)) - _ ← * <~ doOrMeh( - skusToHold.nonEmpty, - DbResultT.fromResult( - apis.middlewarehouse.hold(OrderInventoryHold(cart.referenceNumber, skusToHold)))) + _ ← * <~ doOrMeh(skusToHold.nonEmpty, + DbResultT.fromResult( + apis.middlewarehouse.hold(OrderInventoryHold(cart.referenceNumber, skusToHold)))) mutating = externalCalls.middleWarehouseSuccess = skusToHold.nonEmpty } yield {} @@ -285,13 +281,11 @@ case class Checkout( _ ← * <~ maybeCodeId.fold(DbResultT.unit)(couponMustBeApplicable) } yield {} - private def promotionMustBeActive(orderPromotion: OrderPromotion)( - implicit ctx: OC): DbResultT[Unit] = + private def promotionMustBeActive(orderPromotion: OrderPromotion)(implicit ctx: OC): DbResultT[Unit] = for { promotion ← * <~ Promotions .filterByContextAndShadowId(ctx.id, orderPromotion.promotionShadowId) - .mustFindOneOr( - PromotionNotFoundForContext(orderPromotion.promotionShadowId, ctx.name)) + .mustFindOneOr(PromotionNotFoundForContext(orderPromotion.promotionShadowId, ctx.name)) promoForm ← * <~ ObjectForms.mustFindById404(promotion.formId) promoShadow ← * <~ ObjectShadows.mustFindById404(promotion.shadowId) promoObject = IlluminatedPromotion.illuminate(ctx, promotion, promoForm, promoShadow) @@ -324,10 +318,10 @@ case class Checkout( scPayments ← * <~ OrderPayments.findAllStoreCreditsByCordRef(cart.refNum).result scTotal ← * <~ PaymentHelper.paymentTransaction( - scPayments, - cart.grandTotal, - StoreCredits.authOrderPayment, - (a: StoreCreditAdjustment) ⇒ a.getAmount.abs + scPayments, + cart.grandTotal, + StoreCredits.authOrderPayment, + (a: StoreCreditAdjustment) ⇒ a.getAmount.abs ) gcPayments ← * <~ OrderPayments.findAllGiftCardsByCordRef(cart.refNum).result @@ -339,16 +333,13 @@ case class Checkout( scIds = scPayments.map { case (_, sc) ⇒ sc.id }.distinct gcCodes = gcPayments.map { case (_, gc) ⇒ gc.code }.distinct - _ ← * <~ doOrMeh(scTotal > 0, - LogActivity().scFundsAuthorized(customer, cart, scIds, scTotal)) - _ ← * <~ doOrMeh(gcTotal > 0, - LogActivity().gcFundsAuthorized(customer, cart, gcCodes, gcTotal)) + _ ← * <~ doOrMeh(scTotal > 0, LogActivity().scFundsAuthorized(customer, cart, scIds, scTotal)) + _ ← * <~ doOrMeh(gcTotal > 0, LogActivity().gcFundsAuthorized(customer, cart, gcCodes, gcTotal)) grandTotal = cart.grandTotal internalPayments = gcTotal + scTotal - _ ← * <~ doOrMeh( - grandTotal > internalPayments, // run external payments only if we have to pay more - doExternalPayment(grandTotal - internalPayments)) + _ ← * <~ doOrMeh(grandTotal > internalPayments, // run external payments only if we have to pay more + doExternalPayment(grandTotal - internalPayments)) mutatingResult = externalCalls.authPaymentsSuccess = true // fixme is this flag used anywhere? @aafa } yield {} @@ -360,25 +351,21 @@ case class Checkout( orderPayments ← * <~ OrderPayments.findAllExternalPayments(cart.refNum).result _ ← * <~ failIf(orderPayments.isEmpty, NoExternalPaymentsIsProvided) - _ ← * <~ failIf(orderPayments.groupBy(_.paymentMethodType).size > 1, - OnlyOneExternalPaymentIsAllowed) + _ ← * <~ failIf(orderPayments.groupBy(_.paymentMethodType).size > 1, OnlyOneExternalPaymentIsAllowed) // authorize first payment we've got _ ← * <~ authOneExternalPayment(authAmount, orderPayments.head) } yield () } - private def authOneExternalPayment(authAmount: Long, - orderPayment: OrderPayment): DbResultT[Unit] = { + private def authOneExternalPayment(authAmount: Long, orderPayment: OrderPayment): DbResultT[Unit] = orderPayment.paymentMethodType match { case PaymentMethod.ApplePay ⇒ authApplePay(authAmount, orderPayment) case PaymentMethod.CreditCard ⇒ authCreditCard(authAmount, orderPayment) case _ ⇒ DbResultT.unit } - } - - private def authCreditCard(authAmount: Long, orderPayment: OrderPayment): DbResultT[Unit] = { + private def authCreditCard(authAmount: Long, orderPayment: OrderPayment): DbResultT[Unit] = for { card ← * <~ CreditCards .filter(_.id === orderPayment.paymentMethodId) @@ -393,10 +380,8 @@ case class Checkout( _ ← * <~ CreditCardCharges.create(ourCharge) _ ← * <~ LogActivity().creditCardAuth(cart, ourCharge) } yield () - } - - private def authApplePay(authAmount: Long, orderPayment: OrderPayment): DbResultT[Unit] = { + private def authApplePay(authAmount: Long, orderPayment: OrderPayment): DbResultT[Unit] = for { applePay ← * <~ ApplePayments .filter(_.id === orderPayment.paymentMethodId) @@ -410,8 +395,6 @@ case class Checkout( _ ← * <~ LogActivity().applePayAuth(applePay, ourCharge) } yield () - } - //TODO: Replace with the real deal once we figure out how to do it. private def fraudScore(order: Order): DbResultT[Order] = for { diff --git a/phoenix-scala/phoenix/app/phoenix/services/CordQueries.scala b/phoenix-scala/phoenix/app/phoenix/services/CordQueries.scala index 81db66fd5a..c939cb1072 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/CordQueries.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/CordQueries.scala @@ -20,7 +20,7 @@ trait CordQueries { payStates ← DBIO.sequence(payments.map(getPaymentState)).map(_.flatten) } yield CordQueries.foldPaymentStates(payStates, payments.size) - private def getPaymentState(payment: OrderPayment)(implicit ec: EC): DBIO[Option[State]] = { + private def getPaymentState(payment: OrderPayment)(implicit ec: EC): DBIO[Option[State]] = payment.paymentMethodType match { case PaymentMethod.CreditCard ⇒ CreditCardCharges @@ -39,7 +39,6 @@ trait CordQueries { .one .map(_.map(fromExternalState)) } - } } object CordQueries { diff --git a/phoenix-scala/phoenix/app/phoenix/services/CreditCardManager.scala b/phoenix-scala/phoenix/app/phoenix/services/CreditCardManager.scala index c3b49b5f36..e66d60d071 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/CreditCardManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/CreditCardManager.scala @@ -35,7 +35,7 @@ object CreditCardManager { def createCardFromToken( accountId: Int, payload: CreateCreditCardFromTokenPayload, - admin: Option[User] = None)(implicit ec: EC, db: DB, apis: Apis, ac: AC): DbResultT[Root] = { + admin: Option[User] = None)(implicit ec: EC, db: DB, apis: Apis, ac: AC): DbResultT[Root] = for { _ ← * <~ Regions.mustFindById400(payload.billingAddress.regionId) customer ← * <~ Users.mustFindByAccountId(accountId) @@ -52,15 +52,14 @@ object CreditCardManager { address = address) (stripeCustomer, stripeCard) = stripes cc ← * <~ CreditCards.create( - CreditCard.buildFromToken(accountId = accountId, - customerToken = stripeCustomer.getId, - payload = payload, - address = address, - cardToken = stripeCard.getId)) + CreditCard.buildFromToken(accountId = accountId, + customerToken = stripeCustomer.getId, + payload = payload, + address = address, + cardToken = stripeCard.getId)) _ ← * <~ LogActivity().ccCreated(customer, cc, admin) response ← * <~ CreditCardsResponse.buildFromCreditCard(cc) } yield response - } @deprecated(message = "Use `createCardFromToken` instead", "Until we are PCI compliant") def createCardFromSource( @@ -68,10 +67,7 @@ object CreditCardManager { payload: CreateCreditCardFromSourcePayload, admin: Option[User] = None)(implicit ec: EC, db: DB, apis: Apis, ac: AC): DbResultT[Root] = { - def createCard(customer: User, - sCustomer: StripeCustomer, - sCard: StripeCard, - address: Address) = + def createCard(customer: User, sCustomer: StripeCustomer, sCard: StripeCard, address: Address) = for { _ ← * <~ doOrMeh(address.isNew, Addresses.create(address.copy(accountId = accountId))) cc = CreditCard.buildFromSource(accountId, sCustomer, sCard, payload, address) @@ -84,10 +80,8 @@ object CreditCardManager { for { stripeId ← * <~ CreditCards.filter(_.accountId === accountId).map(_.gatewayCustomerId).one shippingAddress ← * <~ getOptionalShippingAddress(payload.addressId, payload.isShipping) - address ← * <~ getAddressFromPayload(payload.addressId, - payload.address, - shippingAddress, - accountId).mustFindOr(CreditCardMustHaveAddress) + address ← * <~ getAddressFromPayload(payload.addressId, payload.address, shippingAddress, accountId) + .mustFindOr(CreditCardMustHaveAddress) _ ← * <~ validateOptionalAddressOwnership(Some(address), accountId) } yield (stripeId, address) @@ -114,10 +108,10 @@ object CreditCardManager { def removeDefaultCreditCard(accountId: Int)(implicit ec: EC, db: DB): DbResultT[Unit] = CreditCards.findDefaultByAccountId(accountId).map(_.isDefault).update(false).dbresult.void - def deleteCreditCard( - accountId: Int, - ccId: Int, - admin: Option[User] = None)(implicit ec: EC, db: DB, apis: Apis, ac: AC): DbResultT[Unit] = + def deleteCreditCard(accountId: Int, ccId: Int, admin: Option[User] = None)(implicit ec: EC, + db: DB, + apis: Apis, + ac: AC): DbResultT[Unit] = for { customer ← * <~ Users.mustFindByAccountId(accountId) cc ← * <~ CreditCards.mustFindByIdAndAccountId(ccId, accountId) @@ -134,10 +128,10 @@ object CreditCardManager { def update(customer: User, cc: CreditCard) = { val updated = cc.copy( - parentId = Some(cc.id), - holderName = payload.holderName.getOrElse(cc.holderName), - expYear = payload.expYear.getOrElse(cc.expYear), - expMonth = payload.expMonth.getOrElse(cc.expMonth) + parentId = Some(cc.id), + holderName = payload.holderName.getOrElse(cc.holderName), + expYear = payload.expYear.getOrElse(cc.expYear), + expMonth = payload.expMonth.getOrElse(cc.expMonth) ) for { _ ← * <~ apis.stripe.editCard(updated) @@ -179,11 +173,8 @@ object CreditCardManager { .filter(_.accountId === accountId) .mustFindOneOr(NotFoundFailure404(CreditCard, id)) shippingAddress ← * <~ getOptionalShippingAddress(payload.addressId, payload.isShipping) - address ← * <~ getAddressFromPayload(payload.addressId, - payload.address, - shippingAddress, - accountId) - _ ← * <~ validateOptionalAddressOwnership(address, accountId) + address ← * <~ getAddressFromPayload(payload.addressId, payload.address, shippingAddress, accountId) + _ ← * <~ validateOptionalAddressOwnership(address, accountId) } yield address.fold(creditCard)(creditCard.copyFromAddress) for { @@ -201,8 +192,7 @@ object CreditCardManager { region ← cc.region } yield (cc, region)).result.map(buildResponses).run() - def getByIdAndCustomer(creditCardId: Int, customer: User)(implicit ec: EC, - db: DB): DbResultT[Root] = + def getByIdAndCustomer(creditCardId: Int, customer: User)(implicit ec: EC, db: DB): DbResultT[Root] = for { cc ← * <~ CreditCards .findByIdAndAccountId(creditCardId, customer.accountId) @@ -211,18 +201,16 @@ object CreditCardManager { } yield buildResponse(cc, region) private def validateOptionalAddressOwnership(address: Option[Address], - accountId: Int): Either[Failures, Unit] = { + accountId: Int): Either[Failures, Unit] = address match { case Some(a) ⇒ a.mustBelongToAccount(accountId).map(_ ⇒ Unit) case _ ⇒ Either.right(Unit) } - } private def getAddressFromPayload(id: Option[Int], payload: Option[CreateAddressPayload], shippingAddress: Option[OrderShippingAddress], - accountId: Int): DBIO[Option[Address]] = { - + accountId: Int): DBIO[Option[Address]] = (shippingAddress, id, payload) match { case (Some(osa), _, _) ⇒ DBIO.successful(Address.fromOrderShippingAddress(osa).some) @@ -236,7 +224,6 @@ object CreditCardManager { case _ ⇒ DBIO.successful(None) } - } private def getOptionalShippingAddress(id: Option[Int], isShipping: Boolean): DBIO[Option[OrderShippingAddress]] = diff --git a/phoenix-scala/phoenix/app/phoenix/services/CustomerCreditConverter.scala b/phoenix-scala/phoenix/app/phoenix/services/CustomerCreditConverter.scala index 63f7abd744..cd51c82a40 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/CustomerCreditConverter.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/CustomerCreditConverter.scala @@ -15,10 +15,9 @@ import core.db._ object CustomerCreditConverter { - def toStoreCredit(giftCardCode: String, accountId: Int, admin: User)( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[StoreCreditResponse.Root] = + def toStoreCredit(giftCardCode: String, + accountId: Int, + admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[StoreCreditResponse.Root] = for { giftCard ← * <~ GiftCards.mustFindByCode(giftCardCode) _ ← * <~ failIf(!giftCard.isActive, GiftCardConvertFailure(giftCard)) @@ -34,25 +33,25 @@ object CustomerCreditConverter { _ ← * <~ GiftCards.redeemToStoreCredit(giftCard, admin) // Finally, convert to Store Credit - conversion ← * <~ StoreCreditFromGiftCards.create( - StoreCreditFromGiftCard(giftCardId = giftCard.id)) + conversion ← * <~ StoreCreditFromGiftCards.create(StoreCreditFromGiftCard(giftCardId = giftCard.id)) storeCredit ← * <~ StoreCredits.create( - StoreCredit(accountId = accountId, - originId = conversion.id, - scope = giftCard.scope, - originType = StoreCredit.GiftCardTransfer, - currency = giftCard.currency, - originalBalance = giftCard.currentBalance, - currentBalance = giftCard.currentBalance)) + StoreCredit( + accountId = accountId, + originId = conversion.id, + scope = giftCard.scope, + originType = StoreCredit.GiftCardTransfer, + currency = giftCard.currency, + originalBalance = giftCard.currentBalance, + currentBalance = giftCard.currentBalance + )) // Activity _ ← * <~ LogActivity().gcConvertedToSc(admin, giftCard, storeCredit) } yield StoreCreditResponse.build(storeCredit) - def toGiftCard( - storeCreditId: Int, - accountId: Int, - admin: User)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[GiftCardResponse.Root] = + def toGiftCard(storeCreditId: Int, + accountId: Int, + admin: User)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[GiftCardResponse.Root] = for { credit ← * <~ StoreCredits.mustFindById404(storeCreditId) _ ← * <~ failIf(!credit.isActive, StoreCreditConvertFailure(credit)) @@ -68,15 +67,16 @@ object CustomerCreditConverter { .update(StoreCredit.FullyRedeemed) adjustment ← * <~ StoreCredits.redeemToGiftCard(credit, admin) // Convert to Gift Card - conversion ← * <~ GiftCardFromStoreCredits.create( - GiftCardFromStoreCredit(storeCreditId = credit.id)) + conversion ← * <~ GiftCardFromStoreCredits.create(GiftCardFromStoreCredit(storeCreditId = credit.id)) giftCard ← * <~ GiftCards.create( - GiftCard(scope = Scope.current, - originId = conversion.id, - originType = GiftCard.FromStoreCredit, - currency = credit.currency, - originalBalance = credit.currentBalance, - currentBalance = credit.currentBalance)) + GiftCard( + scope = Scope.current, + originId = conversion.id, + originType = GiftCard.FromStoreCredit, + currency = credit.currency, + originalBalance = credit.currentBalance, + currentBalance = credit.currentBalance + )) // Activity _ ← * <~ LogActivity().scConvertedToGc(admin, giftCard, credit) diff --git a/phoenix-scala/phoenix/app/phoenix/services/EntityExporter.scala b/phoenix-scala/phoenix/app/phoenix/services/EntityExporter.scala index 8a4047fa33..a42790fe6e 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/EntityExporter.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/EntityExporter.scala @@ -38,16 +38,14 @@ object EntityExporter { catching(classOf[NumberFormatException]).opt(field.stripPrefix("[").stripSuffix("]").toInt) } - def export(payload: ExportEntity, entity: ExportableEntity)( - implicit apis: Apis, - au: AU, - ec: EC, - system: ActorSystem): HttpResponse = { + def export( + payload: ExportEntity, + entity: ExportableEntity)(implicit apis: Apis, au: AU, ec: EC, system: ActorSystem): HttpResponse = { implicit val chunkable = Chunkable.csvChunkable(payload.fields.map(_.displayName)) val index = s"admin_${au.token.scope}" / entity.searchView val fields = entity.extraFields - .map(getPath(_, removeArrayIndices = true).mkString(".")) ::: payload.fields.map { + .map(getPath(_, removeArrayIndices = true).mkString(".")) ::: payload.fields.map { case ExportField(name, _) ⇒ getPath(name, removeArrayIndices = true) .mkString(".") // we don't care about array index if it exists @@ -64,8 +62,7 @@ object EntityExporter { case ExportField(name, displayName) if entity.calculateFields.isDefinedAt((name, obj)) ⇒ (displayName, entity.calculateFields((name, obj))) case ExportField(name, displayName) ⇒ - (displayName, - extractValue(getPath(name, removeArrayIndices = false), Some(obj)).getOrElse("")) + (displayName, extractValue(getPath(name, removeArrayIndices = false), Some(obj)).getOrElse("")) } } @@ -73,7 +70,7 @@ object EntityExporter { Http.renderAttachment(fileName = setName(payload, entity))(csvSource) } - private def getPath(field: String, removeArrayIndices: Boolean): List[String] = { + private def getPath(field: String, removeArrayIndices: Boolean): List[String] = if (field.nonEmpty) { val path = field.split("\\.") @@ -85,14 +82,13 @@ object EntityExporter { case _ ⇒ Nil }(collection.breakOut) } else Nil - } /** Extracts value from (possibly nested) field path. * * When there is something left in `path` and `acc` is not a json object, * we simply omit outputting the value. */ - @tailrec private def extractValue(path: List[String], acc: Option[JValue]): Option[String] = { + @tailrec private def extractValue(path: List[String], acc: Option[JValue]): Option[String] = (path, acc) match { case (h :: t, Some(jobj: JObject)) ⇒ extractValue(t, jobj.obj.toMap.get(h)) case (ArrayElement(i) :: t, Some(jarr: JArray)) ⇒ @@ -106,7 +102,6 @@ object EntityExporter { } case (_, _) ⇒ None } - } private def setName(payload: ExportEntity, entity: ExportableEntity): String = { val date = formatter.format(Instant.now) @@ -115,10 +110,9 @@ object EntityExporter { (List(entity.entity) ++ description ++ List(date)).mkString("", "-", ".csv") } - private def export( - searchIndex: IndexAndTypes, - searchFields: List[String], - searchIds: List[Long])(implicit apis: Apis, au: AU, ec: EC): Source[Json, NotUsed] = { + private def export(searchIndex: IndexAndTypes, + searchFields: List[String], + searchIds: List[Long])(implicit apis: Apis, au: AU, ec: EC): Source[Json, NotUsed] = { // As of 2.3.x elastic4s's fetchSourceContext on single get item is ignored in multi get request, // so we need to set it manually. // This time we dank mutability. @@ -130,9 +124,10 @@ object EntityExporter { // It's not true, as multiget fetches all documents eagerly. Source .fromFuture(apis.elasticSearch.client.execute(query)) - .map(_.responses - .flatMap(_.response.map(_.getSourceAsString).map(parseOpt(_).getOrElse(JObject()))) - .toStream) + .map( + _.responses + .flatMap(_.response.map(_.getSourceAsString).map(parseOpt(_).getOrElse(JObject()))) + .toStream) .map(Source.apply) .flatMapConcat(identity) } @@ -150,8 +145,7 @@ object EntityExporter { case _ ⇒ rawQuery } Source - .fromPublisher( - apis.elasticSearch.client.publisher(query sourceInclude (searchFields: _*) scroll "1m")) + .fromPublisher(apis.elasticSearch.client.publisher(query sourceInclude (searchFields: _*) scroll "1m")) .map(_.getSourceAsString) .map(parseOpt(_).getOrElse(JObject())) } diff --git a/phoenix-scala/phoenix/app/phoenix/services/LineItemManager.scala b/phoenix-scala/phoenix/app/phoenix/services/LineItemManager.scala index cbb2fc5b5d..e30cd3942a 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/LineItemManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/LineItemManager.scala @@ -14,15 +14,13 @@ import slick.jdbc.PostgresProfile.api._ import core.db._ object LineItemManager { - def getCartLineItems(refNum: String)(implicit ec: EC, - db: DB): DbResultT[Seq[CartLineItemProductData]] = + def getCartLineItems(refNum: String)(implicit ec: EC, db: DB): DbResultT[Seq[CartLineItemProductData]] = for { lineItems ← * <~ CartLineItems.filter(_.cordRef === refNum).result lineItemData ← * <~ lineItems.map(getCartLineItem) } yield lineItemData - def getOrderLineItems(refNum: String)(implicit ec: EC, - db: DB): DbResultT[Seq[OrderLineItemProductData]] = + def getOrderLineItems(refNum: String)(implicit ec: EC, db: DB): DbResultT[Seq[OrderLineItemProductData]] = for { lineItems ← * <~ OrderLineItems.filter(_.cordRef === refNum).result lineItemData ← * <~ lineItems.map(getOrderLineItem) @@ -40,30 +38,33 @@ object LineItemManager { product ← * <~ getProductForSku(sku.model) image ← * <~ getLineItemImage(sku.model, product.model) } yield - CartLineItemProductData(sku = sku.model, - skuForm = sku.form, - skuShadow = sku.shadow, - productForm = product.form, - productShadow = product.shadow, - image = image, - lineItem = cartLineItem, - attributes = cartLineItem.attributes) + CartLineItemProductData( + sku = sku.model, + skuForm = sku.form, + skuShadow = sku.shadow, + productForm = product.form, + productShadow = product.shadow, + image = image, + lineItem = cartLineItem, + attributes = cartLineItem.attributes + ) private def getOrderLineItem(orderLineItem: OrderLineItem)(implicit ec: EC, db: DB) = for { - sku ← * <~ SkuManager.mustFindFullSkuByIdAndShadowId(orderLineItem.skuId, - orderLineItem.skuShadowId) + sku ← * <~ SkuManager.mustFindFullSkuByIdAndShadowId(orderLineItem.skuId, orderLineItem.skuShadowId) product ← * <~ getProductForSku(sku.model) image ← * <~ getLineItemImage(sku.model, product.model) } yield - OrderLineItemProductData(sku = sku.model, - skuForm = sku.form, - skuShadow = sku.shadow, - productForm = product.form, - productShadow = product.shadow, - image = image, - lineItem = orderLineItem, - attributes = orderLineItem.attributes) + OrderLineItemProductData( + sku = sku.model, + skuForm = sku.form, + skuShadow = sku.shadow, + productForm = product.form, + productShadow = product.shadow, + image = image, + lineItem = orderLineItem, + attributes = orderLineItem.attributes + ) private def getProductForSku(sku: Sku)(implicit ec: EC, db: DB) = for { diff --git a/phoenix-scala/phoenix/app/phoenix/services/LineItemUpdater.scala b/phoenix-scala/phoenix/app/phoenix/services/LineItemUpdater.scala index 7432b2c9ae..aad1afd2fa 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/LineItemUpdater.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/LineItemUpdater.scala @@ -45,35 +45,29 @@ object LineItemUpdater { } yield response } - def updateOrderLineItems(admin: User, payload: Seq[UpdateOrderLineItemsPayload], refNum: String)( - implicit ec: EC, - apis: Apis, - db: DB, - ac: AC, - ctx: OC): DbResultT[OrderResponse] = + def updateOrderLineItems( + admin: User, + payload: Seq[UpdateOrderLineItemsPayload], + refNum: String)(implicit ec: EC, apis: Apis, db: DB, ac: AC, ctx: OC): DbResultT[OrderResponse] = for { _ ← * <~ runOrderLineItemUpdates(payload) orderUpdated ← * <~ Orders.mustFindByRefNum(refNum) orderResponse ← * <~ OrderResponse.fromOrder(orderUpdated, grouped = true) } yield orderResponse - private def runOrderLineItemUpdates(payload: Seq[UpdateOrderLineItemsPayload])(implicit ec: EC, - apis: Apis, - db: DB, - ac: AC, - ctx: OC) = + private def runOrderLineItemUpdates( + payload: Seq[UpdateOrderLineItemsPayload])(implicit ec: EC, apis: Apis, db: DB, ac: AC, ctx: OC) = DbResultT.seqCollectFailures( - payload - .map(updatePayload ⇒ - for { - orderLineItem ← * <~ OrderLineItems - .filter(_.referenceNumber === updatePayload.referenceNumber) - .mustFindOneOr(OrderLineItemNotFound(updatePayload.referenceNumber)) - patch = orderLineItem.copy(state = updatePayload.state, - attributes = updatePayload.attributes) - updatedItem ← * <~ OrderLineItems.update(orderLineItem, patch) - } yield updatedItem) - .toList) + payload + .map(updatePayload ⇒ + for { + orderLineItem ← * <~ OrderLineItems + .filter(_.referenceNumber === updatePayload.referenceNumber) + .mustFindOneOr(OrderLineItemNotFound(updatePayload.referenceNumber)) + patch = orderLineItem.copy(state = updatePayload.state, attributes = updatePayload.attributes) + updatedItem ← * <~ OrderLineItems.update(orderLineItem, patch) + } yield updatedItem) + .toList) def updateQuantitiesOnCustomersCart(customer: User, payload: Seq[UpdateLineItemsPayload])( implicit ec: EC, @@ -139,8 +133,7 @@ object LineItemUpdater { } yield response } - def runUpdates(cart: Cart, - logAct: Option[(CartResponse, Map[String, Int]) ⇒ DbResultT[Activity]])( + def runUpdates(cart: Cart, logAct: Option[(CartResponse, Map[String, Int]) ⇒ DbResultT[Activity]])( implicit ec: EC, apis: Apis, db: DB, @@ -154,7 +147,7 @@ object LineItemUpdater { valid ← * <~ CartValidator(cart).validate() res ← * <~ CartResponse.buildRefreshed(cart) li ← * <~ CartLineItems.byCordRef(cart.refNum).countSkus - _ ← * <~ logAct.traverse(_ (res, li)).void + _ ← * <~ logAct.traverse(_(res, li)).void } yield TheResponse.validated(res, valid) def foldQuantityPayload(payload: Seq[UpdateLineItemsPayload]): Map[String, Int] = @@ -163,10 +156,9 @@ object LineItemUpdater { acc.updated(item.sku, quantity + item.quantity) } - private def updateQuantities(cart: Cart, payload: Seq[UpdateLineItemsPayload])( - implicit ec: EC, - ctx: OC, - db: DB): DbResultT[Seq[CartLineItem]] = + private def updateQuantities( + cart: Cart, + payload: Seq[UpdateLineItemsPayload])(implicit ec: EC, ctx: OC, db: DB): DbResultT[Seq[CartLineItem]] = for { _ ← * <~ CartLineItems .byCordRef(cart.referenceNumber) @@ -184,11 +176,8 @@ object LineItemUpdater { fullSku ← ObjectManager.getFullObject(DbResultT.pure(sku)) _ ← * <~ IlluminatedSku.illuminate(ctx, fullSku).mustBeActive // TODO: check if that SKU’s Product is not archived/deactivated @michalrus - _ ← * <~ mustFindProductIdForSku(sku, cart.refNum) - updateResult ← * <~ createLineItems(sku.id, - lineItem.quantity, - cart.refNum, - lineItem.attributes) + _ ← * <~ mustFindProductIdForSku(sku, cart.refNum) + updateResult ← * <~ createLineItems(sku.id, lineItem.quantity, cart.refNum, lineItem.attributes) } yield updateResult private def createLineItems(skuId: Int, @@ -200,9 +189,8 @@ object LineItemUpdater { CartLineItems.createAllReturningModels(List.fill(quantity)(lineItem)) } - private def addQuantities(cart: Cart, payload: Seq[UpdateLineItemsPayload])( - implicit ec: EC, - ctx: OC): DbResultT[Unit] = { + private def addQuantities(cart: Cart, payload: Seq[UpdateLineItemsPayload])(implicit ec: EC, + ctx: OC): DbResultT[Unit] = { val lineItemUpdActions = payload.map { lineItem ⇒ for { sku ← * <~ Skus @@ -219,7 +207,7 @@ object LineItemUpdater { DbResultT.seqCollectFailures(lineItemUpdActions.toList).meh } - private def mustFindProductIdForSku(sku: Sku, refNum: String)(implicit ec: EC, oc: OC) = { + private def mustFindProductIdForSku(sku: Sku, refNum: String)(implicit ec: EC, oc: OC) = for { link ← * <~ ProductSkuLinks.filter(_.rightId === sku.id).one.dbresult.flatMap { case Some(productLink) ⇒ @@ -238,13 +226,11 @@ object LineItemUpdater { } yield productLink.leftId } } yield link - } - private def removeLineItems( - skuId: Int, - delta: Int, - cordRef: String, - requestedAttrs: Option[LineItemAttributes])(implicit ec: EC): DbResultT[Unit] = + private def removeLineItems(skuId: Int, + delta: Int, + cordRef: String, + requestedAttrs: Option[LineItemAttributes])(implicit ec: EC): DbResultT[Unit] = CartLineItems .byCordRef(cordRef) .filter(_.skuId === skuId) diff --git a/phoenix-scala/phoenix/app/phoenix/services/LogActivity.scala b/phoenix-scala/phoenix/app/phoenix/services/LogActivity.scala index 4a19996a45..2efc3af441 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/LogActivity.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/LogActivity.scala @@ -67,36 +67,29 @@ case class LogActivity(implicit ac: AC) { entity: T, assignees: Seq[UserResponse], assignType: AssignmentType, - refType: ReferenceType)(implicit ec: EC): DbResultT[Activity] = { + refType: ReferenceType)(implicit ec: EC): DbResultT[Activity] = Activities.log(Assigned[T](buildUser(admin), entity, assignees, assignType, refType)) - } def unassigned[T](admin: User, entity: T, assignee: User, assignType: AssignmentType, - refType: ReferenceType)(implicit ec: EC): DbResultT[Activity] = { - Activities.log( - Unassigned[T](buildUser(admin), entity, buildUser(assignee), assignType, refType)) - } + refType: ReferenceType)(implicit ec: EC): DbResultT[Activity] = + Activities.log(Unassigned[T](buildUser(admin), entity, buildUser(assignee), assignType, refType)) def bulkAssigned(admin: User, assignee: User, entityIds: Seq[String], assignType: AssignmentType, - refType: ReferenceType)(implicit ec: EC): DbResultT[Activity] = { - Activities.log( - BulkAssigned(buildUser(admin), buildUser(assignee), entityIds, assignType, refType)) - } + refType: ReferenceType)(implicit ec: EC): DbResultT[Activity] = + Activities.log(BulkAssigned(buildUser(admin), buildUser(assignee), entityIds, assignType, refType)) def bulkUnassigned(admin: User, assignee: User, entityIds: Seq[String], assignType: AssignmentType, - refType: ReferenceType)(implicit ec: EC): DbResultT[Activity] = { - Activities.log( - BulkUnassigned(buildUser(admin), buildUser(assignee), entityIds, assignType, refType)) - } + refType: ReferenceType)(implicit ec: EC): DbResultT[Activity] = + Activities.log(BulkUnassigned(buildUser(admin), buildUser(assignee), entityIds, assignType, refType)) /* Notes */ def noteCreated[T](admin: User, entity: T, note: Note)(implicit ec: EC): DbResultT[Activity] = @@ -111,18 +104,15 @@ case class LogActivity(implicit ac: AC) { /* Shared Search Associations */ def associatedWithSearch(admin: User, search: SharedSearch, associates: Seq[User])( - implicit ec: EC): DbResultT[Activity] = { + implicit ec: EC): DbResultT[Activity] = Activities.log(AssociatedWithSearch(buildUser(admin), search, associates.map(buildUser))) - } def unassociatedFromSearch(admin: User, search: SharedSearch, associate: User)( - implicit ec: EC): DbResultT[Activity] = { + implicit ec: EC): DbResultT[Activity] = Activities.log(UnassociatedFromSearch(buildUser(admin), search, buildUser(associate))) - } /* Customer */ - def customerCreated(user: CustomerResponse, admin: Option[User])( - implicit ec: EC): DbResultT[Activity] = + def customerCreated(user: CustomerResponse, admin: Option[User])(implicit ec: EC): DbResultT[Activity] = admin match { case Some(a) ⇒ Activities.log(CustomerCreated(buildUser(a), user)) @@ -130,12 +120,10 @@ case class LogActivity(implicit ac: AC) { Activities.log(CustomerRegistered(user)) } - def customerUpdated(user: User, updated: User, admin: Option[User])( - implicit ec: EC): DbResultT[Activity] = + def customerUpdated(user: User, updated: User, admin: Option[User])(implicit ec: EC): DbResultT[Activity] = Activities.log(CustomerUpdated(buildUser(user), buildUser(updated), admin.map(buildUser))) - def customerActivated(user: CustomerResponse, admin: User)( - implicit ec: EC): DbResultT[Activity] = + def customerActivated(user: CustomerResponse, admin: User)(implicit ec: EC): DbResultT[Activity] = Activities.log(CustomerActivated(buildUser(admin), user)) /* Users */ @@ -153,12 +141,10 @@ case class LogActivity(implicit ac: AC) { Activities.log(UserActivated(buildUser(admin), user)) // FIXME unused, do we need it? @aafa - def userUpdated(user: User, updated: User, admin: Option[User])( - implicit ec: EC): DbResultT[Activity] = + def userUpdated(user: User, updated: User, admin: Option[User])(implicit ec: EC): DbResultT[Activity] = Activities.log(UserUpdated(buildUser(user), buildUser(updated), admin.map(buildUser))) - def userDisabled(disabled: Boolean, user: User, admin: User)( - implicit ec: EC): DbResultT[Activity] = { + def userDisabled(disabled: Boolean, user: User, admin: User)(implicit ec: EC): DbResultT[Activity] = { val adminResponse = buildUser(admin) val userResponse = buildUser(user) @@ -170,8 +156,7 @@ case class LogActivity(implicit ac: AC) { } } - def userBlacklisted(blacklisted: Boolean, user: User, admin: User)( - implicit ec: EC): DbResultT[Activity] = { + def userBlacklisted(blacklisted: Boolean, user: User, admin: User)(implicit ec: EC): DbResultT[Activity] = { val adminResponse = buildUser(admin) val userResponse = buildUser(user) @@ -196,36 +181,30 @@ case class LogActivity(implicit ac: AC) { /* User Addresses */ def addressCreated(originator: User, user: User, address: AddressResponse)( - implicit ec: EC): DbResultT[Activity] = { + implicit ec: EC): DbResultT[Activity] = Activities.log(UserAddressCreated(buildUser(user), address, buildOriginator(originator))) - } - def addressUpdated(originator: User, - user: User, - newAddress: AddressResponse, - oldAddress: AddressResponse)(implicit ec: EC): DbResultT[Activity] = + def addressUpdated(originator: User, user: User, newAddress: AddressResponse, oldAddress: AddressResponse)( + implicit ec: EC): DbResultT[Activity] = Activities.log( - UserAddressUpdated(user = buildUser(user), - newInfo = newAddress, - oldInfo = oldAddress, - admin = buildOriginator(originator))) + UserAddressUpdated(user = buildUser(user), + newInfo = newAddress, + oldInfo = oldAddress, + admin = buildOriginator(originator))) def addressDeleted(originator: User, user: User, address: AddressResponse)( implicit ec: EC): DbResultT[Activity] = Activities.log(UserAddressDeleted(buildUser(user), address, buildOriginator(originator))) /* Users Credit Cards */ - def ccCreated(user: User, cc: CreditCard, admin: Option[User])( - implicit ec: EC): DbResultT[Activity] = + def ccCreated(user: User, cc: CreditCard, admin: Option[User])(implicit ec: EC): DbResultT[Activity] = Activities.log(CreditCardAdded(buildUser(user), buildCc(cc), admin.map(buildUser))) def ccUpdated(user: User, newCc: CreditCard, oldCc: CreditCard, admin: Option[User])( implicit ec: EC): DbResultT[Activity] = - Activities.log( - CreditCardUpdated(buildUser(user), buildCc(newCc), buildCc(oldCc), admin.map(buildUser))) + Activities.log(CreditCardUpdated(buildUser(user), buildCc(newCc), buildCc(oldCc), admin.map(buildUser))) - def ccDeleted(user: User, cc: CreditCard, admin: Option[User])( - implicit ec: EC): DbResultT[Activity] = + def ccDeleted(user: User, cc: CreditCard, admin: Option[User])(implicit ec: EC): DbResultT[Activity] = Activities.log(CreditCardRemoved(buildUser(user), buildCc(cc), admin.map(buildUser))) /* Gift Cards */ @@ -234,15 +213,13 @@ case class LogActivity(implicit ac: AC) { def gcUpdated(admin: User, giftCard: GiftCard, payload: GiftCardUpdateStateByCsr)( implicit ec: EC): DbResultT[Activity] = - Activities.log( - GiftCardStateChanged(buildUser(admin), GiftCardResponse.build(giftCard), payload)) + Activities.log(GiftCardStateChanged(buildUser(admin), GiftCardResponse.build(giftCard), payload)) - def gcConvertedToSc(admin: User, gc: GiftCard, sc: StoreCredit)( - implicit ec: EC): DbResultT[Activity] = + def gcConvertedToSc(admin: User, gc: GiftCard, sc: StoreCredit)(implicit ec: EC): DbResultT[Activity] = Activities.log( - GiftCardConvertedToStoreCredit(buildUser(admin), - GiftCardResponse.build(gc), - StoreCreditResponse.build(sc))) + GiftCardConvertedToStoreCredit(buildUser(admin), + GiftCardResponse.build(gc), + StoreCreditResponse.build(sc))) def gcFundsAuthorized(user: User, cart: Cart, gcCodes: Seq[String], amount: Long)( implicit ec: EC): DbResultT[Activity] = @@ -254,20 +231,17 @@ case class LogActivity(implicit ac: AC) { /* Store Credits */ def scCreated(admin: User, user: User, sc: StoreCredit)(implicit ec: EC): DbResultT[Activity] = - Activities.log( - StoreCreditCreated(buildUser(admin), buildUser(user), StoreCreditResponse.build(sc))) + Activities.log(StoreCreditCreated(buildUser(admin), buildUser(user), StoreCreditResponse.build(sc))) def scUpdated(admin: User, sc: StoreCredit, payload: StoreCreditUpdateStateByCsr)( implicit ec: EC): DbResultT[Activity] = - Activities.log( - StoreCreditStateChanged(buildUser(admin), StoreCreditResponse.build(sc), payload)) + Activities.log(StoreCreditStateChanged(buildUser(admin), StoreCreditResponse.build(sc), payload)) - def scConvertedToGc(admin: User, gc: GiftCard, sc: StoreCredit)( - implicit ec: EC): DbResultT[Activity] = + def scConvertedToGc(admin: User, gc: GiftCard, sc: StoreCredit)(implicit ec: EC): DbResultT[Activity] = Activities.log( - StoreCreditConvertedToGiftCard(buildUser(admin), - GiftCardResponse.build(gc), - StoreCreditResponse.build(sc))) + StoreCreditConvertedToGiftCard(buildUser(admin), + GiftCardResponse.build(gc), + StoreCreditResponse.build(sc))) def scFundsAuthorized(user: User, cart: Cart, scIds: Seq[Int], amount: Long)( implicit ec: EC): DbResultT[Activity] = @@ -286,15 +260,12 @@ case class LogActivity(implicit ac: AC) { implicit ec: EC): DbResultT[Activity] = Activities.log(OrderStateChanged(buildUser(admin), order, oldState)) - def orderBulkStateChanged(newState: Order.State, - cordRefNums: Seq[String], - admin: Option[User] = None)(implicit ec: EC): DbResultT[Activity] = + def orderBulkStateChanged(newState: Order.State, cordRefNums: Seq[String], admin: Option[User] = None)( + implicit ec: EC): DbResultT[Activity] = Activities.log(OrderBulkStateChanged(admin.map(buildUser), cordRefNums, newState)) - def orderRemorsePeriodIncreased( - admin: User, - order: OrderResponse, - oldPeriodEnd: Option[Instant])(implicit ec: EC): DbResultT[Activity] = + def orderRemorsePeriodIncreased(admin: User, order: OrderResponse, oldPeriodEnd: Option[Instant])( + implicit ec: EC): DbResultT[Activity] = Activities.log(OrderRemorsePeriodIncreased(buildUser(admin), order, oldPeriodEnd)) /* Cart Line Items */ @@ -304,23 +275,18 @@ case class LogActivity(implicit ac: AC) { def orderLineItemsUpdatedGc(admin: User, cart: CartResponse, gc: GiftCard)( implicit ec: EC): DbResultT[Activity] = - Activities.log( - CartLineItemsUpdatedGiftCard(buildUser(admin), cart, GiftCardResponse.build(gc))) + Activities.log(CartLineItemsUpdatedGiftCard(buildUser(admin), cart, GiftCardResponse.build(gc))) def orderLineItemsDeletedGc(admin: User, cart: CartResponse, gc: GiftCard)( implicit ec: EC): DbResultT[Activity] = - Activities.log( - CartLineItemsDeletedGiftCard(buildUser(admin), cart, GiftCardResponse.build(gc))) + Activities.log(CartLineItemsDeletedGiftCard(buildUser(admin), cart, GiftCardResponse.build(gc))) def orderLineItemsUpdated(cart: CartResponse, oldQtys: Map[String, Int], payload: Seq[UpdateLineItemsPayload], admin: Option[User] = None)(implicit ec: EC): DbResultT[Activity] = Activities.log( - CartLineItemsUpdatedQuantities(cart, - oldQtys, - foldQuantityPayload(payload), - admin.map(buildUser))) + CartLineItemsUpdatedQuantities(cart, oldQtys, foldQuantityPayload(payload), admin.map(buildUser))) /* Order checkout & payments */ @@ -329,66 +295,61 @@ case class LogActivity(implicit ac: AC) { def orderCaptured(order: Order, cap: CaptureResponse)(implicit ec: EC): DbResultT[Activity] = Activities.log( - OrderCaptured(orderNum = order.referenceNumber, - accountId = order.accountId, - captured = cap.captured, - external = cap.external, - internal = cap.internal, - lineItems = cap.lineItems, - taxes = cap.taxes, - shipping = cap.shipping, - currency = cap.currency)) + OrderCaptured( + orderNum = order.referenceNumber, + accountId = order.accountId, + captured = cap.captured, + external = cap.external, + internal = cap.internal, + lineItems = cap.lineItems, + taxes = cap.taxes, + shipping = cap.shipping, + currency = cap.currency + )) def creditCardAuth(cart: Cart, charge: CreditCardCharge)(implicit ec: EC): DbResultT[Activity] = Activities.log( - CreditCardAuthCompleted( - accountId = cart.accountId, - cordRef = cart.refNum, - orderNum = cart.refNum, - cardId = charge.creditCardId, - amount = charge.amount, - currency = charge.currency - )) - - def applePayAuth(ap: ApplePayment, charge: ApplePayCharge)( - implicit ec: EC): DbResultT[Activity] = + CreditCardAuthCompleted( + accountId = cart.accountId, + cordRef = cart.refNum, + orderNum = cart.refNum, + cardId = charge.creditCardId, + amount = charge.amount, + currency = charge.currency + )) + + def applePayAuth(ap: ApplePayment, charge: ApplePayCharge)(implicit ec: EC): DbResultT[Activity] = Activities.log( - ApplePayAuthCompleted( - accountId = ap.accountId, - stripeTokenId = ap.stripeTokenId, - amount = charge.amount, - currency = charge.currency - )) - - def creditCardCharge(order: Order, charge: CreditCardCharge)( - implicit ec: EC): DbResultT[Activity] = + ApplePayAuthCompleted( + accountId = ap.accountId, + stripeTokenId = ap.stripeTokenId, + amount = charge.amount, + currency = charge.currency + )) + + def creditCardCharge(order: Order, charge: CreditCardCharge)(implicit ec: EC): DbResultT[Activity] = Activities.log( - CreditCardChargeCompleted( - accountId = order.accountId, - cordRef = order.refNum, - orderNum = order.refNum, - cardId = charge.creditCardId, - amount = charge.amount, - currency = charge.currency - )) + CreditCardChargeCompleted( + accountId = order.accountId, + cordRef = order.refNum, + orderNum = order.refNum, + cardId = charge.creditCardId, + amount = charge.amount, + currency = charge.currency + )) /* Cart Payment Methods */ - def orderPaymentMethodAddedCc(originator: User, - cart: CartResponse, - cc: CreditCard, - region: Region)(implicit ec: EC): DbResultT[Activity] = + def orderPaymentMethodAddedCc(originator: User, cart: CartResponse, cc: CreditCard, region: Region)( + implicit ec: EC): DbResultT[Activity] = Activities.log( - CartPaymentMethodAddedCreditCard(cart, - CreditCardsResponse.build(cc, region), - buildOriginator(originator))) + CartPaymentMethodAddedCreditCard(cart, + CreditCardsResponse.build(cc, region), + buildOriginator(originator))) def orderPaymentMethodAddedGc(originator: User, cart: CartResponse, gc: GiftCard, amount: Long)( implicit ec: EC): DbResultT[Activity] = Activities.log( - CartPaymentMethodAddedGiftCard(cart, - GiftCardResponse.build(gc), - amount, - buildOriginator(originator))) + CartPaymentMethodAddedGiftCard(cart, GiftCardResponse.build(gc), amount, buildOriginator(originator))) def orderPaymentMethodUpdatedGc(originator: User, cart: CartResponse, @@ -415,9 +376,7 @@ case class LogActivity(implicit ac: AC) { def orderPaymentMethodDeletedGc(originator: User, cart: CartResponse, gc: GiftCard)( implicit ec: EC): DbResultT[Activity] = Activities.log( - CartPaymentMethodDeletedGiftCard(cart, - GiftCardResponse.build(gc), - buildOriginator(originator))) + CartPaymentMethodDeletedGiftCard(cart, GiftCardResponse.build(gc), buildOriginator(originator))) /* Cart Shipping Addresses */ def orderShippingAddressAdded(originator: User, cart: CartResponse, address: AddressResponse)( @@ -439,15 +398,12 @@ case class LogActivity(implicit ac: AC) { shippingMethod: Option[ShippingMethod])(implicit ec: EC): DbResultT[Activity] = Activities.log(CartShippingMethodUpdated(cart, shippingMethod, buildOriginator(originator))) - def orderShippingMethodDeleted( - originator: User, - cart: CartResponse, - shippingMethod: ShippingMethod)(implicit ec: EC): DbResultT[Activity] = + def orderShippingMethodDeleted(originator: User, cart: CartResponse, shippingMethod: ShippingMethod)( + implicit ec: EC): DbResultT[Activity] = Activities.log(CartShippingMethodRemoved(cart, shippingMethod, buildOriginator(originator))) /* Cart Coupons */ - def orderCouponAttached(cart: Cart, couponCode: CouponCode)( - implicit ec: EC): DbResultT[Activity] = + def orderCouponAttached(cart: Cart, couponCode: CouponCode)(implicit ec: EC): DbResultT[Activity] = Activities.log(CartCouponAttached(cart, couponCode)) def orderCouponDetached(cart: Cart)(implicit ec: EC): DbResultT[Activity] = @@ -471,15 +427,13 @@ case class LogActivity(implicit ac: AC) { implicit ec: EC): DbResultT[Activity] = Activities.log(ReturnSkuLineItemAdded(rma, reason, payload)) - def returnShippingCostItemDeleted(lineItem: ReturnLineItem)( - implicit ec: EC): DbResultT[Activity] = + def returnShippingCostItemDeleted(lineItem: ReturnLineItem)(implicit ec: EC): DbResultT[Activity] = Activities.log(ReturnShippingCostItemDeleted(lineItem)) def returnSkuLineItemDeleted(lineItem: ReturnLineItem)(implicit ec: EC): DbResultT[Activity] = Activities.log(ReturnSkuLineItemDeleted(lineItem)) - def returnSkuLineItemsDropped(skus: List[ReturnLineItemSku])( - implicit ec: EC): DbResultT[Activity] = + def returnSkuLineItemsDropped(skus: List[ReturnLineItemSku])(implicit ec: EC): DbResultT[Activity] = Activities.log(ReturnSkuLineItemsDropped(skus)) def returnPaymentsAdded(rma: ReturnResponse.Root, payments: List[PaymentMethod.Type])( @@ -492,52 +446,44 @@ case class LogActivity(implicit ac: AC) { def issueCcRefund(rma: Return, payment: ReturnPayment)(implicit ec: EC): DbResultT[Activity] = Activities.log(ReturnIssueCcRefund(rma, payment)) - def issueGcRefund(customer: User, rma: Return, gc: GiftCard)( - implicit ec: EC): DbResultT[Activity] = + def issueGcRefund(customer: User, rma: Return, gc: GiftCard)(implicit ec: EC): DbResultT[Activity] = Activities.log(ReturnIssueGcRefund(customer, rma, gc)) - def issueScRefund(customer: User, rma: Return, sc: StoreCredit)( - implicit ec: EC): DbResultT[Activity] = + def issueScRefund(customer: User, rma: Return, sc: StoreCredit)(implicit ec: EC): DbResultT[Activity] = Activities.log(ReturnIssueScRefund(customer, rma, sc)) def cancelRefund(rma: Return)(implicit ec: EC): DbResultT[Activity] = Activities.log(ReturnCancelRefund(rma)) /* Categories */ - def fullCategoryCreated( - admin: Option[User], - category: FullCategoryResponse.Root, - context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = + def fullCategoryCreated(admin: Option[User], + category: FullCategoryResponse.Root, + context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = Activities.log(FullCategoryCreated(admin.map(buildUser), category, context)) - def fullCategoryUpdated( - admin: Option[User], - category: FullCategoryResponse.Root, - context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = + def fullCategoryUpdated(admin: Option[User], + category: FullCategoryResponse.Root, + context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = Activities.log(FullCategoryUpdated(admin.map(buildUser), category, context)) /* Products */ - def fullProductCreated( - admin: Option[User], - product: ProductResponse.Root, - context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = + def fullProductCreated(admin: Option[User], + product: ProductResponse.Root, + context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = Activities.log(FullProductCreated(admin.map(buildUser), product, context)) - def fullProductUpdated( - admin: Option[User], - product: ProductResponse.Root, - context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = + def fullProductUpdated(admin: Option[User], + product: ProductResponse.Root, + context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = Activities.log(FullProductUpdated(admin.map(buildUser), product, context)) /* SKUs */ - def fullSkuCreated(admin: Option[User], - product: SkuResponse.Root, - context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = + def fullSkuCreated(admin: Option[User], product: SkuResponse.Root, context: ObjectContextResponse.Root)( + implicit ec: EC): DbResultT[Activity] = Activities.log(FullSkuCreated(admin.map(buildUser), product, context)) - def fullSkuUpdated(admin: Option[User], - product: SkuResponse.Root, - context: ObjectContextResponse.Root)(implicit ec: EC): DbResultT[Activity] = + def fullSkuUpdated(admin: Option[User], product: SkuResponse.Root, context: ObjectContextResponse.Root)( + implicit ec: EC): DbResultT[Activity] = Activities.log(FullSkuUpdated(admin.map(buildUser), product, context)) /* Promotions */ @@ -558,12 +504,10 @@ case class LogActivity(implicit ac: AC) { implicit ec: EC): DbResultT[Activity] = Activities.log(CouponUpdated(couponResponse, admin.map(buildUser(_)))) - def singleCouponCodeCreated(coupon: Coupon, admin: Option[User])( - implicit ec: EC): DbResultT[Activity] = + def singleCouponCodeCreated(coupon: Coupon, admin: Option[User])(implicit ec: EC): DbResultT[Activity] = Activities.log(SingleCouponCodeGenerated(coupon, admin.map(buildUser(_)))) - def multipleCouponCodeCreated(coupon: Coupon, admin: Option[User])( - implicit ec: EC): DbResultT[Activity] = + def multipleCouponCodeCreated(coupon: Coupon, admin: Option[User])(implicit ec: EC): DbResultT[Activity] = Activities.log(MultipleCouponCodesGenerated(coupon, admin.map(buildUser(_)))) /* Store Admin */ @@ -576,23 +520,21 @@ case class LogActivity(implicit ac: AC) { def storeAdminDeleted(entity: User, admin: User)(implicit ec: EC): DbResultT[Activity] = Activities.log(StoreAdminDeleted(entity, admin)) - def storeAdminStateChanged(entity: User, - oldState: AdminData.State, - newState: AdminData.State, - admin: User)(implicit ec: EC): DbResultT[Activity] = + def storeAdminStateChanged(entity: User, oldState: AdminData.State, newState: AdminData.State, admin: User)( + implicit ec: EC): DbResultT[Activity] = Activities.log(StoreAdminStateChanged(entity, oldState, newState, admin)) /* Customer Groups */ - def customerGroupCreated(customerGroup: CustomerGroup, - admin: User)(implicit ec: EC, ac: AC): DbResultT[Activity] = + def customerGroupCreated(customerGroup: CustomerGroup, admin: User)(implicit ec: EC, + ac: AC): DbResultT[Activity] = Activities.log(CustomerGroupCreated(CustomerGroupActivity(customerGroup), admin)) - def customerGroupUpdated(customerGroup: CustomerGroup, - admin: User)(implicit ec: EC, ac: AC): DbResultT[Activity] = + def customerGroupUpdated(customerGroup: CustomerGroup, admin: User)(implicit ec: EC, + ac: AC): DbResultT[Activity] = Activities.log(CustomerGroupUpdated(CustomerGroupActivity(customerGroup), admin)) - def customerGroupArchived(customerGroup: CustomerGroup, - admin: User)(implicit ec: EC, ac: AC): DbResultT[Activity] = + def customerGroupArchived(customerGroup: CustomerGroup, admin: User)(implicit ec: EC, + ac: AC): DbResultT[Activity] = Activities.log(CustomerGroupArchived(CustomerGroupActivity(customerGroup), admin)) /* Mail stuff */ diff --git a/phoenix-scala/phoenix/app/phoenix/services/NotificationManager.scala b/phoenix-scala/phoenix/app/phoenix/services/NotificationManager.scala index 0286312e09..ad52ea6b8e 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/NotificationManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/NotificationManager.scala @@ -22,14 +22,16 @@ object NotificationManager { def createNotification(payload: CreateNotification)(implicit ac: AC, au: AU, ec: EC, - db: DB): DbResultT[ActivityResponse.Root] = { + db: DB): DbResultT[ActivityResponse.Root] = for { dimension ← * <~ Dimensions.findOrCreateByName(payload.sourceDimension) - activity = Activity(id = payload.activity.id, - activityType = payload.activity.kind, - data = payload.activity.data, - context = payload.activity.context, - createdAt = payload.activity.createdAt) + activity = Activity( + id = payload.activity.id, + activityType = payload.activity.kind, + data = payload.activity.data, + context = payload.activity.context, + createdAt = payload.activity.createdAt + ) adminIds ← * <~ Subs .findByDimensionAndObject(dimension.id, payload.sourceObjectId) @@ -53,12 +55,10 @@ object NotificationManager { sqlu"NOTIFY #${notificationChannel(notification.accountId)}, '#$escapedPayload'" }) } yield response - } - def updateLastSeen(accountId: Int, notificationId: Int)( - implicit au: AU, - ec: EC, - db: DB): DbResultT[LastSeenNotificationResponse] = + def updateLastSeen(accountId: Int, notificationId: Int)(implicit au: AU, + ec: EC, + db: DB): DbResultT[LastSeenNotificationResponse] = for { _ ← * <~ Accounts.mustFindById404(accountId) scope = Scope.current @@ -66,12 +66,11 @@ object NotificationManager { .findByScopeAndAccountId(scope, accountId) .one .findOrCreate( - LastSeenNotifications.create( - LastSeenNotification(scope = scope, - accountId = accountId, - notificationId = notificationId))) - _ ← * <~ LastSeenNotifications.update(lastSeen, - lastSeen.copy(notificationId = notificationId)) + LastSeenNotifications.create( + LastSeenNotification(scope = scope, + accountId = accountId, + notificationId = notificationId))) + _ ← * <~ LastSeenNotifications.update(lastSeen, lastSeen.copy(notificationId = notificationId)) } yield LastSeenNotificationResponse(lastSeenNotificationId = notificationId) def subscribe(adminIds: Seq[Int], objectIds: Seq[String], reason: Sub.Reason, dimension: String)( @@ -79,7 +78,10 @@ object NotificationManager { for { dimension ← * <~ Dimensions.findOrCreateByName(dimension) realAdmins ← * <~ Users.filter(_.accountId.inSet(adminIds)).map(_.accountId).result - requestedSubs = for (adminId ← realAdmins; objectId ← objectIds) yield (adminId, objectId) + requestedSubs = for { + adminId ← realAdmins + objectId ← objectIds + } yield (adminId, objectId) partialFilter = Subs.filter(_.dimensionId === dimension.id).filter(_.reason === reason) existingSubs ← * <~ DBIO .sequence(requestedSubs.map { @@ -93,18 +95,13 @@ object NotificationManager { .map(_.flatten) newSubsQty ← * <~ Subs.createAll(requestedSubs.diff(existingSubs).map { case (adminId, objectId) ⇒ - Sub(adminId = adminId, - objectId = objectId, - dimensionId = dimension.id, - reason = reason) + Sub(adminId = adminId, objectId = objectId, dimensionId = dimension.id, reason = reason) }) warnings = Failures(adminIds.diff(realAdmins).map(NotFoundFailure404(User, _)): _*) } yield TheResponse.build(value = newSubsQty, warnings = warnings) - def unsubscribe(adminIds: Seq[Int], - objectIds: Seq[String], - reason: Sub.Reason, - dimension: String)(implicit ec: EC): DbResultT[Unit] = + def unsubscribe(adminIds: Seq[Int], objectIds: Seq[String], reason: Sub.Reason, dimension: String)( + implicit ec: EC): DbResultT[Unit] = for { d ← * <~ Dimensions.findByName(dimension).one _ ← * <~ d.fold(DbResultT.unit) { dimension ⇒ diff --git a/phoenix-scala/phoenix/app/phoenix/services/PublicService.scala b/phoenix-scala/phoenix/app/phoenix/services/PublicService.scala index c37b65151c..60cc05c583 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/PublicService.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/PublicService.scala @@ -36,9 +36,8 @@ object PublicService { .mustFindOneOr(NoRegionFound(regionShortName)) } yield region - private def sortRegions(regions: Seq[Region]): Seq[Region] = { + private def sortRegions(regions: Seq[Region]): Seq[Region] = regions.filter(r ⇒ regularUsRegions.contains(r.id)).sortBy(_.name) ++ - regions.filter(r ⇒ armedRegions.contains(r.id)).sortBy(_.name) ++ - regions.filterNot(r ⇒ usRegions.contains(r.id)).sortBy(_.name) - } + regions.filter(r ⇒ armedRegions.contains(r.id)).sortBy(_.name) ++ + regions.filterNot(r ⇒ usRegions.contains(r.id)).sortBy(_.name) } diff --git a/phoenix-scala/phoenix/app/phoenix/services/SaveForLaterManager.scala b/phoenix-scala/phoenix/app/phoenix/services/SaveForLaterManager.scala index 83071261d0..230d154a7d 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/SaveForLaterManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/SaveForLaterManager.scala @@ -37,13 +37,12 @@ object SaveForLaterManager { def deleteSaveForLater(id: Int)(implicit ec: EC, db: DB): DbResultT[Unit] = SaveForLaters.deleteById(id, DbResultT.unit, i ⇒ NotFoundFailure404(SaveForLater, i)) - private def findAllDbio(customer: User, contextId: Int)(implicit ec: EC, - db: DB): DbResultT[SavedForLater] = + private def findAllDbio(customer: User, contextId: Int)(implicit ec: EC, db: DB): DbResultT[SavedForLater] = for { sfls ← * <~ SaveForLaters.filter(_.accountId === customer.accountId).result r ← * <~ DbResultT.seqFailuresToWarnings( - sfls.toList.map(sfl ⇒ SaveForLaterResponse.forSkuId(sfl.skuId, contextId)), { - case _ ⇒ true - }) + sfls.toList.map(sfl ⇒ SaveForLaterResponse.forSkuId(sfl.skuId, contextId)), { + case _ ⇒ true + }) } yield r } diff --git a/phoenix-scala/phoenix/app/phoenix/services/SharedSearchService.scala b/phoenix-scala/phoenix/app/phoenix/services/SharedSearchService.scala index d1dd0b7e14..ed47e90022 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/SharedSearchService.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/SharedSearchService.scala @@ -14,8 +14,7 @@ import phoenix.utils.aliases._ import slick.jdbc.PostgresProfile.api._ object SharedSearchService { - def getAll(admin: User, rawScope: Option[String])(implicit ec: EC, - db: DB): DbResultT[Seq[SharedSearch]] = + def getAll(admin: User, rawScope: Option[String])(implicit ec: EC, db: DB): DbResultT[Seq[SharedSearch]] = for { scope ← * <~ rawScope.toEither(SharedSearchScopeNotFound.single) searchScope ← * <~ SharedSearch.Scope @@ -33,18 +32,16 @@ object SharedSearchService { associates ← * <~ SharedSearchAssociations.associatedAdmins(search).result } yield associates.map(UserResponse.build) - def create(admin: User, payload: SharedSearchPayload)(implicit ec: EC, - db: DB, - au: AU): DbResultT[SharedSearch] = + def create(admin: User, + payload: SharedSearchPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[SharedSearch] = for { search ← * <~ SharedSearches.create(SharedSearch.byAdmin(admin, payload, Scope.current)) _ ← * <~ SharedSearchAssociations.create( - SharedSearchAssociation(sharedSearchId = search.id, storeAdminId = admin.accountId)) + SharedSearchAssociation(sharedSearchId = search.id, storeAdminId = admin.accountId)) } yield search - def update(admin: User, code: String, payload: SharedSearchPayload)( - implicit ec: EC, - db: DB): DbResultT[SharedSearch] = + def update(admin: User, code: String, payload: SharedSearchPayload)(implicit ec: EC, + db: DB): DbResultT[SharedSearch] = for { search ← * <~ mustFindActiveByCode(code) updated ← * <~ SharedSearches @@ -73,8 +70,7 @@ object SharedSearchService { .map(adminId ⇒ SharedSearchAssociation(sharedSearchId = search.id, storeAdminId = adminId)) _ ← * <~ SharedSearchAssociations.createAll(newAssociations) notFoundAdmins = diffToFailures(requestedAssigneeIds, adminIds, User) - assignedAdmins = associates.filter(a ⇒ - newAssociations.map(_.storeAdminId).contains(a.accountId)) + assignedAdmins = associates.filter(a ⇒ newAssociations.map(_.storeAdminId).contains(a.accountId)) _ ← * <~ LogActivity().associatedWithSearch(admin, search, assignedAdmins) } yield TheResponse.build(search, errors = notFoundAdmins) diff --git a/phoenix-scala/phoenix/app/phoenix/services/ShippingManager.scala b/phoenix-scala/phoenix/app/phoenix/services/ShippingManager.scala index 24bd338b63..7cd0bdf084 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/ShippingManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/ShippingManager.scala @@ -35,7 +35,7 @@ object ShippingManager { for { shippingMethod ← * <~ ShippingMethods.mustFindById404(shippingMethodId) _ ← * <~ DefaultShippingMethods.create( - DefaultShippingMethod(scope = Scope.current, shippingMethodId = shippingMethodId)) + DefaultShippingMethod(scope = Scope.current, shippingMethodId = shippingMethodId)) } yield ShippingMethodsResponse.build(shippingMethod) def removeDefault()(implicit ec: EC, au: AU): DbResultT[Option[Root]] = { @@ -63,22 +63,19 @@ object ShippingManager { shipData ← * <~ getShippingData(cart) } yield filterMethods(shipMethods, shipData) - def getShippingMethodsForRegion(countryCode: String, originator: User)( - implicit ec: EC, - db: DB): DbResultT[Seq[Root]] = + def getShippingMethodsForRegion(countryCode: String, originator: User)(implicit ec: EC, + db: DB): DbResultT[Seq[Root]] = for { cart ← * <~ getCartByOriginator(originator, None) shipData ← * <~ getShippingData(cart) country ← * <~ Countries.findByCode(countryCode).mustFindOneOr(NoCountryFound(countryCode)) shipMethods ← * <~ ShippingMethods.findActive.result - shipToRegion = shipData.copy( - shippingRegion = Region(countryId = country.id, name = country.name).some) + shipToRegion = shipData.copy(shippingRegion = Region(countryId = country.id, name = country.name).some) } yield filterMethods(shipMethods, shipToRegion) - def getShippingMethodsForCart(refNum: String, customer: Option[User] = None)( - implicit ec: EC, - db: DB): DbResultT[Seq[Root]] = + def getShippingMethodsForCart(refNum: String, customer: Option[User] = None)(implicit ec: EC, + db: DB): DbResultT[Seq[Root]] = for { cart ← * <~ findByRefNumAndOptionalCustomer(refNum, customer) shipMethods ← * <~ ShippingMethods.findActive.result @@ -95,8 +92,8 @@ object ShippingManager { case _ ⇒ Carts.mustFindByRefNum(refNum) } - def evaluateShippingMethodForCart(shippingMethod: ShippingMethod, - cart: Cart)(implicit ec: EC, db: DB): DbResultT[Unit] = { + def evaluateShippingMethodForCart(shippingMethod: ShippingMethod, cart: Cart)(implicit ec: EC, + db: DB): DbResultT[Unit] = getShippingData(cart).flatMap { shippingData ⇒ val failure = ShippingMethodNotApplicableToCart(shippingMethod.id, cart.refNum) if (QueryStatement.evaluate(shippingMethod.conditions, shippingData, evaluateCondition)) { @@ -107,7 +104,6 @@ object ShippingManager { DbResultT.failure(failure) } } - } def filterMethods(shipMethods: Seq[ShippingMethod], shipData: ShippingData): Seq[Root] = shipMethods.collect { @@ -125,23 +121,24 @@ object ShippingManager { lineItems ← * <~ LineItemManager.getCartLineItems(cart.refNum) } yield - ShippingData(cart = cart, - cartTotal = cart.grandTotal, - cartSubTotal = cart.subTotal, - shippingAddress = orderShippingAddress.map(_._1), - shippingRegion = orderShippingAddress.map(_._2), - lineItems = lineItems) - - private def evaluateCondition(cond: Condition, shippingData: ShippingData): Boolean = { + ShippingData( + cart = cart, + cartTotal = cart.grandTotal, + cartSubTotal = cart.subTotal, + shippingAddress = orderShippingAddress.map(_._1), + shippingRegion = orderShippingAddress.map(_._2), + lineItems = lineItems + ) + + private def evaluateCondition(cond: Condition, shippingData: ShippingData): Boolean = cond.rootObject match { case "Order" ⇒ evaluateOrderCondition(shippingData, cond) case "ShippingAddress" ⇒ evaluateShippingAddressCondition(shippingData, cond) case "LineItems" ⇒ evaluateLineItemsCondition(shippingData, cond) case _ ⇒ false } - } - private def evaluateOrderCondition(shippingData: ShippingData, condition: Condition): Boolean = { + private def evaluateOrderCondition(shippingData: ShippingData, condition: Condition): Boolean = condition.field match { case "subtotal" ⇒ Condition.matches(shippingData.cartSubTotal.toInt, condition) // FIXME @aafa .toInt @@ -149,10 +146,8 @@ object ShippingManager { Condition.matches(shippingData.cartTotal.toInt, condition) // FIXME @aafa .toInt case _ ⇒ false } - } - private def evaluateShippingAddressCondition(shippingData: ShippingData, - condition: Condition): Boolean = { + private def evaluateShippingAddressCondition(shippingData: ShippingData, condition: Condition): Boolean = shippingData.shippingAddress.fold(false) { shippingAddress ⇒ condition.field match { case "address1" ⇒ @@ -171,7 +166,7 @@ object ShippingManager { // @aafa Here I extracted shippingRegion matching against incoming queries // since we can have address and region provided separately within shippingData } || shippingData.shippingRegion.fold(false)(shippingRegion ⇒ - condition.field match { + condition.field match { case "countryId" ⇒ Condition.matches(shippingRegion.countryId, condition) case "regionName" ⇒ @@ -180,13 +175,11 @@ object ShippingManager { Condition.matches(shippingRegion.abbreviation, condition) case _ ⇒ false }) - } private val COUNT_TAG = "countTag-" private val COUNT_WITHOUT_TAG = "countWithoutTag-" - private def evaluateLineItemsCondition(shippingData: ShippingData, - condition: Condition): Boolean = + private def evaluateLineItemsCondition(shippingData: ShippingData, condition: Condition): Boolean = condition.field match { case "count" ⇒ Condition.matches(shippingData.lineItems.size, condition) case t if t startsWith COUNT_TAG ⇒ { diff --git a/phoenix-scala/phoenix/app/phoenix/services/StoreAdminManager.scala b/phoenix-scala/phoenix/app/phoenix/services/StoreAdminManager.scala index bc1c877dfd..8e67abf195 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/StoreAdminManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/StoreAdminManager.scala @@ -21,11 +21,8 @@ object StoreAdminManager { adminData ← * <~ AdminsData.mustFindByAccountId(accountId) } yield StoreAdminResponse.build(admin, adminData) - def create(payload: CreateStoreAdminPayload, author: Option[User])( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[StoreAdminResponse.Root] = { - + def create(payload: CreateStoreAdminPayload, + author: Option[User])(implicit ec: EC, db: DB, ac: AC): DbResultT[StoreAdminResponse.Root] = for { organization ← * <~ Organizations .findByName(payload.org) @@ -40,19 +37,15 @@ object StoreAdminManager { organizationScope ← * <~ Scopes.mustFindById400(organization.scopeId) scope ← * <~ Scope.overwrite(organizationScope.path, payload.scope) adminUser ← * <~ AdminsData.create( - AdminData(accountId = admin.accountId, - userId = admin.id, - state = AdminData.Invited, - scope = scope)) + AdminData(accountId = admin.accountId, + userId = admin.id, + state = AdminData.Invited, + scope = scope)) _ ← * <~ CustomersData.create( - CustomerData(accountId = admin.accountId, - userId = admin.id, - isGuest = false, - scope = scope)) + CustomerData(accountId = admin.accountId, userId = admin.id, isGuest = false, scope = scope)) _ ← * <~ LogActivity().storeAdminCreated(admin, author) } yield StoreAdminResponse.build(admin, adminUser) - } def update(accountId: Int, payload: UpdateStoreAdminPayload, @@ -85,10 +78,9 @@ object StoreAdminManager { _ ← * <~ LogActivity().storeAdminDeleted(admin, author) } yield result - def changeState(id: Int, payload: StateChangeStoreAdminPayload, author: User)( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[StoreAdminResponse.Root] = + def changeState(id: Int, + payload: StateChangeStoreAdminPayload, + author: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[StoreAdminResponse.Root] = for { admin ← * <~ Users.mustFindByAccountId(id) adminUser ← * <~ AdminsData.mustFindByAccountId(id) diff --git a/phoenix-scala/phoenix/app/phoenix/services/StoreCreditService.scala b/phoenix-scala/phoenix/app/phoenix/services/StoreCreditService.scala index 5059715a1c..be5a148791 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/StoreCreditService.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/StoreCreditService.scala @@ -28,7 +28,7 @@ object StoreCreditService { // Check subtype only if id is present in payload; discard actual model private def checkSubTypeExists(subTypeId: Option[Int], originType: StoreCredit.OriginType)( - implicit ec: EC): DbResultT[Unit] = { + implicit ec: EC): DbResultT[Unit] = subTypeId.fold(DbResultT.unit) { subtypeId ⇒ StoreCreditSubtypes .byOriginType(originType) @@ -41,16 +41,14 @@ object StoreCreditService { DbResultT.unit }) } - } - def totalsForCustomer(accountId: Int)(implicit ec: EC, - db: DB): DbResultT[StoreCreditResponse.Totals] = + def totalsForCustomer(accountId: Int)(implicit ec: EC, db: DB): DbResultT[StoreCreditResponse.Totals] = for { _ ← * <~ Users.mustFindByAccountId(accountId) totals ← * <~ fetchTotalsForCustomer(accountId) } yield totals.getOrElse(Totals(0, 0)) - def fetchTotalsForCustomer(accountId: Int)(implicit ec: EC): DBIO[Option[Totals]] = { + def fetchTotalsForCustomer(accountId: Int)(implicit ec: EC): DBIO[Option[Totals]] = StoreCredits .findAllActiveByAccountId(accountId) .groupBy(_.accountId) @@ -60,13 +58,11 @@ object StoreCreditService { case (avail, curr) ⇒ StoreCreditResponse.Totals(avail.getOrElse(0L), curr.getOrElse(0L)) }) - } - def createManual(admin: User, accountId: Int, payload: CreateManualStoreCredit)( - implicit ec: EC, - db: DB, - ac: AC, - au: AU): DbResultT[Root] = { + def createManual(admin: User, accountId: Int, payload: CreateManualStoreCredit)(implicit ec: EC, + db: DB, + ac: AC, + au: AU): DbResultT[Root] = { val reason400 = NotFoundFailure400(Reason, payload.reasonId) for { customer ← * <~ Users.mustFindByAccountId(accountId) @@ -78,24 +74,25 @@ object StoreCreditService { subReasonId = payload.subReasonId) origin ← * <~ StoreCreditManuals.create(manual) storeCredit ← * <~ StoreCredits.create( - StoreCredit(accountId = customer.accountId, - originId = origin.id, - scope = scope, - originType = StoreCredit.CsrAppeasement, - subTypeId = payload.subTypeId, - currency = payload.currency, - originalBalance = payload.amount)) + StoreCredit( + accountId = customer.accountId, + originId = origin.id, + scope = scope, + originType = StoreCredit.CsrAppeasement, + subTypeId = payload.subTypeId, + currency = payload.currency, + originalBalance = payload.amount + )) _ ← * <~ LogActivity().withScope(storeCredit.scope).scCreated(admin, customer, storeCredit) } yield build(storeCredit) } // API routes - def createFromExtension(admin: User, accountId: Int, payload: CreateExtensionStoreCredit)( - implicit ec: EC, - db: DB, - ac: AC, - au: AU): DbResultT[Root] = + def createFromExtension( + admin: User, + accountId: Int, + payload: CreateExtensionStoreCredit)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[Root] = for { customer ← * <~ Users.mustFindByAccountId(accountId) scope ← * <~ Scope.resolveOverride(payload.scope) @@ -103,13 +100,15 @@ object StoreCreditService { custom = StoreCreditCustom(adminId = admin.accountId, metadata = payload.metadata) origin ← * <~ StoreCreditCustoms.create(custom) storeCredit ← * <~ StoreCredits.create( - StoreCredit(accountId = customer.accountId, - originType = StoreCredit.Custom, - originId = origin.id, - currency = payload.currency, - subTypeId = payload.subTypeId, - originalBalance = payload.amount, - scope = scope)) + StoreCredit( + accountId = customer.accountId, + originType = StoreCredit.Custom, + originId = origin.id, + currency = payload.currency, + subTypeId = payload.subTypeId, + originalBalance = payload.amount, + scope = scope + )) _ ← * <~ LogActivity().withScope(scope).scCreated(admin, customer, storeCredit) } yield build(storeCredit) @@ -118,17 +117,15 @@ object StoreCreditService { storeCredit ← * <~ StoreCredits.mustFindById404(id) } yield StoreCreditResponse.build(storeCredit) - def getByIdAndCustomer(storeCreditId: Int, customer: User)(implicit ec: EC, - db: DB): DbResultT[Root] = + def getByIdAndCustomer(storeCreditId: Int, customer: User)(implicit ec: EC, db: DB): DbResultT[Root] = for { storeCredit ← * <~ StoreCredits .findByIdAndAccountId(storeCreditId, customer.accountId) .mustFindOr(NotFoundFailure404(StoreCredit, storeCreditId)) } yield StoreCreditResponse.build(storeCredit) - def bulkUpdateStateByCsr( - payload: StoreCreditBulkUpdateStateByCsr, - admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[List[ItemResult]] = + def bulkUpdateStateByCsr(payload: StoreCreditBulkUpdateStateByCsr, + admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[List[ItemResult]] = for { response ← * <~ DbResultT.seqCollectFailures(payload.ids.map { id ⇒ val itemPayload = StoreCreditUpdateStateByCsr(payload.state, payload.reasonId) @@ -137,9 +134,9 @@ object StoreCreditService { }.toList) } yield response - def updateStateByCsr(id: Int, - payload: StoreCreditUpdateStateByCsr, - admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[Root] = + def updateStateByCsr(id: Int, payload: StoreCreditUpdateStateByCsr, admin: User)(implicit ec: EC, + db: DB, + ac: AC): DbResultT[Root] = for { storeCredit ← * <~ StoreCredits.mustFindById404(id) updated ← * <~ cancelOrUpdate(storeCredit, payload.state, payload.reasonId, admin) @@ -160,8 +157,7 @@ object StoreCreditService { upd ← * <~ StoreCredits.update(storeCredit, storeCredit.copy(state = newState, canceledReason = reasonId, - canceledAmount = - storeCredit.availableBalance.some)) + canceledAmount = storeCredit.availableBalance.some)) _ ← * <~ StoreCredits.cancelByCsr(storeCredit, admin) } yield upd diff --git a/phoenix-scala/phoenix/app/phoenix/services/account/AccountManager.scala b/phoenix-scala/phoenix/app/phoenix/services/account/AccountManager.scala index 418492f7d8..9d0d4f758c 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/account/AccountManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/account/AccountManager.scala @@ -21,26 +21,23 @@ object AccountManager { db: DB, ac: AC): DbResultT[Root] = for { - user ← * <~ Users.mustFindByAccountId(accountId) - updated ← * <~ Users.update(user, - user.copy(isDisabled = disabled, disabledBy = Some(actor.id))) - _ ← * <~ LogActivity().userDisabled(disabled, user, actor) + user ← * <~ Users.mustFindByAccountId(accountId) + updated ← * <~ Users.update(user, user.copy(isDisabled = disabled, disabledBy = Some(actor.id))) + _ ← * <~ LogActivity().userDisabled(disabled, user, actor) } yield build(updated) // TODO: add blacklistedReason later - def toggleBlacklisted(accountId: Int, - blacklisted: Boolean, - actor: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[Root] = + def toggleBlacklisted(accountId: Int, blacklisted: Boolean, actor: User)(implicit ec: EC, + db: DB, + ac: AC): DbResultT[Root] = for { user ← * <~ Users.mustFindByAccountId(accountId) - updated ← * <~ Users.update( - user, - user.copy(isBlacklisted = blacklisted, blacklistedBy = Some(actor.id))) + updated ← * <~ Users.update(user, + user.copy(isBlacklisted = blacklisted, blacklistedBy = Some(actor.id))) _ ← * <~ LogActivity().userBlacklisted(blacklisted, user, actor) } yield build(updated) - def resetPasswordSend( - email: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[ResetPasswordSendAnswer] = + def resetPasswordSend(email: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[ResetPasswordSendAnswer] = for { user ← * <~ Users .activeUserByEmail(Option(email)) @@ -59,16 +56,16 @@ object AccountManager { .findOrCreateExtended(UserPasswordResets.create(resetPwInstance)) (resetPw, foundOrCreated) = findOrCreate updatedResetPw ← * <~ (foundOrCreated match { - case Found ⇒ - UserPasswordResets.update(resetPw, resetPw.updateCode()) - case Created ⇒ DbResultT.good(resetPw) - }) + case Found ⇒ + UserPasswordResets.update(resetPw, resetPw.updateCode()) + case Created ⇒ DbResultT.good(resetPw) + }) _ ← * <~ LogActivity().userRemindPassword(user, updatedResetPw.code) } yield ResetPasswordSendAnswer(status = "ok") - def resetPassword( - code: String, - newPassword: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[ResetPasswordDoneAnswer] = { + def resetPassword(code: String, newPassword: String)(implicit ec: EC, + db: DB, + ac: AC): DbResultT[ResetPasswordDoneAnswer] = for { remind ← * <~ UserPasswordResets .findActiveByCode(code) @@ -77,31 +74,26 @@ object AccountManager { account ← * <~ Accounts.mustFindById404(user.accountId) accessMethod ← * <~ AccountAccessMethods .findOneByAccountIdAndName(account.id, "login") - .findOrCreate(AccountAccessMethods.create( - AccountAccessMethod.buildInitial(account.id))) + .findOrCreate(AccountAccessMethods.create(AccountAccessMethod.buildInitial(account.id))) _ ← * <~ Users.update(user, user.copy(isMigrated = false)) - _ ← * <~ UserPasswordResets.update(remind, - remind.copy(state = UserPasswordReset.PasswordRestored, - activatedAt = Instant.now.some)) - updatedAccess ← * <~ AccountAccessMethods.update(accessMethod, - accessMethod.updatePassword(newPassword)) - _ ← * <~ LogActivity().userPasswordReset(user) + _ ← * <~ UserPasswordResets.update( + remind, + remind.copy(state = UserPasswordReset.PasswordRestored, activatedAt = Instant.now.some)) + updatedAccess ← * <~ AccountAccessMethods.update(accessMethod, accessMethod.updatePassword(newPassword)) + _ ← * <~ LogActivity().userPasswordReset(user) } yield ResetPasswordDoneAnswer(status = "ok") - } - def getById(accountId: Int)(implicit ec: EC, db: DB): DbResultT[Root] = { + def getById(accountId: Int)(implicit ec: EC, db: DB): DbResultT[Root] = for { user ← * <~ Users.mustFindByAccountId(accountId) } yield build(user) - } def createUser(name: Option[String], email: Option[String], password: Option[String], context: AccountCreateContext, checkEmail: Boolean = true, - isMigrated: Boolean = false)(implicit ec: EC, db: DB): DbResultT[User] = { - + isMigrated: Boolean = false)(implicit ec: EC, db: DB): DbResultT[User] = for { scope ← * <~ Scopes.mustFindById404(context.scopeId) organization ← * <~ Organizations @@ -117,18 +109,17 @@ object AccountManager { } user ← * <~ Users.create( - User(accountId = account.id, email = email, name = name, isMigrated = isMigrated)) + User(accountId = account.id, email = email, name = name, isMigrated = isMigrated)) _ ← * <~ AccountOrganizations.create( - AccountOrganization(accountId = account.id, organizationId = organization.id)) + AccountOrganization(accountId = account.id, organizationId = organization.id)) _ ← * <~ context.roles.map { r ⇒ addRole(account, r, scope) } } yield user - } - def addRole(account: Account, role: String, scope: Scope)(implicit ec: EC): DbResultT[Unit] = { + def addRole(account: Account, role: String, scope: Scope)(implicit ec: EC): DbResultT[Unit] = //MAXDO Add claim check here. for { role ← * <~ Roles @@ -136,10 +127,8 @@ object AccountManager { .mustFindOr(RoleNotFound(role, scope.path)) _ ← * <~ AccountRoles.create(AccountRole(accountId = account.id, roleId = role.id)) } yield Unit - } - def getClaims(accountId: Int, scopeId: Int)(implicit ec: EC, - db: DB): DbResultT[Account.ClaimSet] = + def getClaims(accountId: Int, scopeId: Int)(implicit ec: EC, db: DB): DbResultT[Account.ClaimSet] = for { scope ← * <~ Scopes.mustFindById404(scopeId) accountRoles ← * <~ AccountRoles.findByAccountId(accountId).result diff --git a/phoenix-scala/phoenix/app/phoenix/services/activity/CartTailored.scala b/phoenix-scala/phoenix/app/phoenix/services/activity/CartTailored.scala index b73bdcb949..49d540d48c 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/activity/CartTailored.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/activity/CartTailored.scala @@ -97,8 +97,7 @@ object CartTailored { extends ActivityBase[CartPaymentMethodDeletedGiftCard] /* Cart Coupons */ - case class CartCouponAttached(cart: Cart, couponCode: CouponCode) - extends ActivityBase[CartCouponAttached] + case class CartCouponAttached(cart: Cart, couponCode: CouponCode) extends ActivityBase[CartCouponAttached] case class CartCouponDetached(cart: Cart) extends ActivityBase[CartCouponDetached] diff --git a/phoenix-scala/phoenix/app/phoenix/services/activity/CustomerGroupsTailored.scala b/phoenix-scala/phoenix/app/phoenix/services/activity/CustomerGroupsTailored.scala index 2f381b60e6..3c88804f79 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/activity/CustomerGroupsTailored.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/activity/CustomerGroupsTailored.scala @@ -20,17 +20,18 @@ object CustomerGroupsTailored { deletedAt: Option[Instant] = None) object CustomerGroupActivity { - def apply(group: CustomerGroup): CustomerGroupActivity = { - CustomerGroupActivity(id = group.id, - scope = group.scope, - createdBy = group.createdBy, - name = group.name, - customersCount = group.customersCount, - groupType = group.groupType, - updatedAt = group.updatedAt, - createdAt = group.createdAt, - deletedAt = group.deletedAt) - } + def apply(group: CustomerGroup): CustomerGroupActivity = + CustomerGroupActivity( + id = group.id, + scope = group.scope, + createdBy = group.createdBy, + name = group.name, + customersCount = group.customersCount, + groupType = group.groupType, + updatedAt = group.updatedAt, + createdAt = group.createdAt, + deletedAt = group.deletedAt + ) } case class CustomerGroupCreated(customerGroup: CustomerGroupActivity, admin: User) diff --git a/phoenix-scala/phoenix/app/phoenix/services/activity/CustomerTailored.scala b/phoenix-scala/phoenix/app/phoenix/services/activity/CustomerTailored.scala index 109fa57675..a8649a77e4 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/activity/CustomerTailored.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/activity/CustomerTailored.scala @@ -1,13 +1,12 @@ package phoenix.services.activity -import phoenix.responses.{AddressResponse, CreditCardsResponse, UserResponse, CustomerResponse} +import phoenix.responses.{AddressResponse, CreditCardsResponse, CustomerResponse, UserResponse} object CustomerTailored { case class CustomerCreated(admin: UserResponse.Root, user: CustomerResponse.Root) extends ActivityBase[CustomerCreated] - case class CustomerRegistered(user: CustomerResponse.Root) - extends ActivityBase[CustomerRegistered] + case class CustomerRegistered(user: CustomerResponse.Root) extends ActivityBase[CustomerRegistered] case class CustomerActivated(admin: UserResponse.Root, user: CustomerResponse.Root) extends ActivityBase[CustomerActivated] diff --git a/phoenix-scala/phoenix/app/phoenix/services/activity/OrderTailored.scala b/phoenix-scala/phoenix/app/phoenix/services/activity/OrderTailored.scala index 6b86e7f54b..72d2611ab0 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/activity/OrderTailored.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/activity/OrderTailored.scala @@ -10,9 +10,7 @@ import core.utils.Money.Currency object OrderTailored { - case class OrderStateChanged(admin: UserResponse.Root, - order: OrderResponse, - oldState: Order.State) + case class OrderStateChanged(admin: UserResponse.Root, order: OrderResponse, oldState: Order.State) extends ActivityBase[OrderStateChanged] case class OrderRemorsePeriodIncreased(admin: UserResponse.Root, @@ -26,8 +24,7 @@ object OrderTailored { extends ActivityBase[OrderBulkStateChanged] /* Order checkout & order payments */ - case class OrderCheckoutCompleted(order: OrderResponse) - extends ActivityBase[OrderCheckoutCompleted] + case class OrderCheckoutCompleted(order: OrderResponse) extends ActivityBase[OrderCheckoutCompleted] case class OrderCaptured(accountId: Int, orderNum: String, @@ -48,10 +45,7 @@ object OrderTailored { cardId: Int) extends ActivityBase[CreditCardAuthCompleted] - case class ApplePayAuthCompleted(accountId: Int, - stripeTokenId: String, - amount: Long, - currency: Currency) + case class ApplePayAuthCompleted(accountId: Int, stripeTokenId: String, amount: Long, currency: Currency) extends ActivityBase[ApplePayAuthCompleted] case class CreditCardChargeCompleted(accountId: Int, diff --git a/phoenix-scala/phoenix/app/phoenix/services/activity/ReturnTailored.scala b/phoenix-scala/phoenix/app/phoenix/services/activity/ReturnTailored.scala index cdcd5daba0..1af6cb6f8e 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/activity/ReturnTailored.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/activity/ReturnTailored.scala @@ -14,8 +14,7 @@ import phoenix.responses.UserResponse.{Root ⇒ UserResponse} object ReturnTailored { - case class ReturnCreated(admin: UserResponse, rma: ReturnResponse) - extends ActivityBase[ReturnCreated] + case class ReturnCreated(admin: UserResponse, rma: ReturnResponse) extends ActivityBase[ReturnCreated] case class ReturnStateChanged(admin: UserResponse, rma: ReturnResponse, oldState: Return.State) extends ActivityBase[ReturnStateChanged] @@ -25,16 +24,13 @@ object ReturnTailored { payload: ReturnShippingCostLineItemPayload) extends ActivityBase[ReturnShippingCostItemAdded] - case class ReturnSkuLineItemAdded(rma: Return, - reason: ReturnReason, - payload: ReturnSkuLineItemPayload) + case class ReturnSkuLineItemAdded(rma: Return, reason: ReturnReason, payload: ReturnSkuLineItemPayload) extends ActivityBase[ReturnSkuLineItemAdded] case class ReturnShippingCostItemDeleted(li: ReturnLineItem) extends ActivityBase[ReturnShippingCostItemDeleted] - case class ReturnSkuLineItemDeleted(li: ReturnLineItem) - extends ActivityBase[ReturnSkuLineItemDeleted] + case class ReturnSkuLineItemDeleted(li: ReturnLineItem) extends ActivityBase[ReturnSkuLineItemDeleted] case class ReturnSkuLineItemsDropped(skus: List[ReturnLineItemSku]) extends ActivityBase[ReturnSkuLineItemsDropped] diff --git a/phoenix-scala/phoenix/app/phoenix/services/activity/StoreAdminsTailored.scala b/phoenix-scala/phoenix/app/phoenix/services/activity/StoreAdminsTailored.scala index 0375e8c2b9..60ddd9e8d4 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/activity/StoreAdminsTailored.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/activity/StoreAdminsTailored.scala @@ -5,14 +5,11 @@ import phoenix.models.admin.AdminData object StoreAdminsTailored { - case class StoreAdminCreated(storeAdmin: User, admin: Option[User]) - extends ActivityBase[StoreAdminCreated] + case class StoreAdminCreated(storeAdmin: User, admin: Option[User]) extends ActivityBase[StoreAdminCreated] - case class StoreAdminUpdated(storeAdmin: User, admin: User) - extends ActivityBase[StoreAdminUpdated] + case class StoreAdminUpdated(storeAdmin: User, admin: User) extends ActivityBase[StoreAdminUpdated] - case class StoreAdminDeleted(storeAdmin: User, admin: User) - extends ActivityBase[StoreAdminDeleted] + case class StoreAdminDeleted(storeAdmin: User, admin: User) extends ActivityBase[StoreAdminDeleted] case class StoreAdminStateChanged(storeAdmin: User, oldState: AdminData.State, diff --git a/phoenix-scala/phoenix/app/phoenix/services/activity/UserTailored.scala b/phoenix-scala/phoenix/app/phoenix/services/activity/UserTailored.scala index e5e0bac4e6..469de648ec 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/activity/UserTailored.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/activity/UserTailored.scala @@ -17,8 +17,7 @@ object UserTailored { case class UserRemovedFromBlacklist(admin: UserResponse.Root, user: UserResponse.Root) extends ActivityBase[UserRemovedFromBlacklist] - case class UserEnabled(admin: UserResponse.Root, user: UserResponse.Root) - extends ActivityBase[UserEnabled] + case class UserEnabled(admin: UserResponse.Root, user: UserResponse.Root) extends ActivityBase[UserEnabled] case class UserDisabled(admin: UserResponse.Root, user: UserResponse.Root) extends ActivityBase[UserDisabled] diff --git a/phoenix-scala/phoenix/app/phoenix/services/actors/RemorseTimer.scala b/phoenix-scala/phoenix/app/phoenix/services/actors/RemorseTimer.scala index 64b1fd4074..894f30a539 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/actors/RemorseTimer.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/actors/RemorseTimer.scala @@ -43,22 +43,22 @@ class RemorseTimer(implicit db: DB, ec: EC, apis: Apis) extends Actor { private def logAcitvity(newState: Order.State, orders: Seq[Order]): DbResultT[Unit] = DbResultT .seqCollectFailures( - orders - .groupBy(_.scope) - .map { - case (scope, scopeOrders) ⇒ - val refNums = scopeOrders.map(_.referenceNumber) + orders + .groupBy(_.scope) + .map { + case (scope, scopeOrders) ⇒ + val refNums = scopeOrders.map(_.referenceNumber) - implicit val ac = EnrichedActivityContext(ctx = ActivityContext(userId = 1, - userType = "admin", - scope = scope, - transactionId = - letterify("?" * 5)), - producer = apis.kafka) + implicit val ac = EnrichedActivityContext(ctx = ActivityContext(userId = 1, + userType = "admin", + scope = scope, + transactionId = + letterify("?" * 5)), + producer = apis.kafka) - LogActivity().withScope(scope).orderBulkStateChanged(newState, refNums) - } - .toList) + LogActivity().withScope(scope).orderBulkStateChanged(newState, refNums) + } + .toList) .meh } diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderAssignmentsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderAssignmentsManager.scala index 98dd53b0a9..60cf3ccbb4 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderAssignmentsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderAssignmentsManager.scala @@ -21,7 +21,6 @@ object AmazonOrderAssignmentsManager extends AssignmentsManager[String, AmazonOr def fetchEntity(refNum: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[AmazonOrder] = AmazonOrders.mustFindOneOr(refNum) - def fetchSequence( - refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[AmazonOrder]] = + def fetchSequence(refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[AmazonOrder]] = AmazonOrders.filter(_.amazonOrderId.inSetBind(refNums)).result.dbresult } diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderWatchersManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderWatchersManager.scala index a768bab214..06646b7935 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderWatchersManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/AmazonOrderWatchersManager.scala @@ -21,7 +21,6 @@ object AmazonOrderWatchersManager extends AssignmentsManager[String, AmazonOrder def fetchEntity(refNum: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[AmazonOrder] = AmazonOrders.mustFindOneOr(refNum) - def fetchSequence( - refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[AmazonOrder]] = + def fetchSequence(refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[AmazonOrder]] = AmazonOrders.filter(_.amazonOrderId.inSetBind(refNums)).result.dbresult } diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/AssignmentsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/AssignmentsManager.scala index 82693207e0..c70f9a2196 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/AssignmentsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/AssignmentsManager.scala @@ -52,10 +52,9 @@ trait AssignmentsManager[K, M <: FoxModel[M]] { response = assignments.map((buildAssignment _).tupled) } yield response - def assign(key: K, payload: AssignmentPayload, originator: User)( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[TheResponse[Seq[Root]]] = + def assign(key: K, + payload: AssignmentPayload, + originator: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[TheResponse[Seq[Root]]] = for { // Validation + assign entity ← * <~ fetchEntity(key) @@ -142,18 +141,17 @@ trait AssignmentsManager[K, M <: FoxModel[M]] { val failureData = getFailureData(entityTrio, payload.storeAdminId, actionType) val batchMetadata = BatchMetadata(BatchMetadataSource(referenceType, successData, failureData)) - (successData, - TheResponse(result, errors = flattenErrors(failureData), batch = batchMetadata.some)) + (successData, TheResponse(result, errors = flattenErrors(failureData), batch = batchMetadata.some)) } // DbResultT builders private def build(entity: M, newAssigneeIds: Seq[Int]): Seq[Assignment] = newAssigneeIds.map( - adminId ⇒ - Assignment(assignmentType = assignmentType, - storeAdminId = adminId, - referenceType = referenceType, - referenceId = entity.id)) + adminId ⇒ + Assignment(assignmentType = assignmentType, + storeAdminId = adminId, + referenceType = referenceType, + referenceId = entity.id)) private def buildSeq(entities: Seq[M], storeAdminId: Int): Seq[Assignment] = for (e ← entities) @@ -166,9 +164,7 @@ trait AssignmentsManager[K, M <: FoxModel[M]] { // Batch metadata builders private def getSuccessData(trio: EntityTrio): SuccessData = searchKeys(trio.succeed) - private def getFailureData(trio: EntityTrio, - storeAdminId: Int, - actionType: ActionType): FailureData = { + private def getFailureData(trio: EntityTrio, storeAdminId: Int, actionType: ActionType): FailureData = { val notFoundFailures = trio.notFound.map { key ⇒ (key, NotFoundFailure404(referenceType, key).description) diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/CouponAssignmentsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/CouponAssignmentsManager.scala index c29a828aa8..16c6ef06d3 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/CouponAssignmentsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/CouponAssignmentsManager.scala @@ -20,12 +20,18 @@ object CouponAssignmentsManager extends AssignmentsManager[Int, ObjectForm] { def buildResponse(model: ObjectForm): Root = build(model) def fetchEntity(id: Int)(implicit ec: EC, db: DB, ac: AC): DbResultT[ObjectForm] = - ObjectForms.filter { f ⇒ - f.kind === ObjectForm.coupon && f.id === id - }.mustFindOneOr(NotFoundFailure404(Coupon, id)) + ObjectForms + .filter { f ⇒ + f.kind === ObjectForm.coupon && f.id === id + } + .mustFindOneOr(NotFoundFailure404(Coupon, id)) def fetchSequence(ids: Seq[Int])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[ObjectForm]] = - ObjectForms.filter { f ⇒ - f.kind === ObjectForm.coupon && f.id.inSet(ids) - }.filter(_.id.inSetBind(ids)).result.dbresult + ObjectForms + .filter { f ⇒ + f.kind === ObjectForm.coupon && f.id.inSet(ids) + } + .filter(_.id.inSetBind(ids)) + .result + .dbresult } diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/CustomerAssignmentsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/CustomerAssignmentsManager.scala index c71863f06b..bdbfaff124 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/CustomerAssignmentsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/CustomerAssignmentsManager.scala @@ -4,7 +4,7 @@ import core.db._ import phoenix.models.account._ import phoenix.models.activity.Dimension import phoenix.models.{Assignment, NotificationSubscription} -import phoenix.responses.UserResponse.{Root, build} +import phoenix.responses.UserResponse.{build, Root} import phoenix.utils.aliases._ import slick.jdbc.PostgresProfile.api._ diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/CustomerWatchersManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/CustomerWatchersManager.scala index 2e9db158e6..9929ddd33e 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/CustomerWatchersManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/CustomerWatchersManager.scala @@ -4,7 +4,7 @@ import core.db._ import phoenix.models.account._ import phoenix.models.activity.Dimension import phoenix.models.{Assignment, NotificationSubscription} -import phoenix.responses.UserResponse.{Root, build} +import phoenix.responses.UserResponse.{build, Root} import phoenix.utils.aliases._ import slick.jdbc.PostgresProfile.api._ diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/GiftCardAssignmentsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/GiftCardAssignmentsManager.scala index 8362f86478..d91f3b6271 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/GiftCardAssignmentsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/GiftCardAssignmentsManager.scala @@ -4,7 +4,7 @@ import core.db._ import phoenix.models.activity.Dimension import phoenix.models.payment.giftcard._ import phoenix.models.{Assignment, NotificationSubscription} -import phoenix.responses.GiftCardResponse.{Root, build} +import phoenix.responses.GiftCardResponse.{build, Root} import phoenix.utils.aliases._ import slick.jdbc.PostgresProfile.api._ @@ -20,7 +20,6 @@ object GiftCardAssignmentsManager extends AssignmentsManager[String, GiftCard] { def fetchEntity(code: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[GiftCard] = GiftCards.mustFindByCode(code) - def fetchSequence( - codes: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[GiftCard]] = + def fetchSequence(codes: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[GiftCard]] = GiftCards.filter(_.code.inSetBind(codes)).result.dbresult } diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/GiftCardWatchersManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/GiftCardWatchersManager.scala index 3f513b0649..92d999e850 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/GiftCardWatchersManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/GiftCardWatchersManager.scala @@ -20,7 +20,6 @@ object GiftCardWatchersManager extends AssignmentsManager[String, GiftCard] { def fetchEntity(code: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[GiftCard] = GiftCards.mustFindByCode(code) - def fetchSequence( - codes: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[GiftCard]] = + def fetchSequence(codes: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[GiftCard]] = GiftCards.filter(_.code.inSetBind(codes)).result.dbresult } diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/PromotionAssignmentsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/PromotionAssignmentsManager.scala index 92c5419dc4..195d4381be 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/PromotionAssignmentsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/PromotionAssignmentsManager.scala @@ -20,12 +20,18 @@ object PromotionAssignmentsManager extends AssignmentsManager[Int, ObjectForm] { def buildResponse(model: ObjectForm): Root = build(model) def fetchEntity(id: Int)(implicit ec: EC, db: DB, ac: AC): DbResultT[ObjectForm] = - ObjectForms.filter { f ⇒ - f.kind === ObjectForm.promotion && f.id === id - }.mustFindOneOr(NotFoundFailure404(Promotion, id)) + ObjectForms + .filter { f ⇒ + f.kind === ObjectForm.promotion && f.id === id + } + .mustFindOneOr(NotFoundFailure404(Promotion, id)) def fetchSequence(ids: Seq[Int])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[ObjectForm]] = - ObjectForms.filter { f ⇒ - f.kind === ObjectForm.promotion && f.id.inSet(ids) - }.filter(_.id.inSetBind(ids)).result.dbresult + ObjectForms + .filter { f ⇒ + f.kind === ObjectForm.promotion && f.id.inSet(ids) + } + .filter(_.id.inSetBind(ids)) + .result + .dbresult } diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/ReturnAssignmentsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/ReturnAssignmentsManager.scala index 17676e6e83..4b27be7552 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/ReturnAssignmentsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/ReturnAssignmentsManager.scala @@ -20,7 +20,6 @@ object ReturnAssignmentsManager extends AssignmentsManager[String, Return] { def fetchEntity(refNum: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[Return] = Returns.mustFindByRefNum(refNum) - def fetchSequence( - refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[Return]] = + def fetchSequence(refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[Return]] = Returns.filter(_.referenceNumber.inSetBind(refNums)).result.dbresult } diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/ReturnWatchersManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/ReturnWatchersManager.scala index 2f269a4fa0..feae88b85f 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/ReturnWatchersManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/ReturnWatchersManager.scala @@ -20,7 +20,6 @@ object ReturnWatchersManager extends AssignmentsManager[String, Return] { def fetchEntity(refNum: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[Return] = Returns.mustFindByRefNum(refNum) - def fetchSequence( - refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[Return]] = + def fetchSequence(refNums: Seq[String])(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[Return]] = Returns.filter(_.referenceNumber.inSetBind(refNums)).result.dbresult } diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/SkuAssignmentsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/SkuAssignmentsManager.scala index d67a205889..3cc7b7b100 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/SkuAssignmentsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/SkuAssignmentsManager.scala @@ -4,7 +4,7 @@ import core.db._ import phoenix.models.activity.Dimension import phoenix.models.inventory.{Sku, Skus} import phoenix.models.{Assignment, NotificationSubscription} -import phoenix.responses.SkuResponses.SkuHeadResponse.{Root, build} +import phoenix.responses.SkuResponses.SkuHeadResponse.{build, Root} import phoenix.utils.aliases._ import slick.jdbc.PostgresProfile.api._ diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/SkuWatchersManager.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/SkuWatchersManager.scala index c1abddffdc..6c644820c2 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/SkuWatchersManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/SkuWatchersManager.scala @@ -4,7 +4,7 @@ import core.db._ import phoenix.models.activity.Dimension import phoenix.models.inventory.{Sku, Skus} import phoenix.models.{Assignment, NotificationSubscription} -import phoenix.responses.SkuResponses.SkuHeadResponse.{Root, build} +import phoenix.responses.SkuResponses.SkuHeadResponse.{build, Root} import phoenix.utils.aliases._ import slick.jdbc.PostgresProfile.api._ diff --git a/phoenix-scala/phoenix/app/phoenix/services/assignments/package.scala b/phoenix-scala/phoenix/app/phoenix/services/assignments/package.scala index 0c27d060bf..a4a58a7abf 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/assignments/package.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/assignments/package.scala @@ -10,8 +10,7 @@ package object assignments { def subscribe[K, M <: FoxModel[M]]( manager: AssignmentsManager[K, M], adminIds: Seq[Int], - objectIds: Seq[String])(implicit ec: EC): DbResultT[TheResponse[Option[Int]]] = { - + objectIds: Seq[String])(implicit ec: EC): DbResultT[TheResponse[Option[Int]]] = if (objectIds.nonEmpty) NotificationManager.subscribe(adminIds = adminIds, dimension = manager.notifyDimension, @@ -19,13 +18,10 @@ package object assignments { objectIds = objectIds) else DbResultT.good(TheResponse(None)) - } - - def unsubscribe[K, M <: FoxModel[M]]( - manager: AssignmentsManager[K, M], - adminIds: Seq[Int], - objectIds: Seq[String])(implicit ec: EC): DbResultT[Unit] = { + def unsubscribe[K, M <: FoxModel[M]](manager: AssignmentsManager[K, M], + adminIds: Seq[Int], + objectIds: Seq[String])(implicit ec: EC): DbResultT[Unit] = if (objectIds.nonEmpty) NotificationManager.unsubscribe(adminIds = adminIds, dimension = manager.notifyDimension, @@ -33,30 +29,25 @@ package object assignments { objectIds = objectIds) else DbResultT.unit - } // Activity logger helpers def logBulkAssign[K, M <: FoxModel[M]](manager: AssignmentsManager[K, M], originator: User, admin: User, - keys: Seq[String])(implicit ec: EC, ac: AC) = { - + keys: Seq[String])(implicit ec: EC, ac: AC) = if (keys.nonEmpty) LogActivity() .bulkAssigned(originator, admin, keys, manager.assignmentType, manager.referenceType) else DbResultT.unit - } def logBulkUnassign[K, M <: FoxModel[M]](manager: AssignmentsManager[K, M], originator: User, admin: User, - keys: Seq[String])(implicit ec: EC, ac: AC) = { - + keys: Seq[String])(implicit ec: EC, ac: AC) = if (keys.nonEmpty) LogActivity() .bulkUnassigned(originator, admin, keys, manager.assignmentType, manager.referenceType) else DbResultT.unit - } } diff --git a/phoenix-scala/phoenix/app/phoenix/services/auth/GoogleOauth.scala b/phoenix-scala/phoenix/app/phoenix/services/auth/GoogleOauth.scala index 2741c93ed4..083e5dd24f 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/auth/GoogleOauth.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/auth/GoogleOauth.scala @@ -20,9 +20,8 @@ class GoogleOauthUser(options: GoogleOauthOptions)(implicit ec: EC, db: DB, ac: with GoogleProvider { def createCustomerByUserInfo(userInfo: UserInfo): DbResultT[User] = { - val context = AccountCreateContext(roles = List(options.roleName), - org = options.orgName, - scopeId = options.scopeId) + val context = + AccountCreateContext(roles = List(options.roleName), org = options.orgName, scopeId = options.scopeId) val payload = CreateCustomerPayload(email = userInfo.email, name = userInfo.name.some) @@ -72,9 +71,8 @@ class GoogleOauthUser(options: GoogleOauthOptions)(implicit ec: EC, db: DB, ac: scope ← * <~ scopeDomainOpt.map { scopeDomain ⇒ Scopes.mustFindById404(scopeDomain.scopeId) } - claims ← * <~ AccountManager.getClaims(account.id, - scope.map(_.id).getOrElse(options.scopeId)) - token ← * <~ UserToken.fromUserAccount(user, account, claims) + claims ← * <~ AccountManager.getClaims(account.id, scope.map(_.id).getOrElse(options.scopeId)) + token ← * <~ UserToken.fromUserAccount(user, account, claims) } yield token def findAccount(user: User): DbResultT[Account] = Accounts.mustFindById404(user.accountId) @@ -84,13 +82,15 @@ object GoogleOauth { def oauthServiceFromConfig(configUser: FoxConfig.User)(implicit ec: EC, db: DB, ac: AC) = { - val opts = GoogleOauthOptions(roleName = configUser.role, - orgName = configUser.org, - scopeId = configUser.scopeId, - clientId = configUser.oauth.google.clientId, - clientSecret = configUser.oauth.google.clientSecret, - redirectUri = configUser.oauth.google.redirectUri, - hostedDomain = configUser.oauth.google.hostedDomain) + val opts = GoogleOauthOptions( + roleName = configUser.role, + orgName = configUser.org, + scopeId = configUser.scopeId, + clientId = configUser.oauth.google.clientId, + clientSecret = configUser.oauth.google.clientSecret, + redirectUri = configUser.oauth.google.redirectUri, + hostedDomain = configUser.oauth.google.hostedDomain + ) new GoogleOauthUser(opts) } diff --git a/phoenix-scala/phoenix/app/phoenix/services/auth/Oauth.scala b/phoenix-scala/phoenix/app/phoenix/services/auth/Oauth.scala index b45e43c1c2..35f0b338df 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/auth/Oauth.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/auth/Oauth.scala @@ -32,8 +32,7 @@ object OauthDirectives { } } -trait OauthService[M] { - this: Oauth ⇒ +trait OauthService[M] { this: Oauth ⇒ def createCustomerByUserInfo(info: UserInfo): DbResultT[M] def createAdminByUserInfo(info: UserInfo): DbResultT[M] @@ -45,11 +44,9 @@ trait OauthService[M] { 1. Exchange code to access token 2. Get base user info: email and name */ - def fetchUserInfoFromCode(oauthResponse: OauthCallbackResponse)( - implicit ec: EC): DbResultT[UserInfo] = { + def fetchUserInfoFromCode(oauthResponse: OauthCallbackResponse)(implicit ec: EC): DbResultT[UserInfo] = for { - code ← DbResultT.fromEither( - oauthResponse.getCode.leftMap(t ⇒ GeneralFailure(t.toString).single)) + code ← DbResultT.fromEither(oauthResponse.getCode.leftMap(t ⇒ GeneralFailure(t.toString).single)) accessTokenResp ← * <~ this .accessToken(code) .leftMap(t ⇒ GeneralFailure(t.toString).single) @@ -59,12 +56,10 @@ trait OauthService[M] { .leftMap(t ⇒ GeneralFailure(t.toString).single) .value } yield info - } - def findOrCreateUserFromInfo(userInfo: UserInfo, createByUserInfo: (UserInfo) ⇒ DbResultT[M])( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[(M, Account)] = + def findOrCreateUserFromInfo( + userInfo: UserInfo, + createByUserInfo: (UserInfo) ⇒ DbResultT[M])(implicit ec: EC, db: DB, ac: AC): DbResultT[(M, Account)] = for { user ← * <~ findByEmail(userInfo.email).findOrCreate(createByUserInfo(userInfo)) account ← * <~ findAccount(user) @@ -76,10 +71,9 @@ trait OauthService[M] { 3. FindOrCreate 4. respondWithToken */ - def oauthCallback(oauthResponse: OauthCallbackResponse, - createByUserInfo: (UserInfo) ⇒ DbResultT[M])(implicit ec: EC, - db: DB, - ac: AC): DbResultT[Token] = + def oauthCallback( + oauthResponse: OauthCallbackResponse, + createByUserInfo: (UserInfo) ⇒ DbResultT[M])(implicit ec: EC, db: DB, ac: AC): DbResultT[Token] = for { info ← * <~ fetchUserInfoFromCode(oauthResponse) userAccount ← * <~ findOrCreateUserFromInfo(info, createByUserInfo) @@ -87,8 +81,7 @@ trait OauthService[M] { token ← * <~ createToken(user, account, info) } yield token - def customerCallback( - oauthResponse: OauthCallbackResponse)(implicit ec: EC, db: DB, ac: AC): Route = + def customerCallback(oauthResponse: OauthCallbackResponse)(implicit ec: EC, db: DB, ac: AC): Route = commonCallback(createCustomerByUserInfo, Uri./)(oauthResponse) def adminCallback(oauthResponse: OauthCallbackResponse)(implicit ec: EC, db: DB, ac: AC): Route = @@ -97,12 +90,11 @@ trait OauthService[M] { private def commonCallback(createByUserInfo: UserInfo ⇒ DbResultT[M], redirectUri: Uri)( oauthResponse: OauthCallbackResponse)(implicit ec: EC, db: DB, ac: AC): Route = // TODO: rethink discarding warnings here @michalrus - onSuccess(oauthCallback(oauthResponse, createByUserInfo).runDBIO.runEmptyA.value) { - tokenOrFailure ⇒ - tokenOrFailure - .flatMap(Authenticator.oauthTokenLoginResponse(redirectUri)) - .fold({ f ⇒ - complete(renderFailure(f)) - }, identity) + onSuccess(oauthCallback(oauthResponse, createByUserInfo).runDBIO.runEmptyA.value) { tokenOrFailure ⇒ + tokenOrFailure + .flatMap(Authenticator.oauthTokenLoginResponse(redirectUri)) + .fold({ f ⇒ + complete(renderFailure(f)) + }, identity) } } diff --git a/phoenix-scala/phoenix/app/phoenix/services/carts/CartCreator.scala b/phoenix-scala/phoenix/app/phoenix/services/carts/CartCreator.scala index e7d951855d..cae8bc81eb 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/carts/CartCreator.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/carts/CartCreator.scala @@ -27,8 +27,7 @@ object CartCreator { case _ ⇒ ??? // FIXME: the hell‽ @michalrus } - def createCartForCustomer(accountId: Int)(implicit ctx: OC, - apis: Apis): DbResultT[CartResponse] = + def createCartForCustomer(accountId: Int)(implicit ctx: OC, apis: Apis): DbResultT[CartResponse] = for { customer ← * <~ Users.mustFindByAccountId(accountId) fullCart ← * <~ CartQueries.findOrCreateCartByAccountInner(customer, Some(admin)) @@ -39,10 +38,10 @@ object CartCreator { account ← * <~ Accounts.create(Account()) guest ← * <~ Users.create(User(accountId = account.id, email = email.some)) custData ← * <~ CustomersData.create( - CustomerData(userId = guest.id, - accountId = account.id, - isGuest = true, - scope = Scope.current)) + CustomerData(userId = guest.id, + accountId = account.id, + isGuest = true, + scope = Scope.current)) scope ← * <~ Scope.resolveOverride(payload.scope) cart ← * <~ Carts.create(Cart(accountId = account.id, scope = scope)) _ ← * <~ LogActivity() diff --git a/phoenix-scala/phoenix/app/phoenix/services/carts/CartPaymentUpdater.scala b/phoenix-scala/phoenix/app/phoenix/services/carts/CartPaymentUpdater.scala index 4aae1a0ef1..a7a8390722 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/carts/CartPaymentUpdater.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/carts/CartPaymentUpdater.scala @@ -30,11 +30,9 @@ object CartPaymentUpdater { type TheFullCart = DbResultT[TheResponse[CartResponse]] - def addGiftCard(originator: User, payload: GiftCardPayment, refNum: Option[String] = None)( - implicit ec: EC, - db: DB, - ac: AC, - ctx: OC): TheFullCart = + def addGiftCard(originator: User, + payload: GiftCardPayment, + refNum: Option[String] = None)(implicit ec: EC, db: DB, ac: AC, ctx: OC): TheFullCart = for { cart ← * <~ getCartByOriginator(originator, refNum) result ← * <~ validGiftCardWithAmount(payload) @@ -42,18 +40,15 @@ object CartPaymentUpdater { _ ← * <~ OrderPayments .byCartAndGiftCard(cart, gc) .mustNotFindOneOr(GiftCardPaymentAlreadyAdded(cart.refNum, payload.code)) - _ ← * <~ OrderPayments.create( - OrderPayment.build(gc).copy(cordRef = cart.refNum, amount = amount.some)) + _ ← * <~ OrderPayments.create(OrderPayment.build(gc).copy(cordRef = cart.refNum, amount = amount.some)) resp ← * <~ CartResponse.buildRefreshed(cart) valid ← * <~ CartValidator(cart).validate() _ ← * <~ LogActivity().orderPaymentMethodAddedGc(originator, resp, gc, amount) } yield TheResponse.validated(resp, valid) - def editGiftCard(originator: User, payload: GiftCardPayment, refNum: Option[String] = None)( - implicit ec: EC, - db: DB, - ac: AC, - ctx: OC): TheFullCart = + def editGiftCard(originator: User, + payload: GiftCardPayment, + refNum: Option[String] = None)(implicit ec: EC, db: DB, ac: AC, ctx: OC): TheFullCart = for { cart ← * <~ getCartByOriginator(originator, refNum) result ← * <~ validGiftCardWithAmount(payload) @@ -86,15 +81,12 @@ object CartPaymentUpdater { case _ ⇒ gc.availableBalance } - def addStoreCredit(originator: User, payload: StoreCreditPayment, refNum: Option[String] = None)( - implicit ec: EC, - db: DB, - ac: AC, - ctx: OC): TheFullCart = { + def addStoreCredit(originator: User, + payload: StoreCreditPayment, + refNum: Option[String] = None)(implicit ec: EC, db: DB, ac: AC, ctx: OC): TheFullCart = { def updateSC(has: Long, want: Long, cart: Cart, storeCredits: List[StoreCredit]) = if (has < want) { - DbResultT.failure( - CustomerHasInsufficientStoreCredit(id = cart.accountId, has = has, want = want)) + DbResultT.failure(CustomerHasInsufficientStoreCredit(id = cart.accountId, has = has, want = want)) } else { def payments = StoreCredit.processFifo(storeCredits, want).map { case (sc, amount) ⇒ @@ -122,10 +114,9 @@ object CartPaymentUpdater { } yield TheResponse.validated(response, validation) } - def addCreditCard( - originator: User, - id: Int, - refNum: Option[String] = None)(implicit ec: EC, db: DB, ac: AC, ctx: OC): TheFullCart = + def addCreditCard(originator: User, + id: Int, + refNum: Option[String] = None)(implicit ec: EC, db: DB, ac: AC, ctx: OC): TheFullCart = for { cart ← * <~ getCartByOriginator(originator, refNum) cc ← * <~ CreditCards.mustFindById400(id) @@ -133,16 +124,14 @@ object CartPaymentUpdater { _ ← * <~ cc.mustBeInWallet region ← * <~ Regions.findOneById(cc.address.regionId).safeGet _ ← * <~ OrderPayments.filter(_.cordRef === cart.refNum).creditCards.delete - _ ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = None)) - valid ← * <~ CartValidator(cart).validate() - resp ← * <~ CartResponse.buildRefreshed(cart) - _ ← * <~ LogActivity().orderPaymentMethodAddedCc(originator, resp, cc, region) + _ ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = None)) + valid ← * <~ CartValidator(cart).validate() + resp ← * <~ CartResponse.buildRefreshed(cart) + _ ← * <~ LogActivity().orderPaymentMethodAddedCc(originator, resp, cc, region) } yield TheResponse.validated(resp, valid) - def deleteCreditCard( - originator: User, - refNum: Option[String] = None)(implicit ec: EC, db: DB, ac: AC, ctx: OC): TheFullCart = + def deleteCreditCard(originator: User, + refNum: Option[String] = None)(implicit ec: EC, db: DB, ac: AC, ctx: OC): TheFullCart = deleteCreditCardOrStoreCredit(originator, refNum, PaymentMethod.CreditCard) def deleteStoreCredit( @@ -166,11 +155,9 @@ object CartPaymentUpdater { _ ← * <~ LogActivity().orderPaymentMethodDeleted(originator, resp, pmt) } yield TheResponse.validated(resp, valid) - def deleteGiftCard(originator: User, code: String, refNum: Option[String] = None)( - implicit ec: EC, - db: DB, - ac: AC, - ctx: OC): TheFullCart = + def deleteGiftCard(originator: User, + code: String, + refNum: Option[String] = None)(implicit ec: EC, db: DB, ac: AC, ctx: OC): TheFullCart = for { cart ← * <~ getCartByOriginator(originator, refNum) giftCard ← * <~ GiftCards.mustFindByCode(code) @@ -179,8 +166,8 @@ object CartPaymentUpdater { .filter(_.cordRef === cart.refNum) .giftCards .deleteAll(onSuccess = CartResponse.buildRefreshed(cart), - onFailure = DbResultT.failure( - OrderPaymentNotFoundFailure(PaymentMethod.GiftCard))) + onFailure = + DbResultT.failure(OrderPaymentNotFoundFailure(PaymentMethod.GiftCard))) updatedCart ← * <~ getCartByOriginator(originator, refNum) validated ← * <~ CartValidator(updatedCart).validate() _ ← * <~ LogActivity().orderPaymentMethodDeletedGc(originator, deleteRes, giftCard) @@ -196,14 +183,13 @@ object CartPaymentUpdater { // create apple charge applePayment ← * <~ ApplePayments.create( - ApplePayment(accountId = originator.accountId, - stripeTokenId = payload.stripeToken)) + ApplePayment(accountId = originator.accountId, stripeTokenId = payload.stripeToken)) _ ← * <~ OrderPayments.create( - OrderPayment(cordRef = cart.refNum, - amount = None, - paymentMethodType = ApplePay, - paymentMethodId = applePayment.id) + OrderPayment(cordRef = cart.refNum, + amount = None, + paymentMethodType = ApplePay, + paymentMethodId = applePayment.id) ) valid ← * <~ CartValidator(cart).validate() diff --git a/phoenix-scala/phoenix/app/phoenix/services/carts/CartPromotionUpdater.scala b/phoenix-scala/phoenix/app/phoenix/services/carts/CartPromotionUpdater.scala index d1ed4ba101..8b0cb5b590 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/carts/CartPromotionUpdater.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/carts/CartPromotionUpdater.scala @@ -47,8 +47,7 @@ object CartPromotionUpdater { clearStalePromotions(cart) >> DbResultT.failures(es) } - private def tryReadjust(cart: Cart, - failFatally: Boolean /* FIXME with the new foxy monad @michalrus */ )( + private def tryReadjust(cart: Cart, failFatally: Boolean /* FIXME with the new foxy monad @michalrus */ )( implicit ec: EC, apis: Apis, db: DB, @@ -68,13 +67,10 @@ object CartPromotionUpdater { CartLineItemAdjustments.findByCordRef(cart.referenceNumber).delete.dbresult.void private def filterPromotionsUsingCustomerGroups[L[_]: TraverseFilter](user: User)( - promos: L[Promotion])(implicit ec: EC, - apis: Apis, - ctx: OC, - db: DB): DbResultT[L[Promotion]] = { + promos: L[Promotion])(implicit ec: EC, apis: Apis, ctx: OC, db: DB): DbResultT[L[Promotion]] = { implicit val formats = JsonFormatters.phoenixFormats - def isApplicable(promotion: Promotion): DbResultT[Boolean] = { + def isApplicable(promotion: Promotion): DbResultT[Boolean] = for { promoForm ← * <~ ObjectForms.mustFindById404(promotion.formId) promoShadow ← * <~ ObjectShadows.mustFindById404(promotion.shadowId) @@ -83,26 +79,23 @@ object CartPromotionUpdater { case JNothing | JNull ⇒ None case cgis ⇒ cgis.extractOpt[Set[Int]] } - result ← * <~ customerGroupIdsO.fold(DbResultT.pure(true))( - GroupMemberManager.isMemberOfAny(_, user)) + result ← * <~ customerGroupIdsO.fold(DbResultT.pure(true))(GroupMemberManager.isMemberOfAny(_, user)) } yield result - } promos.filterA(isApplicable) } - private def findApplicablePromotion( - cart: Cart, - failFatally: Boolean /* FIXME with the new foxy monad @michalrus */ )( + private def findApplicablePromotion(cart: Cart, + failFatally: Boolean /* FIXME with the new foxy monad @michalrus */ )( implicit ec: EC, apis: Apis, au: AU, db: DB, ctx: OC): DbResultT[(OrderPromotion, Promotion, Seq[CartLineItemAdjustment])] = findAppliedCouponPromotion(cart, failFatally).handleErrorWith( - couponErr ⇒ - findApplicableAutoAppliedPromotion(cart).handleErrorWith(_ ⇒ // Any error? @michalrus - DbResultT.failures(couponErr))) + couponErr ⇒ + findApplicableAutoAppliedPromotion(cart).handleErrorWith(_ ⇒ // Any error? @michalrus + DbResultT.failures(couponErr))) private def findAppliedCouponPromotion( cart: Cart, @@ -111,7 +104,7 @@ object CartPromotionUpdater { au: AU, apis: Apis, db: DB, - ctx: OC): DbResultT[(OrderPromotion, Promotion, Seq[CartLineItemAdjustment])] = { + ctx: OC): DbResultT[(OrderPromotion, Promotion, Seq[CartLineItemAdjustment])] = for { orderPromo ← * <~ OrderPromotions .filterByCordRef(cart.refNum) @@ -131,7 +124,6 @@ object CartPromotionUpdater { .getOrElse(DbResultT.failure(OrderHasNoPromotions)) // TODO: no function for that? Seems useful? @michalrus adjustments ← * <~ getAdjustmentsForPromotion(cart, promotion, failFatally) } yield (orderPromo, promotion, adjustments) - } private def findApplicableAutoAppliedPromotion(cart: Cart)( implicit ec: EC, @@ -148,8 +140,7 @@ object CartPromotionUpdater { .map(_.toStream) >>= filterPromotionsUsingCustomerGroups(user) allWithAdjustments ← * <~ all.toList .map(promo ⇒ - getAdjustmentsForPromotion(cart, promo, failFatally = true).map( - (promo, _))) + getAdjustmentsForPromotion(cart, promo, failFatally = true).map((promo, _))) .ignoreFailures .ensure(OrderHasNoPromotions.single)(_.nonEmpty) (bestPromo, bestAdjustments) = allWithAdjustments.maxBy { @@ -285,17 +276,21 @@ object CartPromotionUpdater { shipTotal ← * <~ CartTotaler.shippingTotal(cart) cartWithTotalsUpdated = cart.copy(subTotal = subTotal, shippingTotal = shipTotal) dqLineItems = lineItems.map { li ⇒ - DqLineItem(skuCode = li.sku.code, - productId = li.productForm.id, - price = li.price, - lineItemType = if (li.isGiftCard) DqGiftCardLineItem else DqRegularLineItem, - lineItemReferenceNumber = li.lineItemReferenceNumber) + DqLineItem( + skuCode = li.sku.code, + productId = li.productForm.id, + price = li.price, + lineItemType = if (li.isGiftCard) DqGiftCardLineItem else DqRegularLineItem, + lineItemReferenceNumber = li.lineItemReferenceNumber + ) } - input = DiscountInput(promotionShadowId = promo.id, - cartRefNum = cart.referenceNumber, - customerAccountId = cart.accountId, - lineItems = dqLineItems, - shippingCost = shippingMethod.map(_.price)) + input = DiscountInput( + promotionShadowId = promo.id, + cartRefNum = cart.referenceNumber, + customerAccountId = cart.accountId, + lineItems = dqLineItems, + shippingCost = shippingMethod.map(_.price) + ) _ ← * <~ qualifier.check(input) offerResults ← * <~ offer.adjust(input) } yield offerResults.map(CartLineItemAdjustment.fromOfferResult) diff --git a/phoenix-scala/phoenix/app/phoenix/services/carts/CartQueries.scala b/phoenix-scala/phoenix/app/phoenix/services/carts/CartQueries.scala index 452f2c1189..775e88bb86 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/carts/CartQueries.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/carts/CartQueries.scala @@ -36,24 +36,22 @@ object CartQueries extends CordQueries { resp ← * <~ LineItemUpdater.runUpdates(cart, None) // FIXME: so costly… @michalrus } yield resp - def findOrCreateCartByAccount(customer: User, - context: ObjectContext, - admin: Option[User] = None)(implicit ec: EC, - db: DB, - ac: AC, - ctx: OC, - apis: Apis, - au: AU): DbResultT[CartResponse] = + def findOrCreateCartByAccount(customer: User, context: ObjectContext, admin: Option[User] = None)( + implicit ec: EC, + db: DB, + ac: AC, + ctx: OC, + apis: Apis, + au: AU): DbResultT[CartResponse] = findOrCreateCartByAccountInner(customer, admin) - def findOrCreateCartByAccountId(accountId: Int, - context: ObjectContext, - admin: Option[User] = None)(implicit ec: EC, - db: DB, - ac: AC, - ctx: OC, - apis: Apis, - au: AU): DbResultT[CartResponse] = + def findOrCreateCartByAccountId(accountId: Int, context: ObjectContext, admin: Option[User] = None)( + implicit ec: EC, + db: DB, + ac: AC, + ctx: OC, + apis: Apis, + au: AU): DbResultT[CartResponse] = for { customer ← * <~ Users.mustFindByAccountId(accountId) fullOrder ← * <~ findOrCreateCartByAccountInner(customer, admin) @@ -71,13 +69,12 @@ object CartQueries extends CordQueries { .findByAccountId(customer.accountId) .one .findOrCreateExtended( - Carts.create(Cart(accountId = customer.accountId, scope = Scope.current))) + Carts.create(Cart(accountId = customer.accountId, scope = Scope.current))) (cart, foundOrCreated) = result resp ← if (foundOrCreated == Created) for { fullCart ← * <~ CartResponse.fromCart(cart, grouped, au.isGuest) _ ← * <~ LogActivity().cartCreated(admin, fullCart) } yield TheResponse(fullCart) else LineItemUpdater.runUpdates(cart, None) // FIXME: so costly… @michalrus - } yield - resp.result // FIXME: discarding warnings until we get rid of TheResponse completely @michalrus + } yield resp.result // FIXME: discarding warnings until we get rid of TheResponse completely @michalrus } diff --git a/phoenix-scala/phoenix/app/phoenix/services/carts/CartShippingAddressUpdater.scala b/phoenix-scala/phoenix/app/phoenix/services/carts/CartShippingAddressUpdater.scala index aac2d2c683..8ee8e5c0fb 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/carts/CartShippingAddressUpdater.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/carts/CartShippingAddressUpdater.scala @@ -23,9 +23,7 @@ object CartShippingAddressUpdater { def mustFindShipAddressForCart(cart: Cart)(implicit ec: EC): DbResultT[OrderShippingAddress] = OrderShippingAddresses.findByOrderRef(cart.refNum).mustFindOneOr(NoShipAddress(cart.refNum)) - def createShippingAddressFromAddressId(originator: User, - addressId: Int, - refNum: Option[String] = None)( + def createShippingAddressFromAddressId(originator: User, addressId: Int, refNum: Option[String] = None)( implicit ec: EC, db: DB, ac: AC, diff --git a/phoenix-scala/phoenix/app/phoenix/services/carts/CartShippingMethodUpdater.scala b/phoenix-scala/phoenix/app/phoenix/services/carts/CartShippingMethodUpdater.scala index 841ff0c96a..61b7936515 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/carts/CartShippingMethodUpdater.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/carts/CartShippingMethodUpdater.scala @@ -34,9 +34,9 @@ object CartShippingMethodUpdater { .update(None) _ ← * <~ OrderShippingMethods.findByOrderRef(cart.refNum).delete orderShipMethod ← * <~ OrderShippingMethods.create( - OrderShippingMethod(cordRef = cart.refNum, - shippingMethodId = shippingMethod.id, - price = shippingMethod.price)) + OrderShippingMethod(cordRef = cart.refNum, + shippingMethodId = shippingMethod.id, + price = shippingMethod.price)) _ ← * <~ Shipments .filter(_.cordRef === cart.refNum) .map(_.orderShippingMethodId) diff --git a/phoenix-scala/phoenix/app/phoenix/services/carts/CartTotaler.scala b/phoenix-scala/phoenix/app/phoenix/services/carts/CartTotaler.scala index 35fcd336e6..bf291231cd 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/carts/CartTotaler.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/carts/CartTotaler.scala @@ -16,13 +16,12 @@ object CartTotaler { case class Totals(subTotal: Long, taxes: Long, shipping: Long, adjustments: Long, total: Long) object Totals { - def build(subTotal: Long, shipping: Long, adjustments: Long, taxes: Long): Totals = { + def build(subTotal: Long, shipping: Long, adjustments: Long, taxes: Long): Totals = Totals(subTotal = subTotal, taxes = taxes, shipping = shipping, adjustments = adjustments, total = (subTotal + taxes + shipping - adjustments).zeroIfNegative) - } def empty: Totals = Totals(0, 0, 0, 0, 0) } @@ -71,10 +70,7 @@ object CartTotaler { sub ← * <~ subTotal(cart) ship ← * <~ shippingTotal(cart) adj ← * <~ adjustmentsTotal(cart) - tax ← * <~ taxesTotal(cordRef = cart.refNum, - subTotal = sub, - shipping = ship, - adjustments = adj) + tax ← * <~ taxesTotal(cordRef = cart.refNum, subTotal = sub, shipping = ship, adjustments = adj) } yield Totals.build(subTotal = sub, shipping = ship, adjustments = adj, taxes = tax) def saveTotals(cart: Cart)(implicit ec: EC): DbResultT[Cart] = diff --git a/phoenix-scala/phoenix/app/phoenix/services/carts/package.scala b/phoenix-scala/phoenix/app/phoenix/services/carts/package.scala index 59441bfaca..89df51f22f 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/carts/package.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/carts/package.scala @@ -7,9 +7,8 @@ import phoenix.models.cord._ package object carts { - def getCartByOriginator(originator: User, refNum: Option[String] = None)( - implicit ec: EC, - db: DB): DbResultT[Cart] = + def getCartByOriginator(originator: User, refNum: Option[String] = None)(implicit ec: EC, + db: DB): DbResultT[Cart] = (originator, refNum) match { case (_, Some(ref)) ⇒ Carts.mustFindByRefNum(ref) diff --git a/phoenix-scala/phoenix/app/phoenix/services/category/CategoryManager.scala b/phoenix-scala/phoenix/app/phoenix/services/category/CategoryManager.scala index de2b2b0dec..70f3922a44 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/category/CategoryManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/category/CategoryManager.scala @@ -36,17 +36,14 @@ object CategoryManager { shadow ← * <~ ObjectShadows.mustFindById404(category.shadowId) } yield CategoryShadowResponse.build(shadow) - def getCategory(categoryId: Int, contextName: String)( - implicit ec: EC, - db: DB): DbResultT[FullCategoryResponse.Root] = - getCategoryFull(categoryId, contextName).map(c ⇒ - FullCategoryResponse.build(c.category, c.form, c.shadow)) + def getCategory(categoryId: Int, contextName: String)(implicit ec: EC, + db: DB): DbResultT[FullCategoryResponse.Root] = + getCategoryFull(categoryId, contextName).map(c ⇒ FullCategoryResponse.build(c.category, c.form, c.shadow)) - def createCategory(admin: User, payload: CreateFullCategory, contextName: String)( - implicit ec: EC, - db: DB, - ac: AC, - au: AU): DbResultT[FullCategoryResponse.Root] = + def createCategory( + admin: User, + payload: CreateFullCategory, + contextName: String)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[FullCategoryResponse.Root] = for { scope ← * <~ Scope.resolveOverride(payload.scope) context ← * <~ contextByName(contextName) @@ -60,11 +57,10 @@ object CategoryManager { .fullCategoryCreated(Some(admin), response, ObjectContextResponse.build(context)) } yield response - def updateCategory( - admin: User, - categoryId: Int, - payload: UpdateFullCategory, - contextName: String)(implicit ec: EC, db: DB, ac: AC): DbResultT[FullCategoryResponse.Root] = + def updateCategory(admin: User, categoryId: Int, payload: UpdateFullCategory, contextName: String)( + implicit ec: EC, + db: DB, + ac: AC): DbResultT[FullCategoryResponse.Root] = for { context ← * <~ contextByName(contextName) category ← * <~ categoryById(categoryId, context) @@ -100,12 +96,11 @@ object CategoryManager { categoryShadow ← * <~ ObjectShadows.mustFindById404(commit.shadowId) } yield IlluminatedCategoryResponse.build( - IlluminatedCategory.illuminate(context, category, categoryForm, categoryShadow)) + IlluminatedCategory.illuminate(context, category, categoryForm, categoryShadow)) - private def updateCategoryHead( - category: Category, - categoryShadow: ObjectShadow, - maybeCommit: Option[ObjectCommit])(implicit ec: EC): DbResultT[Category] = + private def updateCategoryHead(category: Category, + categoryShadow: ObjectShadow, + maybeCommit: Option[ObjectCommit])(implicit ec: EC): DbResultT[Category] = maybeCommit match { case Some(commit) ⇒ Categories @@ -117,23 +112,20 @@ object CategoryManager { private def contextByName(contextName: String)(implicit ec: EC): DbResultT[ObjectContext] = ObjectContexts.filterByName(contextName).mustFindOneOr(ObjectContextNotFound(contextName)) - private def categoryById(categoryId: Int, context: ObjectContext)( - implicit ec: EC): DbResultT[Category] = + private def categoryById(categoryId: Int, context: ObjectContext)(implicit ec: EC): DbResultT[Category] = Categories .withContextAndCategory(context.id, categoryId) .mustFindOneOr(CategoryNotFoundForContext(categoryId, context.id)) - private def getCategoryFull(categoryId: Int, contextName: String)( - implicit ec: EC, - db: DB): DbResultT[CategoryFull] = + private def getCategoryFull(categoryId: Int, contextName: String)(implicit ec: EC, + db: DB): DbResultT[CategoryFull] = for { context ← * <~ contextByName(contextName) result ← * <~ getCategoryFull(categoryId, context) } yield result - private def getCategoryFull(categoryId: Int, context: ObjectContext)( - implicit ec: EC, - db: DB): DbResultT[CategoryFull] = + private def getCategoryFull(categoryId: Int, context: ObjectContext)(implicit ec: EC, + db: DB): DbResultT[CategoryFull] = for { category ← * <~ categoryById(categoryId, context) form ← * <~ ObjectForms.mustFindById404(category.formId) diff --git a/phoenix-scala/phoenix/app/phoenix/services/coupon/CouponManager.scala b/phoenix-scala/phoenix/app/phoenix/services/coupon/CouponManager.scala index 3b421e4af0..01c55aa66c 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/coupon/CouponManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/coupon/CouponManager.scala @@ -26,11 +26,9 @@ object CouponManager { implicit val formats: Formats = JsonFormatters.phoenixFormats - def create(payload: CreateCoupon, contextName: String, admin: Option[User])( - implicit ec: EC, - db: DB, - ac: AC, - au: AU): DbResultT[CouponResponse.Root] = { + def create(payload: CreateCoupon, + contextName: String, + admin: Option[User])(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[CouponResponse.Root] = { val formAndShadow = FormAndShadow.fromPayload(Coupon.kind, forceActivate(payload.attributes)) @@ -44,12 +42,12 @@ object CouponManager { .mustFindOneOr(PromotionNotFoundForContext(payload.promotion, context.name)) ins ← * <~ ObjectUtils.insert(formAndShadow.form, formAndShadow.shadow, payload.schema) coupon ← * <~ Coupons.create( - Coupon(scope = scope, - contextId = context.id, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id, - promotionId = payload.promotion)) + Coupon(scope = scope, + contextId = context.id, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id, + promotionId = payload.promotion)) response = CouponResponse.build(context, coupon, ins.form, ins.shadow) _ ← * <~ LogActivity().withScope(scope).couponCreated(response, admin) } yield response @@ -58,7 +56,7 @@ object CouponManager { private def forceActivate(attributes: Map[String, Json]): Map[String, Json] = attributes .updated("activeFrom", ("t" → "datetime") ~ ("v" → Instant.ofEpochMilli(1).toString)) - .updated("activeTo", ("t" → "datetime") ~ ("v" → JNull)) + .updated("activeTo", ("t" → "datetime") ~ ("v" → JNull)) def update(id: Int, payload: UpdateCoupon, contextName: String, admin: User)( implicit ec: EC, @@ -88,8 +86,7 @@ object CouponManager { } yield response } - def getIlluminated(id: Int, contextName: String)(implicit ec: EC, - db: DB): DbResultT[CouponResponse.Root] = + def getIlluminated(id: Int, contextName: String)(implicit ec: EC, db: DB): DbResultT[CouponResponse.Root] = for { context ← * <~ ObjectContexts .filterByName(contextName) @@ -97,9 +94,8 @@ object CouponManager { result ← * <~ getIlluminatedIntern(id, context) } yield result - def getIlluminatedByCode(code: String, contextName: String)( - implicit ec: EC, - db: DB): DbResultT[CouponResponse.Root] = + def getIlluminatedByCode(code: String, contextName: String)(implicit ec: EC, + db: DB): DbResultT[CouponResponse.Root] = for { context ← * <~ ObjectContexts .filterByName(contextName) @@ -110,9 +106,8 @@ object CouponManager { result ← * <~ getIlluminatedIntern(couponCode.couponFormId, context) } yield result - private def getIlluminatedIntern(id: Int, context: ObjectContext)( - implicit ec: EC, - db: DB): DbResultT[CouponResponse.Root] = + private def getIlluminatedIntern(id: Int, context: ObjectContext)(implicit ec: EC, + db: DB): DbResultT[CouponResponse.Root] = for { coupon ← * <~ Coupons .filter(_.contextId === context.id) @@ -122,8 +117,8 @@ object CouponManager { shadow ← * <~ ObjectShadows.mustFindById404(coupon.shadowId) } yield CouponResponse.build(context, coupon, form, shadow) - def archiveByContextAndId(contextName: String, - formId: Int)(implicit ec: EC, db: DB): DbResultT[CouponResponse.Root] = + def archiveByContextAndId(contextName: String, formId: Int)(implicit ec: EC, + db: DB): DbResultT[CouponResponse.Root] = for { context ← * <~ ObjectContexts .filterByName(contextName) @@ -136,18 +131,16 @@ object CouponManager { shadow ← * <~ ObjectShadows.mustFindById404(archiveResult.shadowId) } yield CouponResponse.build(context, archiveResult, form, shadow) - def generateCode(id: Int, code: String, admin: User)(implicit ec: EC, - db: DB, - ac: AC): DbResultT[String] = + def generateCode(id: Int, code: String, admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[String] = for { coupon ← * <~ Coupons.filter(_.formId === id).mustFindOneOr(CouponNotFound(id)) couponCode ← * <~ CouponCodes.create(CouponCode(couponFormId = id, code = code)) _ ← * <~ LogActivity().singleCouponCodeCreated(coupon, Some(admin)) } yield couponCode.code - def generateCodes(id: Int, - payload: GenerateCouponCodes, - admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[String]] = + def generateCodes(id: Int, payload: GenerateCouponCodes, admin: User)(implicit ec: EC, + db: DB, + ac: AC): DbResultT[Seq[String]] = for { _ ← * <~ validateCouponCodePayload(payload) coupon ← * <~ Coupons.filter(_.formId === id).mustFindOneOr(CouponNotFound(id)) @@ -165,17 +158,16 @@ object CouponManager { codes ← * <~ CouponCodes.filter(_.couponFormId === id).result } yield CouponCodesResponse.build(codes) - private def validateCouponCodePayload(p: GenerateCouponCodes)(implicit ec: EC) = { + private def validateCouponCodePayload(p: GenerateCouponCodes)(implicit ec: EC) = ObjectUtils.failIfErrors( - Seq( - if (p.quantity <= 0) Seq(CouponCodeQuanityMustBeGreaterThanZero) - else Seq.empty, - if (p.prefix.isEmpty) Seq(CouponCodePrefixNotSet) else Seq.empty, - if (CouponCodes.isCharacterLimitValid(p.prefix.length, p.quantity, p.length)) - Seq.empty - else Seq(CouponCodeLengthIsTooSmall(p.prefix, p.quantity)) - ).flatten) - } + Seq( + if (p.quantity <= 0) Seq(CouponCodeQuanityMustBeGreaterThanZero) + else Seq.empty, + if (p.prefix.isEmpty) Seq(CouponCodePrefixNotSet) else Seq.empty, + if (CouponCodes.isCharacterLimitValid(p.prefix.length, p.quantity, p.length)) + Seq.empty + else Seq(CouponCodeLengthIsTooSmall(p.prefix, p.quantity)) + ).flatten) private def updateHead(coupon: Coupon, promotionId: Int, @@ -183,9 +175,8 @@ object CouponManager { maybeCommit: Option[ObjectCommit])(implicit ec: EC): DbResultT[Coupon] = maybeCommit match { case Some(commit) ⇒ - Coupons.update( - coupon, - coupon.copy(shadowId = shadow.id, commitId = commit.id, promotionId = promotionId)) + Coupons.update(coupon, + coupon.copy(shadowId = shadow.id, commitId = commit.id, promotionId = promotionId)) case None ⇒ if (promotionId != coupon.promotionId) Coupons.update(coupon, coupon.copy(promotionId = promotionId)) diff --git a/phoenix-scala/phoenix/app/phoenix/services/coupon/CouponUsageService.scala b/phoenix-scala/phoenix/app/phoenix/services/coupon/CouponUsageService.scala index a7111df18f..b7e220816f 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/coupon/CouponUsageService.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/coupon/CouponUsageService.scala @@ -10,22 +10,19 @@ import core.db._ object CouponUsageService { - private def couponUsageCount(couponFormId: Int, accountId: Int)(implicit ec: EC, - db: DB): DBIO[Int] = + private def couponUsageCount(couponFormId: Int, accountId: Int)(implicit ec: EC, db: DB): DBIO[Int] = for { coupon ← CouponCustomerUsages.filterByCouponAndAccount(couponFormId, accountId).one } yield coupon.fold(0)(_.count) - private def couponCodeUsageCount(couponFormId: Int, couponCodeId: Int)(implicit ec: EC, - db: DB): DBIO[Int] = + private def couponCodeUsageCount(couponFormId: Int, couponCodeId: Int)(implicit ec: EC, db: DB): DBIO[Int] = for { counter ← CouponCodeUsages.filterByCouponAndCode(couponFormId, couponCodeId).one } yield counter.fold(0)(_.count) - def couponCodeMustBeUsable(couponFormId: Int, - couponCodeId: Int, - usesAvailable: Int, - code: String)(implicit ec: EC, db: DB): DbResultT[Unit] = + def couponCodeMustBeUsable(couponFormId: Int, couponCodeId: Int, usesAvailable: Int, code: String)( + implicit ec: EC, + db: DB): DbResultT[Unit] = for { count ← * <~ couponCodeUsageCount(couponFormId, couponCodeId) _ ← * <~ failIf(usesAvailable <= count, CouponCodeCannotBeUsedAnymore(code)) @@ -36,8 +33,7 @@ object CouponUsageService { db: DB): DbResultT[Unit] = for { count ← * <~ couponUsageCount(couponFormId, accountId) - _ ← * <~ failIf(usesAvailable <= count, - CouponCodeCannotBeUsedByCustomerAnymore(code, accountId)) + _ ← * <~ failIf(usesAvailable <= count, CouponCodeCannotBeUsedByCustomerAnymore(code, accountId)) } yield {} def mustBeUsableByCustomer(couponFormId: Int, @@ -47,15 +43,12 @@ object CouponUsageService { usesAvailableForCustomer: Int, couponCode: String)(implicit ec: EC, db: DB): DbResultT[Unit] = for { - _ ← * <~ couponCodeMustBeUsable(couponFormId, - couponCodeId, - usesAvailableForCustomer, - couponCode) + _ ← * <~ couponCodeMustBeUsable(couponFormId, couponCodeId, usesAvailableForCustomer, couponCode) _ ← * <~ couponMustBeUsable(couponFormId, accountId, usesAvailableForCustomer, couponCode) } yield {} def updateUsageCounts(couponCodeId: Option[Int], - customer: User)(implicit ec: EC, db: DB, ctx: OC): DbResultT[Unit] = { + customer: User)(implicit ec: EC, db: DB, ctx: OC): DbResultT[Unit] = couponCodeId match { case Some(codeId) ⇒ for { @@ -70,34 +63,32 @@ object CouponUsageService { couponUsage ← * <~ CouponUsages .filterByCoupon(coupon.formId) .one - .findOrCreate(CouponUsages.create( - CouponUsage(couponFormId = coupon.formId, count = 1))) + .findOrCreate( + CouponUsages.create(CouponUsage(couponFormId = coupon.formId, count = 1))) couponCodeUsage ← * <~ CouponCodeUsages .filterByCouponAndCode(coupon.formId, couponCode.id) .one .findOrCreate( - CouponCodeUsages.create( - CouponCodeUsage(couponFormId = coupon.formId, - couponCodeId = couponCode.id, - count = 0))) + CouponCodeUsages.create( + CouponCodeUsage(couponFormId = coupon.formId, + couponCodeId = couponCode.id, + count = 0))) couponUsageByCustomer ← * <~ CouponCustomerUsages .filterByCouponAndAccount(coupon.formId, customer.accountId) .one .findOrCreate( - CouponCustomerUsages.create( - CouponCustomerUsage(couponFormId = coupon.formId, - accountId = customer.accountId, - count = 0))) - _ ← * <~ CouponUsages.update(couponUsage, - couponUsage.copy(count = couponUsage.count + 1)) + CouponCustomerUsages.create( + CouponCustomerUsage(couponFormId = coupon.formId, + accountId = customer.accountId, + count = 0))) + _ ← * <~ CouponUsages.update(couponUsage, couponUsage.copy(count = couponUsage.count + 1)) _ ← * <~ CouponCodeUsages.update(couponCodeUsage, couponCodeUsage.copy(count = couponCodeUsage.count + 1)) _ ← * <~ CouponCustomerUsages.update( - couponUsageByCustomer, - couponUsageByCustomer.copy(count = couponUsageByCustomer.count + 1)) + couponUsageByCustomer, + couponUsageByCustomer.copy(count = couponUsageByCustomer.count + 1)) } yield {} case _ ⇒ DbResultT.unit } - } } diff --git a/phoenix-scala/phoenix/app/phoenix/services/customerGroups/GroupManager.scala b/phoenix-scala/phoenix/app/phoenix/services/customerGroups/GroupManager.scala index beb70392fb..33c4cd3c30 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/customerGroups/GroupManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/customerGroups/GroupManager.scala @@ -11,7 +11,7 @@ import phoenix.models.account.{Scope, User} import phoenix.models.customer.CustomerGroup.Manual import phoenix.models.customer._ import phoenix.payloads.CustomerGroupPayloads.CustomerGroupPayload -import phoenix.responses.GroupResponses.GroupResponse.{Root, build} +import phoenix.responses.GroupResponses.GroupResponse.{build, Root} import phoenix.services.LogActivity import phoenix.utils.aliases._ import phoenix.utils.time._ @@ -44,10 +44,10 @@ object GroupManager { payloadWithCount = if (group.groupType == Manual) payload.copy(customersCount = memberCount) else payload groupEdited ← * <~ CustomerGroups.update( - group, - CustomerGroup - .fromPayloadAndAdmin(payloadWithCount, group.createdBy, scope) - .copy(id = groupId, createdAt = group.createdAt, updatedAt = Instant.now)) + group, + CustomerGroup + .fromPayloadAndAdmin(payloadWithCount, group.createdBy, scope) + .copy(id = groupId, createdAt = group.createdAt, updatedAt = Instant.now)) _ ← * <~ LogActivity().customerGroupUpdated(groupEdited, admin) } yield build(groupEdited) @@ -68,28 +68,22 @@ object GroupManager { admin: User)(implicit ec: EC, db: DB, au: AU, ac: AC): DbResultT[Root] = for { scope ← * <~ Scope.resolveOverride(payload.scope) - group ← * <~ CustomerGroups.create( - CustomerGroup.fromPayloadAndAdmin(payload, admin.accountId, scope)) + group ← * <~ CustomerGroups.create(CustomerGroup.fromPayloadAndAdmin(payload, admin.accountId, scope)) updated ← * <~ doOrGood(group.elasticRequest == JObject() || group.elasticRequest == JNull, CustomerGroups.update(group, withGroupQuery(group)), group) _ ← * <~ LogActivity().customerGroupCreated(updated, admin) } yield build(updated) - private def createTemplateGroup(templateId: Int, payload: CustomerGroupPayload, admin: User)( - implicit ec: EC, - db: DB, - au: AU, - ac: AC): DbResultT[Root] = + private def createTemplateGroup(templateId: Int, + payload: CustomerGroupPayload, + admin: User)(implicit ec: EC, db: DB, au: AU, ac: AC): DbResultT[Root] = for { scope ← * <~ Scope.resolveOverride(payload.scope) template ← * <~ CustomerGroupTemplates.mustFindById404(templateId) - group ← * <~ CustomerGroups.create( - CustomerGroup.fromPayloadAndAdmin(payload, admin.accountId, scope)) + group ← * <~ CustomerGroups.create(CustomerGroup.fromPayloadAndAdmin(payload, admin.accountId, scope)) _ ← * <~ GroupTemplateInstances.create( - GroupTemplateInstance(groupId = group.id, - groupTemplateId = template.id, - scope = scope)) + GroupTemplateInstance(groupId = group.id, groupTemplateId = template.id, scope = scope)) _ ← * <~ LogActivity().customerGroupCreated(group, admin) } yield build(group) diff --git a/phoenix-scala/phoenix/app/phoenix/services/customerGroups/GroupMemberManager.scala b/phoenix-scala/phoenix/app/phoenix/services/customerGroups/GroupMemberManager.scala index 3ff83d2ce5..95f3e10cfe 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/customerGroups/GroupMemberManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/customerGroups/GroupMemberManager.scala @@ -13,7 +13,7 @@ import phoenix.models.customer._ import phoenix.models.discount.SearchReference import org.json4s.JsonAST._ import phoenix.payloads.CustomerGroupPayloads._ -import phoenix.responses.CustomerResponse.{Root, build} +import phoenix.responses.CustomerResponse.{build, Root} import phoenix.responses.GroupResponses.CustomerGroupResponse import phoenix.services.StoreCreditService import phoenix.services.customers.CustomerManager @@ -45,9 +45,8 @@ object GroupMemberManager { } } yield {} - def sync(groupId: Int, payload: CustomerGroupMemberSyncPayload)(implicit ec: EC, - db: DB, - ac: AC): DbResultT[Unit] = + def sync(groupId: Int, + payload: CustomerGroupMemberSyncPayload)(implicit ec: EC, db: DB, ac: AC): DbResultT[Unit] = for { group ← * <~ CustomerGroups.mustFindById404(groupId) _ ← * <~ group.mustBeOfType(Manual) @@ -57,10 +56,9 @@ object GroupMemberManager { memberIds = currentMemberData.map(_.accountId).toSet forCreation = payload.toAdd.toSet forDeletion = payload.toDelete.toSet - _ ← * <~ failIf(!forCreation.intersect(forDeletion).isEmpty, - CustomerGroupMemberPayloadContainsSameIdsInBothSections(groupId, - forCreation, - forDeletion)) + _ ← * <~ failIf( + !forCreation.intersect(forDeletion).isEmpty, + CustomerGroupMemberPayloadContainsSameIdsInBothSections(groupId, forCreation, forDeletion)) _ ← * <~ forCreation.diff(memberIds).toSeq.map { userId ⇒ createGroupMember(userId, groupId) } @@ -102,30 +100,29 @@ object GroupMemberManager { } dynamicGroupsOfUser ← * <~ CustomerGroups.fildAllByIdsAndType(groupIds, Dynamic).result } yield - build(customer.copy(phoneNumber = customer.phoneNumber.orElse(phoneOverride)), - customerData, - shipRegion, - billRegion, - rank = rank, - scTotals = totals, - lastOrderDays = maxOrdersDate.map(DAYS.between(_, Instant.now)), - groups = (dynamicGroupsOfUser ++ newGroups).map(CustomerGroupResponse.build _)) + build( + customer.copy(phoneNumber = customer.phoneNumber.orElse(phoneOverride)), + customerData, + shipRegion, + billRegion, + rank = rank, + scTotals = totals, + lastOrderDays = maxOrdersDate.map(DAYS.between(_, Instant.now)), + groups = (dynamicGroupsOfUser ++ newGroups).map(CustomerGroupResponse.build _) + ) - private def createGroupMember(userId: Int, groupId: Int)( - implicit ec: EC, - db: DB): DbResultT[CustomerGroupMember] = + private def createGroupMember(userId: Int, groupId: Int)(implicit ec: EC, + db: DB): DbResultT[CustomerGroupMember] = for { customerData ← * <~ CustomersData.mustFindByAccountId(userId) group ← * <~ CustomerGroups.mustFindById400(groupId) membership = CustomerGroupMember(customerDataId = customerData.id, groupId = groupId) result ← * <~ CustomerGroupMembers.create(membership) - _ ← * <~ doOrMeh( - group.groupType == Manual, - CustomerGroups.update(group, group.copy(customersCount = group.customersCount + 1))) + _ ← * <~ doOrMeh(group.groupType == Manual, + CustomerGroups.update(group, group.copy(customersCount = group.customersCount + 1))) } yield result - private def deleteGroupMember(userId: Int, groupId: Int)(implicit ec: EC, - db: DB): DbResultT[Unit] = + private def deleteGroupMember(userId: Int, groupId: Int)(implicit ec: EC, db: DB): DbResultT[Unit] = for { customerData ← * <~ CustomersData.mustFindByAccountId(userId) group ← * <~ CustomerGroups.mustFindById400(groupId) @@ -134,21 +131,18 @@ object GroupMemberManager { .mustFindOneOr(NotFoundFailure400(User, userId)) _ ← * <~ CustomerGroupMembers .deleteById(membership.id, DbResultT.unit, userId ⇒ NotFoundFailure400(User, userId)) - _ ← * <~ doOrMeh( - group.groupType == Manual, - CustomerGroups.update(group, group.copy(customersCount = group.customersCount - 1))) + _ ← * <~ doOrMeh(group.groupType == Manual, + CustomerGroups.update(group, group.copy(customersCount = group.customersCount - 1))) } yield {} - def isMemberOfAny(groupIds: Set[Int], customer: User)(implicit ec: EC, - apis: Apis): DbResultT[Boolean] = + def isMemberOfAny(groupIds: Set[Int], customer: User)(implicit ec: EC, apis: Apis): DbResultT[Boolean] = for { customerGroups ← * <~ CustomerGroups.fildAllByIds(groupIds).result.dbresult results ← * <~ customerGroups.toStream .traverse(isMember(_, customer)) // FIXME: no need to check all of them, but Scala is strict… @michalrus } yield results.exists(identity) - def isMember(group: CustomerGroup, customer: User)(implicit ec: EC, - apis: Apis): DbResultT[Boolean] = + def isMember(group: CustomerGroup, customer: User)(implicit ec: EC, apis: Apis): DbResultT[Boolean] = if (group.groupType == Manual) for { customerData ← * <~ CustomersData.mustFindByAccountId(customer.accountId) num ← * <~ CustomerGroupMembers @@ -159,21 +153,18 @@ object GroupMemberManager { } yield (num > 0) else if (group.groupType == Dynamic) for { num ← * <~ apis.elasticSearch.numResults( - ElasticsearchApi.SearchView(SearchReference.customersSearchView), - narrowDownWithUserId(customer.id)(group.elasticRequest)) + ElasticsearchApi.SearchView(SearchReference.customersSearchView), + narrowDownWithUserId(customer.id)(group.elasticRequest)) } yield (num > 0) else DbResultT.pure(false) private def narrowDownWithUserId(userId: Int)(elasticRequest: Json): Json = { - val term = JObject(JField("term", JObject(JField("id", JInt(userId))))) - val userQuery = JObject( - JField("query", JObject(JField("bool", JObject(JField("must", term)))))) + val term = JObject(JField("term", JObject(JField("id", JInt(userId))))) + val userQuery = JObject(JField("query", JObject(JField("bool", JObject(JField("must", term)))))) JObject( - JField("query", - JObject( - JField("bool", - JObject(JField("filter", JArray(List(elasticRequest, userQuery)))))))) + JField("query", + JObject(JField("bool", JObject(JField("filter", JArray(List(elasticRequest, userQuery)))))))) } } diff --git a/phoenix-scala/phoenix/app/phoenix/services/customers/CustomerManager.scala b/phoenix-scala/phoenix/app/phoenix/services/customers/CustomerManager.scala index 9dcf74041f..9ec251af20 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/customers/CustomerManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/customers/CustomerManager.scala @@ -39,9 +39,14 @@ object CustomerManager { shipment.shippingAddressId.isDefined address ← OrderShippingAddresses if address.id === shipment.shippingAddressId && address.phoneNumber.isDefined - } yield (address.phoneNumber, shipment.updatedAt)).sortBy { - case (_, updatedAt) ⇒ updatedAt.desc.nullsLast - }.map { case (phone, _) ⇒ phone }.one.map(_.flatten).dbresult + } yield (address.phoneNumber, shipment.updatedAt)) + .sortBy { + case (_, updatedAt) ⇒ updatedAt.desc.nullsLast + } + .map { case (phone, _) ⇒ phone } + .one + .map(_.flatten) + .dbresult for { default ← * <~ Addresses @@ -54,7 +59,7 @@ object CustomerManager { } yield shipment } - private def getCustomerInfo(userDbT: DbResultT[User])(implicit ec: EC, db: DB): DbResultT[Root] = { + private def getCustomerInfo(userDbT: DbResultT[User])(implicit ec: EC, db: DB): DbResultT[Root] = for { customer ← * <~ userDbT customerDatas ← * <~ CustomersData @@ -75,15 +80,16 @@ object CustomerManager { groupIds = groupMembership.map(_.groupId).toSet groups ← * <~ CustomerGroups.findAllByIds(groupIds).result } yield - build(customer.copy(phoneNumber = customer.phoneNumber.orElse(phoneOverride)), - customerData, - shipRegion, - billRegion, - rank = rank, - scTotals = totals, - lastOrderDays = maxOrdersDate.map(DAYS.between(_, Instant.now)), - groups = groups.map(CustomerGroupResponse.build)) - } + build( + customer.copy(phoneNumber = customer.phoneNumber.orElse(phoneOverride)), + customerData, + shipRegion, + billRegion, + rank = rank, + scTotals = totals, + lastOrderDays = maxOrdersDate.map(DAYS.between(_, Instant.now)), + groups = groups.map(CustomerGroupResponse.build) + ) def getByAccountId(accountId: Int)(implicit ec: EC, db: DB): DbResultT[Root] = { val userDbByAccountId = Users.mustFindByAccountId(accountId) @@ -97,9 +103,7 @@ object CustomerManager { def create(payload: CreateCustomerPayload, admin: Option[User] = None, - context: AccountCreateContext)(implicit ec: EC, - db: DB, - ac: AC): DbResultT[(Root, AuthPayload)] = + context: AccountCreateContext)(implicit ec: EC, db: DB, ac: AC): DbResultT[(Root, AuthPayload)] = for { contextScope ← * <~ Scopes.mustFindById400(context.scopeId) @@ -115,10 +119,9 @@ object CustomerManager { auth ← * <~ AuthPayload(token) } yield (result, auth) - def createFromAdmin( - payload: CreateCustomerPayload, - admin: Option[User] = None, - context: AccountCreateContext)(implicit ec: EC, db: DB, ac: AC): DbResultT[Root] = + def createFromAdmin(payload: CreateCustomerPayload, + admin: Option[User] = None, + context: AccountCreateContext)(implicit ec: EC, db: DB, ac: AC): DbResultT[Root] = for { contextScope ← * <~ Scopes.mustFindById400(context.scopeId) scope ← * <~ Scope.overwrite(contextScope.path, payload.scope) @@ -128,11 +131,10 @@ object CustomerManager { _ ← * <~ LogActivity().withScope(scope).customerCreated(resp, admin) } yield resp - private def createCustomer( - payload: CreateCustomerPayload, - admin: Option[User] = None, - context: AccountCreateContext, - scope: LTree)(implicit ec: EC, db: DB, ac: AC): DbResultT[(User, CustomerData)] = + private def createCustomer(payload: CreateCustomerPayload, + admin: Option[User] = None, + context: AccountCreateContext, + scope: LTree)(implicit ec: EC, db: DB, ac: AC): DbResultT[(User, CustomerData)] = for { user ← * <~ AccountManager.createUser(name = payload.name, email = payload.email.toLowerCase.some, @@ -141,14 +143,13 @@ object CustomerManager { checkEmail = !payload.isGuest.getOrElse(false)) custData ← * <~ CustomersData.create( - CustomerData(accountId = user.accountId, - userId = user.id, - isGuest = payload.isGuest.getOrElse(false), - scope = scope)) + CustomerData(accountId = user.accountId, + userId = user.id, + isGuest = payload.isGuest.getOrElse(false), + scope = scope)) } yield (user, custData) - def createGuest(context: AccountCreateContext)(implicit ec: EC, - db: DB): DbResultT[(User, CustomerData)] = + def createGuest(context: AccountCreateContext)(implicit ec: EC, db: DB): DbResultT[(User, CustomerData)] = for { user ← * <~ AccountManager.createUser(name = None, @@ -158,16 +159,15 @@ object CustomerManager { checkEmail = false) scope ← * <~ Scopes.mustFindById400(context.scopeId) custData ← * <~ CustomersData.create( - CustomerData(accountId = user.accountId, - userId = user.id, - isGuest = true, - scope = LTree(scope.path))) + CustomerData(accountId = user.accountId, + userId = user.id, + isGuest = true, + scope = LTree(scope.path))) } yield (user, custData) - def update(accountId: Int, payload: UpdateCustomerPayload, admin: Option[User] = None)( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[(Root, AuthPayload)] = + def update(accountId: Int, + payload: UpdateCustomerPayload, + admin: Option[User] = None)(implicit ec: EC, db: DB, ac: AC): DbResultT[(Root, AuthPayload)] = for { result ← * <~ updateCustomer(accountId, payload, admin) (updated, custData) = result @@ -181,19 +181,17 @@ object CustomerManager { auth ← * <~ AuthPayload(token) } yield (build(updated, custData), auth) - def updateFromAdmin(accountId: Int, payload: UpdateCustomerPayload, admin: Option[User] = None)( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[Root] = + def updateFromAdmin(accountId: Int, + payload: UpdateCustomerPayload, + admin: Option[User] = None)(implicit ec: EC, db: DB, ac: AC): DbResultT[Root] = for { result ← * <~ updateCustomer(accountId, payload, admin) } yield build(result._1, result._2) - private def updateCustomer(accountId: Int, - payload: UpdateCustomerPayload, - admin: Option[User] = None)(implicit ec: EC, - db: DB, - ac: AC): DbResultT[(User, CustomerData)] = + private def updateCustomer(accountId: Int, payload: UpdateCustomerPayload, admin: Option[User] = None)( + implicit ec: EC, + db: DB, + ac: AC): DbResultT[(User, CustomerData)] = for { customer ← * <~ Users.mustFindByAccountId(accountId) custData ← * <~ CustomersData.mustFindByAccountId(accountId) @@ -204,9 +202,9 @@ object CustomerManager { _ ← * <~ LogActivity().customerUpdated(customer, updated, admin) } yield (updated, custData) - def changePassword( - accountId: Int, - payload: ChangeCustomerPasswordPayload)(implicit ec: EC, db: DB, ac: AC): DbResultT[Unit] = + def changePassword(accountId: Int, payload: ChangeCustomerPasswordPayload)(implicit ec: EC, + db: DB, + ac: AC): DbResultT[Unit] = for { user ← * <~ Users.mustFindByAccountId(accountId) account ← * <~ Accounts.mustFindById404(accountId) @@ -221,28 +219,28 @@ object CustomerManager { _ ← * <~ LogActivity().userPasswordReset(user) } yield {} - def updatedUser(customer: User, payload: UpdateCustomerPayload): User = { - customer.copy(name = payload.name.fold(customer.name)(Some(_)), - email = payload.email.map(_.toLowerCase).orElse(customer.email), - phoneNumber = payload.phoneNumber.fold(customer.phoneNumber)(Some(_))) - } + def updatedUser(customer: User, payload: UpdateCustomerPayload): User = + customer.copy( + name = payload.name.fold(customer.name)(Some(_)), + email = payload.email.map(_.toLowerCase).orElse(customer.email), + phoneNumber = payload.phoneNumber.fold(customer.phoneNumber)(Some(_)) + ) - def updatedCustUser(custData: CustomerData, payload: UpdateCustomerPayload): CustomerData = { + def updatedCustUser(custData: CustomerData, payload: UpdateCustomerPayload): CustomerData = (payload.name, payload.email) match { case (Some(name), Some(email)) ⇒ custData.copy(isGuest = false) case _ ⇒ custData } - } - def activate(accountId: Int, - payload: ActivateCustomerPayload, - admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[Root] = + def activate(accountId: Int, payload: ActivateCustomerPayload, admin: User)(implicit ec: EC, + db: DB, + ac: AC): DbResultT[Root] = for { customer ← * <~ Users.mustFindByAccountId(accountId) _ ← * <~ (customer.email match { - case None ⇒ DbResultT.failure(CustomerMustHaveCredentials) - case _ ⇒ DbResultT.unit - }) + case None ⇒ DbResultT.failure(CustomerMustHaveCredentials) + case _ ⇒ DbResultT.unit + }) _ ← * <~ Users.updateEmailMustBeUnique(customer.email, accountId) updated ← * <~ Users.update(customer, customer.copy(name = payload.name.some)) custData ← * <~ CustomersData.mustFindByAccountId(accountId) @@ -260,9 +258,9 @@ object CustomerManager { custData ← * <~ CustomersData.mustFindByAccountId(accountId) } yield build(customer, custData) - def toggleBlacklisted(accountId: Int, - blacklisted: Boolean, - actor: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[Root] = + def toggleBlacklisted(accountId: Int, blacklisted: Boolean, actor: User)(implicit ec: EC, + db: DB, + ac: AC): DbResultT[Root] = for { r ← * <~ AccountManager.toggleBlacklisted(accountId, blacklisted, actor) customer ← * <~ Users.mustFindByAccountId(accountId) diff --git a/phoenix-scala/phoenix/app/phoenix/services/discount/DiscountManager.scala b/phoenix-scala/phoenix/app/phoenix/services/discount/DiscountManager.scala index 1e6b59d7a2..1aa9a5f3d3 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/discount/DiscountManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/discount/DiscountManager.scala @@ -40,8 +40,7 @@ object DiscountManager { shadow ← * <~ ObjectShadows.mustFindById404(discount.shadowId) } yield DiscountShadowResponse.build(shadow) - def get(discountId: Int, contextName: String)(implicit ec: EC, - db: DB): DbResultT[DiscountResponse.Root] = + def get(discountId: Int, contextName: String)(implicit ec: EC, db: DB): DbResultT[DiscountResponse.Root] = for { context ← * <~ ObjectContexts .filterByName(contextName) @@ -54,9 +53,8 @@ object DiscountManager { shadow ← * <~ ObjectShadows.mustFindById404(discount.shadowId) } yield DiscountResponse.build(form, shadow) - def create( - payload: CreateDiscount, - contextName: String)(implicit ec: EC, db: DB, au: AU): DbResultT[DiscountResponse.Root] = + def create(payload: CreateDiscount, + contextName: String)(implicit ec: EC, db: DB, au: AU): DbResultT[DiscountResponse.Root] = for { context ← * <~ ObjectContexts .filterByName(contextName) @@ -73,20 +71,19 @@ object DiscountManager { copy(form = form, shadow = shadow) } - def createInternal(payload: CreateDiscount, context: ObjectContext)( - implicit ec: EC, - au: AU): DbResultT[CreateInternalResult] = { + def createInternal(payload: CreateDiscount, + context: ObjectContext)(implicit ec: EC, au: AU): DbResultT[CreateInternalResult] = { val fs = FormAndShadow.fromPayload(Discount.kind, payload.attributes) for { scope ← * <~ Scope.resolveOverride(payload.scope) _ ← * <~ DiscountValidator.validate(fs) ins ← * <~ ObjectUtils.insert(fs.form, fs.shadow, payload.schema) discount ← * <~ Discounts.create( - Discount(scope = scope, - contextId = context.id, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) + Discount(scope = scope, + contextId = context.id, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) } yield CreateInternalResult(discount, ins.commit, ins.form, ins.shadow) } @@ -128,9 +125,8 @@ object DiscountManager { } yield UpdateInternalResult(discount, updated, update.form, update.shadow) } - def getIlluminated(id: Int, contextName: String)( - implicit ec: EC, - db: DB): DbResultT[IlluminatedDiscountResponse.Root] = + def getIlluminated(id: Int, contextName: String)(implicit ec: EC, + db: DB): DbResultT[IlluminatedDiscountResponse.Root] = for { context ← * <~ ObjectContexts .filterByName(contextName) @@ -142,12 +138,10 @@ object DiscountManager { form ← * <~ ObjectForms.mustFindById404(discount.formId) shadow ← * <~ ObjectShadows.mustFindById404(discount.shadowId) } yield - IlluminatedDiscountResponse.build( - IlluminatedDiscount.illuminate(context = context.some, form, shadow)) + IlluminatedDiscountResponse.build(IlluminatedDiscount.illuminate(context = context.some, form, shadow)) - private def updateHead(discount: Discount, - shadow: ObjectShadow, - maybeCommit: Option[ObjectCommit])(implicit ec: EC): DbResultT[Discount] = + private def updateHead(discount: Discount, shadow: ObjectShadow, maybeCommit: Option[ObjectCommit])( + implicit ec: EC): DbResultT[Discount] = maybeCommit match { case Some(commit) ⇒ Discounts.update(discount, discount.copy(shadowId = shadow.id, commitId = commit.id)) diff --git a/phoenix-scala/phoenix/app/phoenix/services/discount/compilers/QualifierCompiler.scala b/phoenix-scala/phoenix/app/phoenix/services/discount/compilers/QualifierCompiler.scala index 932efe135f..99ee5899b8 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/discount/compilers/QualifierCompiler.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/discount/compilers/QualifierCompiler.scala @@ -25,8 +25,7 @@ case class QualifierCompiler(qualifierType: QualifierType, attributes: Json) { case _ ⇒ Either.left(QualifierNotImplementedFailure(qualifierType).single) } - private def extract[T <: Qualifier](json: Json)( - implicit m: Manifest[T]): Either[Failures, Qualifier] = + private def extract[T <: Qualifier](json: Json)(implicit m: Manifest[T]): Either[Failures, Qualifier] = try { json.extract[T] match { case q: NonEmptySearch if q.search.isEmpty ⇒ diff --git a/phoenix-scala/phoenix/app/phoenix/services/giftcards/GiftCardService.scala b/phoenix-scala/phoenix/app/phoenix/services/giftcards/GiftCardService.scala index 8edc9dbafb..7bfd1d489f 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/giftcards/GiftCardService.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/giftcards/GiftCardService.scala @@ -47,14 +47,12 @@ object GiftCardService { for { customer ← * <~ Users.mustFindByAccountId(accountId) custData ← * <~ CustomersData.mustFindByAccountId(accountId) - } yield - GiftCardResponse.build(giftCard, Some(CustomerResponse.build(customer, custData)), None) + } yield GiftCardResponse.build(giftCard, Some(CustomerResponse.build(customer, custData)), None) case _ ⇒ DbResultT.good(GiftCardResponse.build(giftCard, None, None)) } - def createByAdmin( - admin: User, - payload: GiftCardCreateByCsr)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[Root] = + def createByAdmin(admin: User, + payload: GiftCardCreateByCsr)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[Root] = for { scope ← * <~ Scope.resolveOverride(payload.scope) _ ← * <~ Reasons.mustFindById400(payload.reasonId) @@ -66,16 +64,15 @@ object GiftCardService { .map(Some(_)) // A bit silly but need to rewrap it back } origin ← * <~ GiftCardManuals.create( - GiftCardManual(adminId = admin.accountId, reasonId = payload.reasonId)) + GiftCardManual(adminId = admin.accountId, reasonId = payload.reasonId)) giftCard ← * <~ GiftCards.create(GiftCard.buildAppeasement(payload, origin.id, scope)) adminResp = Some(UserResponse.build(admin)) _ ← * <~ LogActivity().withScope(scope).gcCreated(admin, giftCard) } yield build(gc = giftCard, admin = adminResp) - def createByCustomer(admin: User, payload: GiftCardCreatedByCustomer)(implicit ec: EC, - db: DB, - ac: AC, - au: AU): DbResultT[Root] = + def createByCustomer( + admin: User, + payload: GiftCardCreatedByCustomer)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[Root] = for { scope ← * <~ Scope.resolveOverride(payload.scope) origin ← * <~ GiftCardOrders.create(GiftCardOrder(cordRef = payload.cordRef)) @@ -84,11 +81,10 @@ object GiftCardService { _ ← * <~ LogActivity().withScope(scope).gcCreated(admin, giftCard) } yield build(gc = giftCard, admin = adminResp) - def createBulkByAdmin(admin: User, payload: GiftCardBulkCreateByCsr)( - implicit ec: EC, - db: DB, - ac: AC, - au: AU): DbResultT[List[ItemResult]] = + def createBulkByAdmin(admin: User, payload: GiftCardBulkCreateByCsr)(implicit ec: EC, + db: DB, + ac: AC, + au: AU): DbResultT[List[ItemResult]] = for { scope ← * <~ Scope.resolveOverride(payload.scope) gcCreatePayload = GiftCardCreateByCsr(balance = payload.balance, @@ -100,18 +96,16 @@ object GiftCardService { }.toList) } yield response - def bulkUpdateStateByCsr( - payload: GiftCardBulkUpdateStateByCsr, - admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[List[ItemResult]] = + def bulkUpdateStateByCsr(payload: GiftCardBulkUpdateStateByCsr, + admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[List[ItemResult]] = DbResultT.seqCollectFailures(payload.codes.map { code ⇒ val itemPayload = GiftCardUpdateStateByCsr(payload.state, payload.reasonId) updateStateByCsr(code, itemPayload, admin).mapEitherRight(buildItemResult(_, Some(code))) }.toList) - def updateStateByCsr(code: String, payload: GiftCardUpdateStateByCsr, admin: User)( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[Root] = + def updateStateByCsr(code: String, + payload: GiftCardUpdateStateByCsr, + admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[Root] = for { _ ← * <~ payload.reasonId.map(id ⇒ Reasons.mustFindById400(id)).getOrElse(DbResultT.unit) giftCard ← * <~ GiftCards.mustFindByCode(code) diff --git a/phoenix-scala/phoenix/app/phoenix/services/image/ImageManager.scala b/phoenix-scala/phoenix/app/phoenix/services/image/ImageManager.scala index c56e0218d2..d2e78f0bae 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/image/ImageManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/image/ImageManager.scala @@ -26,8 +26,7 @@ object ImageManager { type FullAlbum = FullObject[Album] type FullAlbumWithImages = (FullObject[Album], Seq[FullObject[Image]]) - def getAlbum(formId: ObjectForm#Id, contextName: String)(implicit ec: EC, - db: DB): DbResultT[AlbumRoot] = + def getAlbum(formId: ObjectForm#Id, contextName: String)(implicit ec: EC, db: DB): DbResultT[AlbumRoot] = for { context ← * <~ ObjectManager.mustFindByName404(contextName) album ← * <~ getAlbumInner(formId, context) @@ -40,16 +39,14 @@ object ImageManager { images ← * <~ AlbumImageLinks.queryRightByLeft(album.model) } yield AlbumResponse.build(album, images) - def getAlbumsForProduct(productReference: ProductReference)(implicit ec: EC, - db: DB, - oc: OC): DbResultT[Seq[AlbumRoot]] = + def getAlbumsForProduct( + productReference: ProductReference)(implicit ec: EC, db: DB, oc: OC): DbResultT[Seq[AlbumRoot]] = for { product ← * <~ Products.mustFindByReference(productReference) result ← * <~ getAlbumsForProductInner(product) } yield result - def getAlbumsForProductInner( - product: Product)(implicit ec: EC, db: DB, oc: OC): DbResultT[Seq[AlbumRoot]] = + def getAlbumsForProductInner(product: Product)(implicit ec: EC, db: DB, oc: OC): DbResultT[Seq[AlbumRoot]] = for { albums ← * <~ ProductAlbumLinks.queryRightByLeft(product) images ← * <~ albums.map(album ⇒ AlbumImageLinks.queryRightByLeft(album.model)) @@ -63,9 +60,8 @@ object ImageManager { albums ← * <~ getAlbumsForSkuInner(code, oc) } yield albums - def getAlbumsForSkuInner(code: String, context: ObjectContext)( - implicit ec: EC, - db: DB): DbResultT[Seq[AlbumResponse.Root]] = + def getAlbumsForSkuInner(code: String, context: ObjectContext)(implicit ec: EC, + db: DB): DbResultT[Seq[AlbumResponse.Root]] = for { sku ← * <~ SkuManager.mustFindSkuByContextAndCode(context.id, code) result ← * <~ getAlbumsBySku(sku) @@ -92,21 +88,20 @@ object ImageManager { payload: AlbumPayload, context: ObjectContext)(implicit ec: EC, db: DB, au: AU): DbResultT[FullAlbumWithImages] = for { - album ← * <~ ObjectUtils.insertFullObject( - payload.formAndShadow, - ins ⇒ createAlbumHeadFromInsert(context, ins, payload.scope)) + album ← * <~ ObjectUtils.insertFullObject(payload.formAndShadow, + ins ⇒ createAlbumHeadFromInsert(context, ins, payload.scope)) images ← * <~ (payload.images match { - case Some(imagesPayload) ⇒ - createImagesForAlbum(album.model, imagesPayload, context) - case None ⇒ - DbResultT.good(Seq.empty) - }) + case Some(imagesPayload) ⇒ + createImagesForAlbum(album.model, imagesPayload, context) + case None ⇒ + DbResultT.good(Seq.empty) + }) } yield (album, images) - def createOrUpdateImagesForAlbum( - album: Album, - imagesPayload: Seq[ImagePayload], - context: ObjectContext)(implicit ec: EC, db: DB, au: AU): DbResultT[Seq[FullObject[Image]]] = + def createOrUpdateImagesForAlbum(album: Album, imagesPayload: Seq[ImagePayload], context: ObjectContext)( + implicit ec: EC, + db: DB, + au: AU): DbResultT[Seq[FullObject[Image]]] = for { updatedImages ← * <~ imagesPayload.zipWithIndex.map { case (payload, index) ⇒ @@ -119,18 +114,17 @@ object ImageManager { _ ← * <~ Images.filterByIds(linksToDelete.map(_.rightId)).delete } yield updatedImages - def createOrUpdateImages(imagesPayload: Seq[ImagePayload], context: ObjectContext)( - implicit ec: EC, - db: DB, - au: AU): DbResultT[Seq[FullObject[Image]]] = + def createOrUpdateImages( + imagesPayload: Seq[ImagePayload], + context: ObjectContext)(implicit ec: EC, db: DB, au: AU): DbResultT[Seq[FullObject[Image]]] = for { images ← * <~ imagesPayload.map { payload ⇒ payload.id match { case None ⇒ for { inserted ← * <~ ObjectUtils.insertFullObject( - payload.formAndShadow, - ins ⇒ createImageHeadFromInsert(context, ins, payload.scope)) + payload.formAndShadow, + ins ⇒ createImageHeadFromInsert(context, ins, payload.scope)) } yield inserted case Some(id) ⇒ for { @@ -146,21 +140,18 @@ object ImageManager { } yield images - def createOrUpdateImageForAlbum( - album: Album, - payload: ImagePayload, - position: Int, - context: ObjectContext)(implicit ec: EC, db: DB, au: AU): DbResultT[FullObject[Image]] = + def createOrUpdateImageForAlbum(album: Album, payload: ImagePayload, position: Int, context: ObjectContext)( + implicit ec: EC, + db: DB, + au: AU): DbResultT[FullObject[Image]] = payload.id match { case None ⇒ for { inserted ← * <~ ObjectUtils.insertFullObject( - payload.formAndShadow, - ins ⇒ createImageHeadFromInsert(context, ins, payload.scope)) + payload.formAndShadow, + ins ⇒ createImageHeadFromInsert(context, ins, payload.scope)) _ ← * <~ AlbumImageLinks.create( - AlbumImageLink(leftId = album.id, - position = position, - rightId = inserted.model.id)) + AlbumImageLink(leftId = album.id, position = position, rightId = inserted.model.id)) } yield inserted case Some(id) ⇒ for { @@ -188,23 +179,20 @@ object ImageManager { au: AU): DbResultT[Seq[FullObject[Image]]] = for { images ← * <~ imagesPayload.map( - img ⇒ - ObjectUtils.insertFullObject( - img.formAndShadow, - ins ⇒ createImageHeadFromInsert(context, ins, img.scope))) + img ⇒ + ObjectUtils.insertFullObject(img.formAndShadow, + ins ⇒ createImageHeadFromInsert(context, ins, img.scope))) links ← * <~ images.zipWithIndex.map { case (image, index) ⇒ AlbumImageLinks.create( - AlbumImageLink(leftId = album.id, position = index, rightId = image.model.id)) + AlbumImageLink(leftId = album.id, position = index, rightId = image.model.id)) } } yield images - def createAlbumForProduct(admin: User, productId: ProductReference, payload: AlbumPayload)( - implicit ec: EC, - db: DB, - ac: AC, - au: AU, - oc: OC): DbResultT[AlbumRoot] = + def createAlbumForProduct( + admin: User, + productId: ProductReference, + payload: AlbumPayload)(implicit ec: EC, db: DB, ac: AC, au: AU, oc: OC): DbResultT[AlbumRoot] = for { product ← * <~ Products.mustFindByReference(productId) created ← * <~ createAlbumInner(payload, oc) @@ -212,12 +200,10 @@ object ImageManager { link ← * <~ ProductAlbumLinks.createLast(product, fullAlbum.model) } yield AlbumResponse.build(fullAlbum, images) - def createAlbumForSku(admin: User, code: String, payload: AlbumPayload)( - implicit ec: EC, - db: DB, - ac: AC, - oc: OC, - au: AU): DbResultT[AlbumRoot] = + def createAlbumForSku( + admin: User, + code: String, + payload: AlbumPayload)(implicit ec: EC, db: DB, ac: AC, oc: OC, au: AU): DbResultT[AlbumRoot] = for { sku ← * <~ SkuManager.mustFindSkuByContextAndCode(oc.id, code) created ← * <~ createAlbumInner(payload, oc) @@ -242,21 +228,15 @@ object ImageManager { oldShadow = album.shadow (payloadForm, payloadShadow) = payload.formAndShadow.tupled mergedAtts = oldShadow.attributes.merge(payloadShadow.attributes) - album ← * <~ ObjectUtils.commitUpdate[Album](album, - payloadForm.attributes, - mergedAtts, - updateAlbumHead, - force = true) - _ ← * <~ createOrUpdateImagesForAlbum(album.model, - payload.images.getOrElse(Seq.empty), - context) + album ← * <~ ObjectUtils + .commitUpdate[Album](album, payloadForm.attributes, mergedAtts, updateAlbumHead, force = true) + _ ← * <~ createOrUpdateImagesForAlbum(album.model, payload.images.getOrElse(Seq.empty), context) images ← * <~ AlbumImageLinks.queryRightByLeft(album.model) } yield (album, images) - def updateProductAlbumPosition( - albumFormId: ObjectForm#Id, - productRef: ProductReference, - position: Int)(implicit ec: EC, db: DB, oc: OC): DbResultT[Seq[AlbumRoot]] = + def updateProductAlbumPosition(albumFormId: ObjectForm#Id, + productRef: ProductReference, + position: Int)(implicit ec: EC, db: DB, oc: OC): DbResultT[Seq[AlbumRoot]] = for { product ← * <~ Products.mustFindByReference(productRef) album ← * <~ ImageManager.mustFindAlbumByFormIdAndContext404(albumFormId, oc) @@ -264,15 +244,12 @@ object ImageManager { albums ← * <~ getAlbumsForProductInner(product) } yield albums - def updateOrCreateAlbum(payload: AlbumPayload)(implicit ec: EC, - db: DB, - oc: OC, - au: AU): DbResultT[FullAlbumWithImages] = { + def updateOrCreateAlbum( + payload: AlbumPayload)(implicit ec: EC, db: DB, oc: OC, au: AU): DbResultT[FullAlbumWithImages] = payload.id match { case Some(id) ⇒ updateAlbumInner(id, payload, oc) case None ⇒ createAlbumInner(payload, oc) } - } def archiveByContextAndId(id: Int, contextName: String)(implicit ec: EC, db: DB) = for { @@ -285,15 +262,14 @@ object ImageManager { images ← * <~ getAlbumImages(albumObject.model) } yield AlbumResponse.build( - FullObject(model = archiveResult, form = albumObject.form, shadow = albumObject.shadow), - images) + FullObject(model = archiveResult, form = albumObject.form, shadow = albumObject.shadow), + images) - def mustFindFullAlbumByFormIdAndContext404(id: ObjectForm#Id, - context: ObjectContext)(implicit ec: EC, db: DB) = + def mustFindFullAlbumByFormIdAndContext404(id: ObjectForm#Id, context: ObjectContext)(implicit ec: EC, + db: DB) = ObjectManager.getFullObject(mustFindAlbumByFormIdAndContext404(id, context)) - def mustFindAlbumByFormIdAndContext404(id: Int, context: ObjectContext)(implicit ec: EC, - db: DB) = + def mustFindAlbumByFormIdAndContext404(id: Int, context: ObjectContext)(implicit ec: EC, db: DB) = Albums .filterByContextAndFormId(context.id, id) .mustFindOneOr(AlbumNotFoundForContext(id, context.id)) @@ -301,8 +277,7 @@ object ImageManager { def getAlbumImages(album: Album)(implicit ec: EC, db: DB): DbResultT[Seq[FullObject[Image]]] = for { imageIds ← * <~ AlbumImageLinks.filterLeft(album).sortBy(_.position).map(_.rightId).result - images ← * <~ imageIds.map(imgId ⇒ - ObjectManager.getFullObject(Images.mustFindById404(imgId))) + images ← * <~ imageIds.map(imgId ⇒ ObjectManager.getFullObject(Images.mustFindById404(imgId))) } yield images def getFirstImageForAlbum(album: Album)(implicit ec: EC, db: DB): DbResultT[Option[String]] = @@ -319,49 +294,47 @@ object ImageManager { } } yield src - private def createAlbumHeadFromInsert( - oc: ObjectContext, - insert: InsertResult, - maybeScope: Option[String])(implicit ec: EC, db: DB, au: AU): DbResultT[Album] = + private def createAlbumHeadFromInsert(oc: ObjectContext, insert: InsertResult, maybeScope: Option[String])( + implicit ec: EC, + db: DB, + au: AU): DbResultT[Album] = for { scope ← * <~ Scope.resolveOverride(maybeScope) album ← * <~ Albums.create( - Album(scope = scope, - contextId = oc.id, - shadowId = insert.shadow.id, - formId = insert.form.id, - commitId = insert.commit.id)) + Album(scope = scope, + contextId = oc.id, + shadowId = insert.shadow.id, + formId = insert.form.id, + commitId = insert.commit.id)) } yield album - private def updateAlbumHead(fullObject: FullObject[Album], commitId: Int)( - implicit ec: EC, - db: DB): DbResultT[FullObject[Album]] = + private def updateAlbumHead(fullObject: FullObject[Album], + commitId: Int)(implicit ec: EC, db: DB): DbResultT[FullObject[Album]] = for { newModel ← * <~ Albums.update( - fullObject.model, - fullObject.model.copy(shadowId = fullObject.shadow.id, commitId = commitId)) + fullObject.model, + fullObject.model.copy(shadowId = fullObject.shadow.id, commitId = commitId)) } yield fullObject.copy(model = newModel) - private def createImageHeadFromInsert( - oc: ObjectContext, - ins: InsertResult, - maybeScope: Option[String])(implicit ec: EC, db: DB, au: AU): DbResultT[Image] = + private def createImageHeadFromInsert(oc: ObjectContext, ins: InsertResult, maybeScope: Option[String])( + implicit ec: EC, + db: DB, + au: AU): DbResultT[Image] = for { scope ← * <~ Scope.resolveOverride(maybeScope) image ← * <~ Images.create( - Image(scope = scope, - contextId = oc.id, - shadowId = ins.shadow.id, - formId = ins.form.id, - commitId = ins.commit.id)) + Image(scope = scope, + contextId = oc.id, + shadowId = ins.shadow.id, + formId = ins.form.id, + commitId = ins.commit.id)) } yield image - private def updateImageHead(fullObject: FullObject[Image], commitId: Int)( - implicit ec: EC, - db: DB): DbResultT[FullObject[Image]] = + private def updateImageHead(fullObject: FullObject[Image], + commitId: Int)(implicit ec: EC, db: DB): DbResultT[FullObject[Image]] = for { newModel ← * <~ Images.update( - fullObject.model, - fullObject.model.copy(shadowId = fullObject.shadow.id, commitId = commitId)) + fullObject.model, + fullObject.model.copy(shadowId = fullObject.shadow.id, commitId = commitId)) } yield fullObject.copy(model = newModel) } diff --git a/phoenix-scala/phoenix/app/phoenix/services/inventory/SkuManager.scala b/phoenix-scala/phoenix/app/phoenix/services/inventory/SkuManager.scala index 1691a4ccea..aba4fcc556 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/inventory/SkuManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/inventory/SkuManager.scala @@ -28,11 +28,9 @@ import slick.jdbc.PostgresProfile.api._ object SkuManager { implicit val formats = JsonFormatters.DefaultFormats - def createSku(admin: User, payload: SkuPayload)(implicit ec: EC, - db: DB, - ac: AC, - oc: OC, - au: AU): DbResultT[SkuResponse.Root] = { + def createSku( + admin: User, + payload: SkuPayload)(implicit ec: EC, db: DB, ac: AC, oc: OC, au: AU): DbResultT[SkuResponse.Root] = { val albumPayloads = payload.albums.getOrElse(Seq.empty) for { @@ -54,12 +52,10 @@ object SkuManager { albums ← * <~ ImageManager.getAlbumsForSkuInner(sku.code, oc) } yield SkuResponse.build(IlluminatedSku.illuminate(oc, FullObject(sku, form, shadow)), albums) - def updateSku(admin: User, code: String, payload: SkuPayload)( - implicit ec: EC, - db: DB, - ac: AC, - oc: OC, - au: AU): DbResultT[SkuResponse.Root] = + def updateSku( + admin: User, + code: String, + payload: SkuPayload)(implicit ec: EC, db: DB, ac: AC, oc: OC, au: AU): DbResultT[SkuResponse.Root] = for { sku ← * <~ SkuManager.mustFindSkuByContextAndCode(oc.id, code) updatedSku ← * <~ updateSkuInner(sku, payload) @@ -70,27 +66,22 @@ object SkuManager { def archiveByCode(code: String)(implicit ec: EC, db: DB, oc: OC): DbResultT[SkuResponse.Root] = for { - fullSku ← * <~ ObjectManager.getFullObject( - SkuManager.mustFindSkuByContextAndCode(oc.id, code)) - _ ← * <~ fullSku.model.mustNotBePresentInCarts - archivedSku ← * <~ Skus.update(fullSku.model, - fullSku.model.copy(archivedAt = Some(Instant.now))) + fullSku ← * <~ ObjectManager.getFullObject(SkuManager.mustFindSkuByContextAndCode(oc.id, code)) + _ ← * <~ fullSku.model.mustNotBePresentInCarts + archivedSku ← * <~ Skus.update(fullSku.model, fullSku.model.copy(archivedAt = Some(Instant.now))) albumLinks ← * <~ SkuAlbumLinks.filterLeft(archivedSku).result _ ← * <~ albumLinks.map(l ⇒ SkuAlbumLinks.update(l, l.copy(archivedAt = Some(Instant.now)))) albums ← * <~ ImageManager.getAlbumsForSkuInner(archivedSku.code, oc) productLinks ← * <~ ProductSkuLinks.filterRight(archivedSku).result - _ ← * <~ productLinks.map(l ⇒ - ProductSkuLinks.update(l, l.copy(archivedAt = Some(Instant.now)))) + _ ← * <~ productLinks.map(l ⇒ ProductSkuLinks.update(l, l.copy(archivedAt = Some(Instant.now)))) } yield - SkuResponse.build( - IlluminatedSku.illuminate( - oc, - FullObject(model = archivedSku, form = fullSku.form, shadow = fullSku.shadow)), - albums) + SkuResponse.build(IlluminatedSku.illuminate( + oc, + FullObject(model = archivedSku, form = fullSku.form, shadow = fullSku.shadow)), + albums) - def createSkuInner( - context: ObjectContext, - payload: SkuPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[FullObject[Sku]] = { + def createSkuInner(context: ObjectContext, + payload: SkuPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[FullObject[Sku]] = { val form = ObjectForm.fromPayload(Sku.kind, payload.attributes) val shadow = ObjectShadow.fromPayload(payload.attributes) @@ -100,17 +91,16 @@ object SkuManager { code ← * <~ mustGetSkuCode(payload) ins ← * <~ ObjectUtils.insert(form, shadow, payload.schema) sku ← * <~ Skus.create( - Sku(scope = scope, - contextId = context.id, - code = code, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) + Sku(scope = scope, + contextId = context.id, + code = code, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) } yield FullObject(sku, ins.form, ins.shadow) } - def updateSkuInner(sku: Sku, payload: SkuPayload)(implicit ec: EC, - db: DB): DbResultT[FullObject[Sku]] = { + def updateSkuInner(sku: Sku, payload: SkuPayload)(implicit ec: EC, db: DB): DbResultT[FullObject[Sku]] = { val newFormAttrs = ObjectForm.fromPayload(Sku.kind, payload.attributes).attributes val newShadowAttrs = ObjectShadow.fromPayload(payload.attributes).attributes @@ -137,10 +127,8 @@ object SkuManager { } } yield sku - private def updateHead(sku: Sku, - code: String, - shadow: ObjectShadow, - maybeCommit: Option[ObjectCommit])(implicit ec: EC): DbResultT[Sku] = + private def updateHead(sku: Sku, code: String, shadow: ObjectShadow, maybeCommit: Option[ObjectCommit])( + implicit ec: EC): DbResultT[Sku] = maybeCommit match { case Some(commit) ⇒ Skus.update(sku, sku.copy(code = code, shadowId = shadow.id, commitId = commit.id)) @@ -189,17 +177,15 @@ object SkuManager { def mustFindFullSkuById(id: Int)(implicit ec: EC, db: DB): DbResultT[FullObject[Sku]] = ObjectManager.getFullObject(Skus.filter(_.id === id).mustFindOneOr(SkuNotFound(id))) - def mustFindFullSkuByIdAndShadowId(skuId: Int, shadowId: Int)( - implicit ec: EC, - db: DB): DbResultT[FullObject[Sku]] = + def mustFindFullSkuByIdAndShadowId(skuId: Int, shadowId: Int)(implicit ec: EC, + db: DB): DbResultT[FullObject[Sku]] = for { shadow ← * <~ ObjectShadows.mustFindById404(shadowId) form ← * <~ ObjectForms.mustFindById404(shadow.formId) sku ← * <~ Skus.mustFindById404(skuId) } yield FullObject(sku, form, shadow) - def illuminateSku( - fullSku: FullObject[Sku])(implicit ec: EC, db: DB, oc: OC): DbResultT[SkuResponse.Root] = + def illuminateSku(fullSku: FullObject[Sku])(implicit ec: EC, db: DB, oc: OC): DbResultT[SkuResponse.Root] = ImageManager .getAlbumsBySku(fullSku.model) .map(albums ⇒ SkuResponse.buildLite(IlluminatedSku.illuminate(oc, fullSku), albums)) diff --git a/phoenix-scala/phoenix/app/phoenix/services/migration/CustomerImportService.scala b/phoenix-scala/phoenix/app/phoenix/services/migration/CustomerImportService.scala index d064c9fc83..5e40106644 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/migration/CustomerImportService.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/migration/CustomerImportService.scala @@ -24,10 +24,10 @@ object CustomerImportService { checkEmail = true, isMigrated = true) custData ← * <~ CustomersData.create( - CustomerData(accountId = user.accountId, - userId = user.id, - scope = scope.ltree, - isGuest = payload.isGuest.getOrElse(false))) + CustomerData(accountId = user.accountId, + userId = user.id, + scope = scope.ltree, + isGuest = payload.isGuest.getOrElse(false))) result = build(user, custData) _ ← * <~ LogActivity().withScope(scope.ltree).customerCreated(result, admin) } yield result diff --git a/phoenix-scala/phoenix/app/phoenix/services/notes/NoteManager.scala b/phoenix-scala/phoenix/app/phoenix/services/notes/NoteManager.scala index 9168cc6045..43e47865c6 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/notes/NoteManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/notes/NoteManager.scala @@ -60,18 +60,17 @@ trait NoteManager[K, T <: Identity[T]] { private def entityQuerySeq(entityId: Int)(implicit ec: EC, db: DB, ac: AC): Notes.QuerySeq = Notes.filter(_.referenceType === noteType()).filter(_.referenceId === entityId).notDeleted - private def createInner( - entity: T, - refType: Note.ReferenceType, - author: User, - payload: CreateNote)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[Note] = + private def createInner(entity: T, + refType: Note.ReferenceType, + author: User, + payload: CreateNote)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[Note] = for { note ← * <~ Notes.create( - Note(storeAdminId = author.accountId, - referenceId = getEntityId(entity), - referenceType = refType, - body = payload.body, - scope = Scope.current)) + Note(storeAdminId = author.accountId, + referenceId = getEntityId(entity), + referenceType = refType, + body = payload.body, + scope = Scope.current)) _ ← * <~ LogActivity().noteCreated(author, entity, note) } yield note @@ -92,15 +91,16 @@ trait NoteManager[K, T <: Identity[T]] { ac: AC): DbResultT[Unit] = for { note ← * <~ Notes.mustFindById404(noteId) - _ ← * <~ Notes.update( - note, - note.copy(deletedAt = Some(Instant.now), deletedBy = Some(admin.accountId))) - _ ← * <~ LogActivity().noteDeleted(admin, entity, note) + _ ← * <~ Notes.update(note, note.copy(deletedAt = Some(Instant.now), deletedBy = Some(admin.accountId))) + _ ← * <~ LogActivity().noteDeleted(admin, entity, note) } yield () private def forModel[M <: FoxModel[M]]( finder: Notes.QuerySeq)(implicit ec: EC, db: DB, ac: AC): DbResultT[Seq[Root]] = { - val query = for (notes ← finder; authors ← notes.author) yield (notes, authors) + val query = for { + notes ← finder + authors ← notes.author + } yield (notes, authors) DbResultT.fromF(query.result.map(_.map { case (note, author) ⇒ AdminNotes.build(note, author) })) diff --git a/phoenix-scala/phoenix/app/phoenix/services/notes/package.scala b/phoenix-scala/phoenix/app/phoenix/services/notes/package.scala index d9c60d32a4..8a834e91cf 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/notes/package.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/notes/package.scala @@ -14,30 +14,31 @@ import slick.jdbc.PostgresProfile.api._ package object notes { def forModel[M <: FoxModel[M]](finder: Notes.QuerySeq)(implicit ec: EC): DbResultT[Seq[Root]] = { - val query = for (notes ← finder; authors ← notes.author) yield (notes, authors) + val query = for { + notes ← finder + authors ← notes.author + } yield (notes, authors) DbResultT.fromF(query.result.map(_.map { case (note, author) ⇒ AdminNotes.build(note, author) })) } - def createNote[T](entity: T, - refId: Int, - refType: Note.ReferenceType, - author: User, - payload: CreateNote)(implicit ec: EC, ac: AC, au: AU): DbResultT[Note] = + def createNote[T](entity: T, refId: Int, refType: Note.ReferenceType, author: User, payload: CreateNote)( + implicit ec: EC, + ac: AC, + au: AU): DbResultT[Note] = for { note ← * <~ Notes.create( - Note(storeAdminId = author.id, - referenceId = refId, - referenceType = refType, - body = payload.body, - scope = Scope.current)) + Note(storeAdminId = author.id, + referenceId = refId, + referenceType = refType, + body = payload.body, + scope = Scope.current)) _ ← * <~ LogActivity().noteCreated(author, entity, note) } yield note - def updateNote[T](entity: T, noteId: Int, author: User, payload: UpdateNote)( - implicit ec: EC, - ac: AC): DbResultT[Root] = + def updateNote[T](entity: T, noteId: Int, author: User, payload: UpdateNote)(implicit ec: EC, + ac: AC): DbResultT[Root] = for { oldNote ← * <~ Notes .filterByIdAndAdminId(noteId, author.id) @@ -46,14 +47,10 @@ package object notes { _ ← * <~ LogActivity().noteUpdated(author, entity, oldNote, newNote) } yield AdminNotes.build(newNote, author) - def deleteNote[T](entity: T, noteId: Int, admin: User)(implicit ec: EC, - db: DB, - ac: AC): DbResultT[Unit] = + def deleteNote[T](entity: T, noteId: Int, admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[Unit] = for { note ← * <~ Notes.mustFindById404(noteId) - _ ← * <~ Notes.update( - note, - note.copy(deletedAt = Some(Instant.now), deletedBy = Some(admin.accountId))) - _ ← * <~ LogActivity().noteDeleted(admin, entity, note) + _ ← * <~ Notes.update(note, note.copy(deletedAt = Some(Instant.now), deletedBy = Some(admin.accountId))) + _ ← * <~ LogActivity().noteDeleted(admin, entity, note) } yield {} } diff --git a/phoenix-scala/phoenix/app/phoenix/services/orders/OrderQueries.scala b/phoenix-scala/phoenix/app/phoenix/services/orders/OrderQueries.scala index 070d9fd719..7393b8ca77 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/orders/OrderQueries.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/orders/OrderQueries.scala @@ -27,10 +27,9 @@ object OrderQueries extends CordQueries { } yield TheResponse.build(response) } - def findOne(refNum: String, grouped: Boolean = true)( - implicit ec: EC, - db: DB, - ctx: OC): DbResultT[TheResponse[OrderResponse]] = + def findOne(refNum: String, grouped: Boolean = true)(implicit ec: EC, + db: DB, + ctx: OC): DbResultT[TheResponse[OrderResponse]] = for { order ← * <~ Orders.mustFindByRefNum(refNum) response ← * <~ OrderResponse.fromOrder(order, grouped) @@ -55,9 +54,8 @@ object OrderQueries extends CordQueries { response ← * <~ OrderResponse.fromOrder(order, grouped) } yield TheResponse.build(response) - private def buildResponse(order: Order, grouped: Boolean)(implicit ec: EC, - db: DB, - ctx: OC): DbResultT[OrderResponse] = + private def buildResponse(order: Order, + grouped: Boolean)(implicit ec: EC, db: DB, ctx: OC): DbResultT[OrderResponse] = for { response ← * <~ OrderResponse.fromOrder(order, grouped) } yield response diff --git a/phoenix-scala/phoenix/app/phoenix/services/orders/OrderStateUpdater.scala b/phoenix-scala/phoenix/app/phoenix/services/orders/OrderStateUpdater.scala index 26ee447fbf..89acc107f1 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/orders/OrderStateUpdater.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/orders/OrderStateUpdater.scala @@ -21,32 +21,28 @@ import slick.jdbc.PostgresProfile.api._ object OrderStateUpdater { - def updateState(admin: User, refNum: String, newState: Order.State)( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[OrderResponse] = + def updateState(admin: User, refNum: String, newState: Order.State)(implicit ec: EC, + db: DB, + ac: AC): DbResultT[OrderResponse] = for { order ← * <~ Orders.mustFindByRefNum(refNum) _ ← * <~ order.transitionState(newState) _ ← * <~ updateQueries(admin, Seq(refNum), newState) updated ← * <~ Orders.mustFindByRefNum(refNum) response ← * <~ OrderResponse.fromOrder(updated, grouped = true) - _ ← * <~ doOrMeh(order.state != newState, - LogActivity().orderStateChanged(admin, response, order.state)) + _ ← * <~ doOrMeh(order.state != newState, LogActivity().orderStateChanged(admin, response, order.state)) } yield response def updateStates(admin: User, refNumbers: Seq[String], newState: Order.State, - skipActivity: Boolean = false)( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[BatchResponse[AllOrders.Root]] = + skipActivity: Boolean = false)(implicit ec: EC, + db: DB, + ac: AC): DbResultT[BatchResponse[AllOrders.Root]] = for { // Turn failures into errors batchMetadata ← * <~ updateStatesDbio(admin, refNumbers, newState, skipActivity) - response ← * <~ OrderQueries.findAllByQuery( - Orders.filter(_.referenceNumber.inSetBind(refNumbers))) + response ← * <~ OrderQueries.findAllByQuery(Orders.filter(_.referenceNumber.inSetBind(refNumbers))) } yield response.copy(errors = batchMetadata.flatten, batch = Some(batchMetadata)) private def updateStatesDbio( @@ -66,7 +62,7 @@ object OrderStateUpdater { updateQueriesWrapper(admin, possibleRefNums, newState, skipActivityMod).flatMap { _ ⇒ // Failure handling val invalid = invalidTransitions.map(o ⇒ - (o.refNum, StateTransitionNotAllowed(o.state, newState, o.refNum).description)) + (o.refNum, StateTransitionNotAllowed(o.state, newState, o.refNum).description)) val notFound = refNumbers .filterNot(refNum ⇒ orders.map(_.referenceNumber).contains(refNum)) .map(refNum ⇒ (refNum, NotFoundFailure400(Order, refNum).description)) @@ -81,8 +77,7 @@ object OrderStateUpdater { admin: User, cordRefs: Seq[String], newState: State, - skipActivity: Boolean = false)(implicit ec: EC, ac: AC, db: DB): DbResultT[Unit] = { - + skipActivity: Boolean = false)(implicit ec: EC, ac: AC, db: DB): DbResultT[Unit] = if (skipActivity) updateQueries(admin, cordRefs, newState) else @@ -90,11 +85,9 @@ object OrderStateUpdater { _ ← * <~ LogActivity().orderBulkStateChanged(newState, cordRefs, admin.some) _ ← * <~ updateQueries(admin, cordRefs, newState) } yield () - } - private def updateQueries(admin: User, cordRefs: Seq[String], newState: State)( - implicit ec: EC, - db: DB): DbResultT[Unit] = + private def updateQueries(admin: User, cordRefs: Seq[String], newState: State)(implicit ec: EC, + db: DB): DbResultT[Unit] = newState match { case Canceled ⇒ cancelOrders(cordRefs) @@ -116,14 +109,12 @@ object OrderStateUpdater { _ ← * <~ Orders.filter(_.referenceNumber.inSetBind(cordRefs)).map(_.state).update(Canceled) } yield () - private def cancelGiftCards(orderPayments: Seq[OrderPayment])(implicit ec: EC, - db: DB): DBIO[Int] = { + private def cancelGiftCards(orderPayments: Seq[OrderPayment])(implicit ec: EC, db: DB): DBIO[Int] = { val paymentIds = orderPayments.map(_.id) GiftCardAdjustments.filter(_.orderPaymentId.inSetBind(paymentIds)).cancel() } - private def cancelStoreCredits(orderPayments: Seq[OrderPayment])(implicit ec: EC, - db: DB): DBIO[Int] = { + private def cancelStoreCredits(orderPayments: Seq[OrderPayment])(implicit ec: EC, db: DB): DBIO[Int] = { val paymentIds = orderPayments.map(_.id) StoreCreditAdjustments.filter(_.orderPaymentId.inSetBind(paymentIds)).cancel() } diff --git a/phoenix-scala/phoenix/app/phoenix/services/orders/OrderUpdater.scala b/phoenix-scala/phoenix/app/phoenix/services/orders/OrderUpdater.scala index 302554e852..88f805762b 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/orders/OrderUpdater.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/orders/OrderUpdater.scala @@ -10,15 +10,14 @@ import core.db._ object OrderUpdater { - def increaseRemorsePeriod(refNum: String, admin: User)(implicit ec: EC, - db: DB, - ac: AC): DbResultT[OrderResponse] = + def increaseRemorsePeriod(refNum: String, + admin: User)(implicit ec: EC, db: DB, ac: AC): DbResultT[OrderResponse] = for { order ← * <~ Orders.mustFindByRefNum(refNum) isRemorse ← * <~ order.mustBeRemorseHold updated ← * <~ Orders.update( - order, - order.copy(remorsePeriodEnd = order.remorsePeriodEnd.map(_.plusMinutes(15)))) + order, + order.copy(remorsePeriodEnd = order.remorsePeriodEnd.map(_.plusMinutes(15)))) response ← * <~ OrderResponse.fromOrder(updated, grouped = true) _ ← * <~ LogActivity().orderRemorsePeriodIncreased(admin, response, order.remorsePeriodEnd) } yield response diff --git a/phoenix-scala/phoenix/app/phoenix/services/orders/TimeMachine.scala b/phoenix-scala/phoenix/app/phoenix/services/orders/TimeMachine.scala index 22207d3d90..8dd1b35639 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/orders/TimeMachine.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/orders/TimeMachine.scala @@ -7,8 +7,7 @@ import phoenix.models.cord.{Order, Orders} object TimeMachine { - def changePlacedAt(refNum: String, placedAt: Instant)(implicit ec: EC, - db: DB): DbResultT[Order] = + def changePlacedAt(refNum: String, placedAt: Instant)(implicit ec: EC, db: DB): DbResultT[Order] = for { order ← * <~ Orders.mustFindByRefNum(refNum) updated ← * <~ Orders.update(order, order.copy(placedAt = placedAt)) diff --git a/phoenix-scala/phoenix/app/phoenix/services/plugins/PluginsManager.scala b/phoenix-scala/phoenix/app/phoenix/services/plugins/PluginsManager.scala index 6b706c98dc..498c0bd383 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/plugins/PluginsManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/plugins/PluginsManager.scala @@ -20,73 +20,66 @@ import scala.concurrent.Future object PluginsManager extends LazyLogging { - private def getSchemaSettings( - plugin: Plugin, - payload: RegisterPluginPayload, - foundOrCreated: FoundOrCreated)(implicit ec: EC): DbResultT[SettingsSchema] = + private def getSchemaSettings(plugin: Plugin, + payload: RegisterPluginPayload, + foundOrCreated: FoundOrCreated)(implicit ec: EC): DbResultT[SettingsSchema] = payload.schemaSettings.fold { plugin .apiUrl() - .fold(DbResultT.failure[SettingsSchema]( - GeneralFailure("settingsSchema or apiUrl should be " + - "present"))) { apiUrl ⇒ + .fold(DbResultT.failure[SettingsSchema](GeneralFailure("settingsSchema or apiUrl should be " + + "present"))) { apiUrl ⇒ val req = host(apiUrl) / "_settings" / "schema" DbResultT.fromF(DBIO.from(Http(req OK as.json4s.Json).map(_.extract[SettingsSchema]))) } }(DbResultT.good(_)) - def uploadNewSettingsToPlugin(plugin: Plugin)(implicit ec: EC, - formats: Formats): Future[String] = { + def uploadNewSettingsToPlugin(plugin: Plugin)(implicit ec: EC, formats: Formats): Future[String] = plugin.apiUrl().fold(Future.successful("")) { apiUrl ⇒ val rawReq = host(apiUrl) / "_settings" / "upload" val body = compact(render(plugin.settings.toJson)) val req = rawReq.setContentType("application/json", "UTF-8") << body - logger.info( - s"Updating plugin ${plugin.name} at ${plugin.apiHost}:${plugin.apiPort}: ${body}") + logger.info(s"Updating plugin ${plugin.name} at ${plugin.apiHost}:${plugin.apiPort}: $body") val resp = Http(req.POST OK as.String) resp.map { respBody ⇒ logger.info(s"Plugin Response: $respBody") respBody } } - } - private def updatePluginInfo( - plugin: Plugin, - schema: SettingsSchema, - payload: RegisterPluginPayload)(implicit ec: EC): DbResultT[Plugin] = { - val newSettings = schema.filterNot { s ⇒ - plugin.settings.contains(s.name) - }.foldLeft(plugin.settings) { (settings, schemaSetting) ⇒ - settings + (schemaSetting.name → schemaSetting.default) - } - Plugins.update(plugin, - plugin.copy(settings = newSettings, - schemaSettings = schema, - apiHost = payload.apiHost, - apiPort = payload.apiPort, - version = payload.version, - description = payload.description)) + private def updatePluginInfo(plugin: Plugin, schema: SettingsSchema, payload: RegisterPluginPayload)( + implicit ec: EC): DbResultT[Plugin] = { + val newSettings = schema + .filterNot { s ⇒ + plugin.settings.contains(s.name) + } + .foldLeft(plugin.settings) { (settings, schemaSetting) ⇒ + settings + (schemaSetting.name → schemaSetting.default) + } + Plugins.update( + plugin, + plugin.copy(settings = newSettings, + schemaSettings = schema, + apiHost = payload.apiHost, + apiPort = payload.apiPort, + version = payload.version, + description = payload.description) + ) } - private def updatePlugin(plugin: Plugin, - payload: RegisterPluginPayload, - foundOrCreated: FoundOrCreated)(implicit ec: EC): DbResultT[Plugin] = + private def updatePlugin(plugin: Plugin, payload: RegisterPluginPayload, foundOrCreated: FoundOrCreated)( + implicit ec: EC): DbResultT[Plugin] = for { schema ← * <~ getSchemaSettings(plugin, payload, foundOrCreated) plugin ← * <~ updatePluginInfo(plugin, schema, payload) } yield plugin - def listPlugins()(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[ListPluginsAnswer] = { + def listPlugins()(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[ListPluginsAnswer] = for { plugins ← * <~ Plugins.forCurrentUser.result } yield plugins.map(PluginInfo.fromPlugin) - } - def registerPlugin(payload: RegisterPluginPayload)(implicit ec: EC, - db: DB, - au: AU, - ac: AC): DbResultT[RegisterAnswer] = { + def registerPlugin( + payload: RegisterPluginPayload)(implicit ec: EC, db: DB, au: AU, ac: AC): DbResultT[RegisterAnswer] = { val pluginT = for { result ← * <~ Plugins .findByName(payload.name) @@ -105,11 +98,9 @@ object PluginsManager extends LazyLogging { } } - def updateSettings(name: String, payload: UpdateSettingsPayload)( - implicit ec: EC, - db: DB, - au: AU, - ac: AC): DbResultT[SettingsUpdated] = { + def updateSettings( + name: String, + payload: UpdateSettingsPayload)(implicit ec: EC, db: DB, au: AU, ac: AC): DbResultT[SettingsUpdated] = { val updated = for { plugin ← * <~ Plugins .findByName(name) @@ -128,24 +119,21 @@ object PluginsManager extends LazyLogging { } } - def listSettings( - name: String)(implicit ec: EC, db: DB, au: AU, ac: AC): DbResultT[SettingsValues] = { + def listSettings(name: String)(implicit ec: EC, db: DB, au: AU, ac: AC): DbResultT[SettingsValues] = for { plugin ← * <~ Plugins .findByName(name) .forCurrentUser .mustFindOneOr(NotFoundFailure404(Plugin, name)) } yield plugin.settings - } def getSettingsWithSchema( - name: String)(implicit ec: EC, db: DB, au: AU, ac: AC): DbResultT[PluginSettingsResponse] = { + name: String)(implicit ec: EC, db: DB, au: AU, ac: AC): DbResultT[PluginSettingsResponse] = for { plugin ← * <~ Plugins .findByName(name) .forCurrentUser .mustFindOneOr(NotFoundFailure404(Plugin, name)) } yield PluginSettingsResponse.fromPlugin(plugin) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/services/product/ProductManager.scala b/phoenix-scala/phoenix/app/phoenix/services/product/ProductManager.scala index 5fd9897d6f..8a58d15f4a 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/product/ProductManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/product/ProductManager.scala @@ -45,12 +45,11 @@ object ProductManager extends LazyLogging { implicit val formats: Formats = JsonFormatters.phoenixFormats - def createProduct(admin: User, payload: CreateProductPayload)( - implicit ec: EC, - db: DB, - ac: AC, - oc: OC, - au: AU): DbResultT[ProductResponse.Root] = { + def createProduct(admin: User, payload: CreateProductPayload)(implicit ec: EC, + db: DB, + ac: AC, + oc: OC, + au: AU): DbResultT[ProductResponse.Root] = { val form = ObjectForm.fromPayload(Product.kind, payload.attributes) val shadow = ObjectShadow.fromPayload(payload.attributes) @@ -63,12 +62,12 @@ object ProductManager extends LazyLogging { _ ← * <~ validateCreate(payload) ins ← * <~ ObjectUtils.insert(form, shadow, payload.schema) product ← * <~ Products.create( - Product(scope = scope, - slug = payload.slug, - contextId = oc.id, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) + Product(scope = scope, + slug = payload.slug, + contextId = oc.id, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) albums ← * <~ findOrCreateAlbumsForProduct(product, albumPayloads) productSkus ← * <~ findOrCreateSkusForProduct(product, payload.skus, !hasVariants) @@ -77,11 +76,12 @@ object ProductManager extends LazyLogging { (variantSkus, variantResponses) = variantAndSkus taxons ← * <~ TaxonomyManager.getAssignedTaxons(product) response = ProductResponse.build( - IlluminatedProduct.illuminate(oc, product, ins.form, ins.shadow), - albums.map(AlbumResponse.build), - if (hasVariants) variantSkus else productSkus, - variantResponses, - taxons) + IlluminatedProduct.illuminate(oc, product, ins.form, ins.shadow), + albums.map(AlbumResponse.build), + if (hasVariants) variantSkus else productSkus, + variantResponses, + taxons + ) _ ← * <~ LogActivity() .withScope(scope) .fullProductCreated(Some(admin), response, ObjectContextResponse.build(oc)) @@ -89,22 +89,23 @@ object ProductManager extends LazyLogging { } - def getProduct( - productId: ProductReference, - checkActive: Boolean)(implicit ec: EC, db: DB, oc: OC): DbResultT[ProductResponse.Root] = + def getProduct(productId: ProductReference, + checkActive: Boolean)(implicit ec: EC, db: DB, oc: OC): DbResultT[ProductResponse.Root] = for { oldProduct ← * <~ Products.mustFindFullByReference(productId) illuminated = IlluminatedProduct .illuminate(oc, oldProduct.model, oldProduct.form, oldProduct.shadow) - _ ← * <~ doOrMeh(checkActive, { - illuminated.mustBeActive match { - case Left(err) ⇒ { - logger.warn(err.toString) - DbResultT.failure(NotFoundFailure404(Product, oldProduct.model.slug)) + _ ← * <~ doOrMeh( + checkActive, { + illuminated.mustBeActive match { + case Left(err) ⇒ { + logger.warn(err.toString) + DbResultT.failure(NotFoundFailure404(Product, oldProduct.model.slug)) + } + case Right(_) ⇒ DbResultT.unit } - case Right(_) ⇒ DbResultT.unit } - }) + ) albums ← * <~ ImageManager.getAlbumsForProduct(oldProduct.model.reference) fullSkus ← * <~ ProductSkuLinks.queryRightByLeft(oldProduct.model) @@ -118,11 +119,13 @@ object ProductManager extends LazyLogging { variantAndSkus ← * <~ getVariantsWithRelatedSkus(fullVariants) (variantSkus, variantResponses) = variantAndSkus skus = if (hasVariants) variantSkus else productSkus - _ ← * <~ failIf(checkActive && !skus.exists(_.isActive), { - logger.warn( + _ ← * <~ failIf( + checkActive && !skus.exists(_.isActive), { + logger.warn( s"Product variants for product with id=${oldProduct.model.slug} is archived or inactive") - NotFoundFailure404(Product, oldProduct.model.slug) - }) + NotFoundFailure404(Product, oldProduct.model.slug) + } + ) taxons ← * <~ TaxonomyManager.getAssignedTaxons(oldProduct.model) } yield ProductResponse.build(illuminated, albums, skus, variantResponses, taxons) @@ -167,21 +170,19 @@ object ProductManager extends LazyLogging { (variantSkus, variantResponses) = variantAndSkus taxons ← * <~ TaxonomyManager.getAssignedTaxons(oldProduct.model) response = ProductResponse.build( - IlluminatedProduct.illuminate(oc, updatedHead, updated.form, updated.shadow), - albums, - if (hasVariants) variantSkus else updatedSkus, - variantResponses, - taxons) + IlluminatedProduct.illuminate(oc, updatedHead, updated.form, updated.shadow), + albums, + if (hasVariants) variantSkus else updatedSkus, + variantResponses, + taxons) _ ← * <~ LogActivity() .fullProductUpdated(Some(au.model), response, ObjectContextResponse.build(oc)) } yield response } - def archiveByContextAndId(productId: ProductReference)( - implicit ec: EC, - db: DB, - oc: OC): DbResultT[ProductResponse.Root] = { + def archiveByContextAndId( + productId: ProductReference)(implicit ec: EC, db: DB, oc: OC): DbResultT[ProductResponse.Root] = { val payload = Map("activeFrom" → (("v" → JNull) ~ ("t" → JString("datetime"))), "activeTo" → (("v" → JNull) ~ ("t" → JString("datetime")))) @@ -200,20 +201,17 @@ object ProductManager extends LazyLogging { commit ← * <~ ObjectUtils.commit(inactive) updatedHead ← * <~ updateHead(productObject.model, inactive.shadow, commit, None) - archiveResult ← * <~ Products.update(updatedHead, - updatedHead.copy(archivedAt = Some(Instant.now))) - - albumLinks ← * <~ ProductAlbumLinks.filterLeft(archiveResult).result - _ ← * <~ albumLinks.map(l ⇒ - ProductAlbumLinks.update(l, l.copy(archivedAt = Some(Instant.now)))) - albums ← * <~ ImageManager.getAlbumsForProduct(ProductReference(inactive.form.id)) - skuLinks ← * <~ ProductSkuLinks.filterLeft(archiveResult).result - _ ← * <~ skuLinks.map(l ⇒ ProductSkuLinks.update(l, l.copy(archivedAt = Some(Instant.now)))) - updatedSkus ← * <~ ProductSkuLinks.queryRightByLeft(archiveResult) - skus ← * <~ updatedSkus.map(SkuManager.illuminateSku) - variantLinks ← * <~ ProductVariantLinks.filterLeft(archiveResult).result - _ ← * <~ variantLinks.map(l ⇒ - ProductVariantLinks.update(l, l.copy(archivedAt = Some(Instant.now)))) + archiveResult ← * <~ Products.update(updatedHead, updatedHead.copy(archivedAt = Some(Instant.now))) + + albumLinks ← * <~ ProductAlbumLinks.filterLeft(archiveResult).result + _ ← * <~ albumLinks.map(l ⇒ ProductAlbumLinks.update(l, l.copy(archivedAt = Some(Instant.now)))) + albums ← * <~ ImageManager.getAlbumsForProduct(ProductReference(inactive.form.id)) + skuLinks ← * <~ ProductSkuLinks.filterLeft(archiveResult).result + _ ← * <~ skuLinks.map(l ⇒ ProductSkuLinks.update(l, l.copy(archivedAt = Some(Instant.now)))) + updatedSkus ← * <~ ProductSkuLinks.queryRightByLeft(archiveResult) + skus ← * <~ updatedSkus.map(SkuManager.illuminateSku) + variantLinks ← * <~ ProductVariantLinks.filterLeft(archiveResult).result + _ ← * <~ variantLinks.map(l ⇒ ProductVariantLinks.update(l, l.copy(archivedAt = Some(Instant.now)))) updatedVariants ← * <~ ProductVariantLinks.queryRightByLeft(archiveResult) variants ← * <~ updatedVariants.map(VariantManager.zipVariantWithValues) variantAndSkus ← * <~ getVariantsWithRelatedSkus(variants) @@ -221,12 +219,11 @@ object ProductManager extends LazyLogging { taxons ← * <~ TaxonomyManager.getAssignedTaxons(productObject.model) } yield ProductResponse.build( - product = - IlluminatedProduct.illuminate(oc, archiveResult, inactive.form, inactive.shadow), - albums = albums, - if (variantLinks.length > 0) variantSkus else skus, - variantResponses, - taxons + product = IlluminatedProduct.illuminate(oc, archiveResult, inactive.form, inactive.shadow), + albums = albums, + if (variantLinks.length > 0) variantSkus else skus, + variantResponses, + taxons ) } @@ -234,7 +231,8 @@ object ProductManager extends LazyLogging { implicit ec: EC, db: DB, oc: OC): DbResultT[(Seq[SkuResponse.Root], Seq[IlluminatedVariantResponse.Root])] = { - val variantValueIds = variants.flatMap { case (_, variantValue) ⇒ variantValue } + val variantValueIds = variants + .flatMap { case (_, variantValue) ⇒ variantValue } .map(_.model.id) for { variantValueSkuCodes ← * <~ VariantManager.getVariantValueSkuCodes(variantValueIds) @@ -248,38 +246,31 @@ object ProductManager extends LazyLogging { } yield (variantSkus, illuminated) } - private def validateCreate( - payload: CreateProductPayload): ValidatedNel[Failure, CreateProductPayload] = { + private def validateCreate(payload: CreateProductPayload): ValidatedNel[Failure, CreateProductPayload] = { val maxSkus = payload.variants .getOrElse(Seq.empty) .map(_.values.getOrElse(Seq.empty).length.max(1)) .product - (notEmpty(payload.skus, "SKUs") |@| lesserThanOrEqual(payload.skus.length, - maxSkus, - "number of SKUs") |@| - validateSlug(payload.slug, true)).map { + (notEmpty(payload.skus, "SKUs") |@| lesserThanOrEqual(payload.skus.length, maxSkus, "number of SKUs") |@| + validateSlug(payload.slug, true)).map { case _ ⇒ payload } } - private def validateUpdate( - payload: UpdateProductPayload): ValidatedNel[Failure, UpdateProductPayload] = + private def validateUpdate(payload: UpdateProductPayload): ValidatedNel[Failure, UpdateProductPayload] = payload.slug.fold(ok)(value ⇒ validateSlug(value)).map { case _ ⇒ payload } - private def validateSlug(slug: String, - forProductCreate: Boolean = false): ValidatedNel[Failure, Unit] = { + private def validateSlug(slug: String, forProductCreate: Boolean = false): ValidatedNel[Failure, Unit] = if (slug.isEmpty && forProductCreate || slug.exists(_.isLetter)) { ok } else { Validated.invalidNel(ProductFailures.SlugShouldHaveLetters(slug)) } - } private def validateSkuMatchesVariants( skus: Seq[SkuResponse.Root], - variants: Seq[(FullObject[Variant], Seq[FullObject[VariantValue]])]) - : ValidatedNel[Failure, Unit] = { + variants: Seq[(FullObject[Variant], Seq[FullObject[VariantValue]])]): ValidatedNel[Failure, Unit] = { val maxSkus = variants.map { case (_, values) ⇒ values.length.max(1) }.product lesserThanOrEqual(skus.length, maxSkus, "number of SKUs for given variants").map { @@ -287,8 +278,7 @@ object ProductManager extends LazyLogging { } } - private def updateAssociatedVariants(product: Product, - variantsPayload: Option[Seq[VariantPayload]])( + private def updateAssociatedVariants(product: Product, variantsPayload: Option[Seq[VariantPayload]])( implicit ec: EC, db: DB, oc: OC, @@ -326,8 +316,7 @@ object ProductManager extends LazyLogging { (product: Product) ⇒ newSlug.fold(product)(value ⇒ product.copy(slug = value)) def withCommit = (product: Product) ⇒ - maybeCommit.fold(product)(commit ⇒ - product.copy(shadowId = shadow.id, commitId = commit.id)) + maybeCommit.fold(product)(commit ⇒ product.copy(shadowId = shadow.id, commitId = commit.id)) val newProduct = withNewSlug.andThen(withCommit)(product) @@ -345,36 +334,36 @@ object ProductManager extends LazyLogging { for { code ← * <~ SkuManager.mustGetSkuCode(payload) sku ← * <~ Skus.filterByContextAndCode(oc.id, code).one.dbresult - up ← * <~ sku.map { foundSku ⇒ - if (foundSku.archivedAt.isEmpty) { + up ← * <~ sku + .map { foundSku ⇒ + if (foundSku.archivedAt.isEmpty) { + for { + existingSku ← * <~ SkuManager.updateSkuInner(foundSku, payload) + _ ← * <~ SkuManager.findOrCreateAlbumsForSku(existingSku.model, albumPayloads) + _ ← * <~ ProductSkuLinks.syncLinks(product, + if (createLinks) Seq(existingSku.model) + else Seq.empty) + } yield existingSku + } else { + DbResultT.failure(LinkInactiveSkuFailure(Product, product.id, code)) + } + } + .getOrElse { for { - existingSku ← * <~ SkuManager.updateSkuInner(foundSku, payload) - _ ← * <~ SkuManager.findOrCreateAlbumsForSku(existingSku.model, albumPayloads) + newSku ← * <~ SkuManager.createSkuInner(oc, payload) + _ ← * <~ SkuManager.findOrCreateAlbumsForSku(newSku.model, albumPayloads) _ ← * <~ ProductSkuLinks.syncLinks(product, - if (createLinks) Seq(existingSku.model) + if (createLinks) Seq(newSku.model) else Seq.empty) - } yield existingSku - } else { - DbResultT.failure(LinkInactiveSkuFailure(Product, product.id, code)) + } yield newSku } - }.getOrElse { - for { - newSku ← * <~ SkuManager.createSkuInner(oc, payload) - _ ← * <~ SkuManager.findOrCreateAlbumsForSku(newSku.model, albumPayloads) - _ ← * <~ ProductSkuLinks.syncLinks(product, - if (createLinks) Seq(newSku.model) - else Seq.empty) - } yield newSku - } albums ← * <~ ImageManager.getAlbumsForSkuInner(code, oc) } yield SkuResponse.buildLite(IlluminatedSku.illuminate(oc, up), albums) } - private def findOrCreateVariantsForProduct(product: Product, payload: Seq[VariantPayload])( - implicit ec: EC, - db: DB, - oc: OC, - au: AU): DbResultT[Seq[FullVariant]] = + private def findOrCreateVariantsForProduct( + product: Product, + payload: Seq[VariantPayload])(implicit ec: EC, db: DB, oc: OC, au: AU): DbResultT[Seq[FullVariant]] = for { variants ← * <~ payload.map(VariantManager.updateOrCreateVariant(oc, _)) _ ← * <~ ProductVariantLinks.syncLinks(product, variants.map { @@ -394,9 +383,8 @@ object ProductManager extends LazyLogging { }) } yield albums - def mustFindProductByContextAndFormId404(contextId: Int, formId: Int)( - implicit ec: EC, - db: DB): DbResultT[Product] = + def mustFindProductByContextAndFormId404(contextId: Int, formId: Int)(implicit ec: EC, + db: DB): DbResultT[Product] = Products .filter(_.contextId === contextId) .filter(_.formId === formId) @@ -414,14 +402,13 @@ object ProductManager extends LazyLogging { productId: Int)(implicit ec: EC, db: DB, oc: OC): DbResultT[FullObject[Product]] = ObjectManager.getFullObject(mustFindProductByContextAndFormId404(oc.id, productId)) - def mustFindFullProductById(productId: Int)(implicit ec: EC, - db: DB): DbResultT[FullObject[Product]] = + def mustFindFullProductById(productId: Int)(implicit ec: EC, db: DB): DbResultT[FullObject[Product]] = ObjectManager.getFullObject(Products.mustFindById404(productId)) // This is an inefficient intensely quering method that does the trick - private def skusToBeUnassociatedMustNotBePresentInCarts( - productId: Int, - payloadSkus: Seq[SkuPayload])(implicit ec: EC, db: DB): DbResultT[Unit] = + private def skusToBeUnassociatedMustNotBePresentInCarts(productId: Int, payloadSkus: Seq[SkuPayload])( + implicit ec: EC, + db: DB): DbResultT[Unit] = for { skuIdsForProduct ← * <~ ProductSkuLinks.filter(_.leftId === productId).result.flatMap { case links @ Seq(_) ⇒ @@ -445,10 +432,10 @@ object ProductManager extends LazyLogging { skuCodesFromPayload = payloadSkus.map(ps ⇒ SkuManager.getSkuCode(ps.attributes)).flatten skuCodesToBeGone = skuCodesForProduct.diff(skuCodesFromPayload) _ ← * <~ (skuCodesToBeGone.map { codeToUnassociate ⇒ - for { - skuToUnassociate ← * <~ Skus.mustFindByCode(codeToUnassociate) - _ ← * <~ skuToUnassociate.mustNotBePresentInCarts - } yield {} - }) + for { + skuToUnassociate ← * <~ Skus.mustFindByCode(codeToUnassociate) + _ ← * <~ skuToUnassociate.mustNotBePresentInCarts + } yield {} + }) } yield {} } diff --git a/phoenix-scala/phoenix/app/phoenix/services/promotion/PromotionManager.scala b/phoenix-scala/phoenix/app/phoenix/services/promotion/PromotionManager.scala index a4a075aebf..f6f1934e42 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/promotion/PromotionManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/promotion/PromotionManager.scala @@ -29,11 +29,10 @@ object PromotionManager { implicit val formats: Formats = JsonFormatters.phoenixFormats - def create(payload: CreatePromotion, contextName: String, admin: Option[User])( - implicit ec: EC, - db: DB, - ac: AC, - au: AU): DbResultT[PromotionResponse.Root] = { + def create( + payload: CreatePromotion, + contextName: String, + admin: Option[User])(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[PromotionResponse.Root] = { val formAndShadow = FormAndShadow.fromPayload(kind = Promotion.kind, attributes = payload.attributes) @@ -47,12 +46,12 @@ object PromotionManager { .tupled ins ← * <~ ObjectUtils.insert((form, shadow), payload.schema) promotion ← * <~ Promotions.create( - Promotion(scope = scope, - contextId = context.id, - applyType = payload.applyType, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) + Promotion(scope = scope, + contextId = context.id, + applyType = payload.applyType, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) discount ← * <~ createDiscounts(context, payload, ins.shadow) response = PromotionResponse .build(context, promotion, ins.form, ins.shadow, discount.forms.zip(discount.shadows)) @@ -83,13 +82,12 @@ object PromotionManager { for { promotion ← * <~ Promotions .filterByContextAndShadowId(context.id, promotionShadow.id) - .mustFindOneOr(NotFoundFailure404(classOf[Promotion].getSimpleName, - "shadowId", - promotionShadow.id)) + .mustFindOneOr( + NotFoundFailure404(classOf[Promotion].getSimpleName, "shadowId", promotionShadow.id)) discount ← * <~ DiscountManager .createInternal(CreateDiscount(attributes = createDiscount.attributes), context) link ← * <~ PromotionDiscountLinks.create( - PromotionDiscountLink(leftId = promotion.id, rightId = discount.discount.id)) + PromotionDiscountLink(leftId = promotion.id, rightId = discount.discount.id)) } yield DiscountCreateResult(discount.form, discount.shadow) def update(id: Int, payload: UpdatePromotion, contextName: String, admin: Option[User])( @@ -125,15 +123,13 @@ object PromotionManager { } yield response } - def archiveByContextAndId(contextName: String, formId: Int)( - implicit ec: EC, - db: DB): DbResultT[PromotionResponse.Root] = + def archiveByContextAndId(contextName: String, formId: Int)(implicit ec: EC, + db: DB): DbResultT[PromotionResponse.Root] = for { context ← * <~ ObjectContexts .filterByName(contextName) .mustFindOneOr(ObjectContextNotFound(contextName)) - fullObject ← * <~ ObjectManager.getFullObject( - mustFindPromotionByContextAndFormId(context.id, formId)) + fullObject ← * <~ ObjectManager.getFullObject(mustFindPromotionByContextAndFormId(context.id, formId)) model = fullObject.model now = Some(Instant.now) archiveResult ← * <~ Promotions.update(model, model.copy(archivedAt = now)) @@ -149,9 +145,8 @@ object PromotionManager { fullObject.shadow, discountForms.zip(discountShadows)) - private def mustFindPromotionByContextAndFormId(contextId: Int, formId: Int)( - implicit ec: EC, - db: DB): DbResultT[Promotion] = + private def mustFindPromotionByContextAndFormId(contextId: Int, formId: Int)(implicit ec: EC, + db: DB): DbResultT[Promotion] = Promotions .findOneByContextAndFormId(contextId, formId) .mustFindOneOr(NotFoundFailure404(Promotion, formId)) @@ -160,8 +155,7 @@ object PromotionManager { private def updateDiscounts(context: ObjectContext, payload: UpdatePromotion)( implicit ec: EC, - db: DB): DbResultT[UpdateDiscountsResult] = { - + db: DB): DbResultT[UpdateDiscountsResult] = for { updated ← * <~ payload.discounts.sortBy(_.id).map { discount ⇒ updateDiscount(context, discount) @@ -169,19 +163,16 @@ object PromotionManager { forms = updated.map(_.form) shadows = updated.map(_.shadow) } yield UpdateDiscountsResult(forms, shadows) - } private case class UpdateDiscountResult(form: ObjectForm, shadow: ObjectShadow) private def updateDiscount(context: ObjectContext, updateDiscount: UpdatePromoDiscount)( implicit ec: EC, - db: DB): DbResultT[UpdateDiscountResult] = { - + db: DB): DbResultT[UpdateDiscountResult] = for { discount ← * <~ DiscountManager .updateInternal(updateDiscount.id, updateDiscount.attributes, context) } yield UpdateDiscountResult(discount.form, discount.shadow) - } def getIlluminated(id: Int, contextName: String)(implicit ec: EC, db: DB): DbResultT[PromotionResponse.Root] = @@ -198,16 +189,15 @@ object PromotionManager { discounts ← * <~ PromotionDiscountLinks.queryRightByLeft(promotion) } yield PromotionResponse.build( - promotion = IlluminatedPromotion.illuminate(context, promotion, form, shadow), - discounts = - discounts.map(d ⇒ IlluminatedDiscount.illuminate(form = d.form, shadow = d.shadow)), - promotion) - - private def updateHead( - promotion: Promotion, - payload: UpdatePromotion, - shadow: ObjectShadow, - maybeCommit: Option[ObjectCommit])(implicit ec: EC): DbResultT[Promotion] = + promotion = IlluminatedPromotion.illuminate(context, promotion, form, shadow), + discounts = discounts.map(d ⇒ IlluminatedDiscount.illuminate(form = d.form, shadow = d.shadow)), + promotion + ) + + private def updateHead(promotion: Promotion, + payload: UpdatePromotion, + shadow: ObjectShadow, + maybeCommit: Option[ObjectCommit])(implicit ec: EC): DbResultT[Promotion] = maybeCommit match { case Some(commit) ⇒ val updated = diff --git a/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnLineItemManager.scala b/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnLineItemManager.scala index 971bc4d11b..47571ef97e 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnLineItemManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnLineItemManager.scala @@ -21,11 +21,10 @@ import slick.jdbc.PostgresProfile.api._ object ReturnLineItemManager { - def addLineItem(refNum: String, payload: ReturnLineItemPayload)( - implicit ec: EC, - db: DB, - ac: AC, - oc: OC): DbResultT[ReturnResponse.Root] = + def addLineItem(refNum: String, payload: ReturnLineItemPayload)(implicit ec: EC, + db: DB, + ac: AC, + oc: OC): DbResultT[ReturnResponse.Root] = for { rma ← * <~ Returns.mustFindActiveByRefNum404(refNum) reason ← * <~ ReturnReasons.mustFindById400(payload.reasonId) @@ -50,26 +49,22 @@ object ReturnLineItemManager { .map { case (_, sku) ⇒ sku } .to[List] .result - _ ← * <~ skusLiQuery.deleteAll - _ ← * <~ doOrMeh(skus.nonEmpty, LogActivity().returnSkuLineItemsDropped(skus)) - _ ← * <~ payload.map(p ⇒ - ReturnReasons.mustFindById400(p.reasonId).flatMap(addSkuLineItem(rma, _, p))) + _ ← * <~ skusLiQuery.deleteAll + _ ← * <~ doOrMeh(skus.nonEmpty, LogActivity().returnSkuLineItemsDropped(skus)) + _ ← * <~ payload.map(p ⇒ ReturnReasons.mustFindById400(p.reasonId).flatMap(addSkuLineItem(rma, _, p))) updated ← * <~ Returns.refresh(rma) response ← * <~ ReturnResponse.fromRma(updated) } yield response - private def processAddLineItem( - rma: Return, - reason: ReturnReason, - payload: ReturnLineItemPayload)(implicit ec: EC, db: DB, ac: AC, oc: OC) = { + private def processAddLineItem(rma: Return, + reason: ReturnReason, + payload: ReturnLineItemPayload)(implicit ec: EC, db: DB, ac: AC, oc: OC) = payload match { case shipping: ReturnShippingCostLineItemPayload ⇒ addShippingCostItem(rma, reason, shipping) case sku: ReturnSkuLineItemPayload ⇒ addSkuLineItem(rma, reason, sku) } - } - private def validateMaxShippingCost(rma: Return, amount: Long)(implicit ec: EC, - db: DB): DbResultT[Unit] = + private def validateMaxShippingCost(rma: Return, amount: Long)(implicit ec: EC, db: DB): DbResultT[Unit] = for { order ← * <~ Orders.mustFindByRefNum(rma.orderRef) orderShippingTotal = order.shippingTotal @@ -82,10 +77,9 @@ object ReturnLineItemManager { .getOrElse(0L) .result maxAmount = orderShippingTotal - previouslyReturnedCost - _ ← * <~ failIf(amount > maxAmount, - ReturnShippingCostExceeded(refNum = rma.referenceNumber, - amount = amount, - maxAmount = maxAmount)) + _ ← * <~ failIf( + amount > maxAmount, + ReturnShippingCostExceeded(refNum = rma.referenceNumber, amount = amount, maxAmount = maxAmount)) } yield () private def addShippingCostItem(rma: Return, @@ -102,20 +96,19 @@ object ReturnLineItemManager { .one _ ← * <~ oli.map(li ⇒ ReturnLineItems.filter(_.id === li.id).deleteAll) li ← * <~ ReturnLineItems.create( - ReturnLineItem( - returnId = rma.id, - reasonId = reason.id, - originType = ReturnLineItem.ShippingCost - )) + ReturnLineItem( + returnId = rma.id, + reasonId = reason.id, + originType = ReturnLineItem.ShippingCost + )) _ ← * <~ ReturnLineItemShippingCosts.create( - ReturnLineItemShippingCost(id = li.id, returnId = rma.id, amount = payload.amount)) + ReturnLineItemShippingCost(id = li.id, returnId = rma.id, amount = payload.amount)) _ ← * <~ LogActivity().returnShippingCostItemAdded(rma, reason, payload) } yield li - private def validateMaxQuantity(rma: Return, sku: String, quantity: Int)( - implicit ec: EC, - db: DB, - oc: OC): DbResultT[Unit] = + private def validateMaxQuantity(rma: Return, sku: String, quantity: Int)(implicit ec: EC, + db: DB, + oc: OC): DbResultT[Unit] = for { order ← * <~ Orders.mustFindByRefNum(rma.orderRef) orderedQuantity ← * <~ OrderLineItems @@ -138,11 +131,10 @@ object ReturnLineItemManager { maxQuantity = maxQuantity)) } yield () - private def addSkuLineItem(rma: Return, reason: ReturnReason, payload: ReturnSkuLineItemPayload)( - implicit ec: EC, - db: DB, - ac: AC, - oc: OC): DbResultT[ReturnLineItem] = + private def addSkuLineItem( + rma: Return, + reason: ReturnReason, + payload: ReturnSkuLineItemPayload)(implicit ec: EC, db: DB, ac: AC, oc: OC): DbResultT[ReturnLineItem] = for { _ ← * <~ validateMaxQuantity(rma, payload.sku, payload.quantity) sku ← * <~ SkuManager.mustFindSkuByContextAndCode(oc.id, payload.sku) @@ -155,37 +147,38 @@ object ReturnLineItemManager { .one _ ← * <~ oli.map(li ⇒ ReturnLineItems.filter(_.id === li.id).deleteAll) li ← * <~ ReturnLineItems.create( - ReturnLineItem( - returnId = rma.id, - reasonId = reason.id, - originType = ReturnLineItem.SkuItem - )) + ReturnLineItem( + returnId = rma.id, + reasonId = reason.id, + originType = ReturnLineItem.SkuItem + )) _ ← * <~ ReturnLineItemSkus.create( - ReturnLineItemSku(id = li.id, - returnId = rma.id, - quantity = payload.quantity, - skuId = sku.id, - skuShadowId = skuShadow.id)) + ReturnLineItemSku(id = li.id, + returnId = rma.id, + quantity = payload.quantity, + skuId = sku.id, + skuShadowId = skuShadow.id)) _ ← * <~ LogActivity().returnSkuLineItemAdded(rma, reason, payload) } yield li - def deleteLineItem(refNum: String, lineItemId: Int)(implicit ec: EC, - ac: AC, - db: DB): DbResultT[ReturnResponse.Root] = + def deleteLineItem(refNum: String, + lineItemId: Int)(implicit ec: EC, ac: AC, db: DB): DbResultT[ReturnResponse.Root] = for { rma ← * <~ Returns.mustFindActiveByRefNum404(refNum) li ← * <~ ReturnLineItems.mustFindById404(lineItemId) deleted ← * <~ ReturnLineItems.filter(_.id === li.id).deleteAllWithRowsBeingAffected - _ ← * <~ doOrMeh(deleted, li.originType match { - case ReturnLineItem.ShippingCost ⇒ LogActivity().returnShippingCostItemDeleted(li) - case ReturnLineItem.SkuItem ⇒ LogActivity().returnSkuLineItemDeleted(li) - }) + _ ← * <~ doOrMeh( + deleted, + li.originType match { + case ReturnLineItem.ShippingCost ⇒ LogActivity().returnShippingCostItemDeleted(li) + case ReturnLineItem.SkuItem ⇒ LogActivity().returnSkuLineItemDeleted(li) + } + ) updated ← * <~ Returns.refresh(rma) response ← * <~ ReturnResponse.fromRma(updated) } yield response - def fetchSkuLineItems(rma: Return)(implicit ec: EC, - db: DB): DbResultT[Seq[ReturnResponse.LineItem.Sku]] = { + def fetchSkuLineItems(rma: Return)(implicit ec: EC, db: DB): DbResultT[Seq[ReturnResponse.LineItem.Sku]] = { val skusQuery = (for { liSku ← ReturnLineItemSkus.findByRmaId(rma.id) li ← ReturnLineItems if liSku.id === li.id @@ -208,20 +201,20 @@ object ReturnLineItemManager { title ← FormShadowGet.title(form, shadow) } yield ReturnResponse.LineItem.Sku( - id = id, - reason = reason, - imagePath = image.getOrElse(CordResponseLineItems.NO_IMAGE), - title = title, - sku = sku.code, - quantity = quantity, - price = price, - currency = currency) + id = id, + reason = reason, + imagePath = image.getOrElse(CordResponseLineItems.NO_IMAGE), + title = title, + sku = sku.code, + quantity = quantity, + price = price, + currency = currency + ) } } - def fetchShippingCostLineItem(rma: Return)( - implicit ec: EC, - db: DB): DbResultT[Option[ReturnResponse.LineItem.ShippingCost]] = { + def fetchShippingCostLineItem( + rma: Return)(implicit ec: EC, db: DB): DbResultT[Option[ReturnResponse.LineItem.ShippingCost]] = { val shippingCostsQuery = (for { liSc ← ReturnLineItemShippingCosts.findByRmaId(rma.id) li ← liSc.li diff --git a/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnPaymentManager.scala b/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnPaymentManager.scala index 0391156a29..4cb0dcea1d 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnPaymentManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnPaymentManager.scala @@ -26,16 +26,13 @@ import core.db._ import phoenix.models.payment.applepay.ApplePayments object ReturnPaymentManager { - def updatePayments(refNum: String, payments: Map[PaymentMethod.Type, Long], overwrite: Boolean)( - implicit ec: EC, - db: DB, - ac: AC, - au: AU): DbResultT[ReturnResponse.Root] = { + def updatePayments( + refNum: String, + payments: Map[PaymentMethod.Type, Long], + overwrite: Boolean)(implicit ec: EC, db: DB, ac: AC, au: AU): DbResultT[ReturnResponse.Root] = { @inline - def addPayment(rma: Return, - payment: OrderPayment, - paymentMethodAmount: (PaymentMethod.Type, Long)) = { + def addPayment(rma: Return, payment: OrderPayment, paymentMethodAmount: (PaymentMethod.Type, Long)) = { val (method, amount) = paymentMethodAmount processAddPayment(rma, payment, method, amount) } @@ -45,16 +42,13 @@ object ReturnPaymentManager { if (paymentsToAdd.isEmpty) for { - rma ← * <~ Returns.mustFindActiveByRefNum404(refNum) - response ← * <~ ifElse(overwrite, - deletePayments(rma, paymentsToRemove), - ReturnResponse.fromRma(rma)) + rma ← * <~ Returns.mustFindActiveByRefNum404(refNum) + response ← * <~ ifElse(overwrite, deletePayments(rma, paymentsToRemove), ReturnResponse.fromRma(rma)) } yield response else for { - _ ← * <~ failIf( - paymentsToAdd.filter { case (pt, _) ⇒ pt.isExternal }.groupBy(_._1).size > 1, - OnlyOneExternalPaymentIsAllowed) + _ ← * <~ failIf(paymentsToAdd.filter { case (pt, _) ⇒ pt.isExternal }.groupBy(_._1).size > 1, + OnlyOneExternalPaymentIsAllowed) rma ← * <~ Returns.mustFindActiveByRefNum404(refNum) payment ← * <~ mustFindExternalPaymentsByOrderRef(rma.orderRef) _ ← * <~ validateMaxAllowedPayments(rma, paymentsToAdd, sumOther = !overwrite) @@ -73,10 +67,9 @@ object ReturnPaymentManager { _ ← * <~ Returns.update(rma, rma.copy(totalRefund = rma.totalRefund |+| totalRefund)) } yield () - private def validateMaxAllowedPayments( - rma: Return, - payments: Map[PaymentMethod.Type, Long], - sumOther: Boolean)(implicit ec: EC, db: DB): DbResultT[Unit] = { + private def validateMaxAllowedPayments(rma: Return, + payments: Map[PaymentMethod.Type, Long], + sumOther: Boolean)(implicit ec: EC, db: DB): DbResultT[Unit] = { def validateTotalPayment() = for { adjustments ← * <~ ReturnTotaler.adjustmentsTotal(rma) @@ -94,10 +87,9 @@ object ReturnPaymentManager { maxAmount = (subTotal + taxes + shipping - adjustments).zeroIfNegative amount = payments.valuesIterator.sum - _ ← * <~ failIf(amount > maxAmount, - ReturnPaymentExceeded(refNum = rma.referenceNumber, - amount = amount, - maxAmount = maxAmount)) + _ ← * <~ failIf( + amount > maxAmount, + ReturnPaymentExceeded(refNum = rma.referenceNumber, amount = amount, maxAmount = maxAmount)) } yield () def validateCCPayment() = { @@ -138,18 +130,16 @@ object ReturnPaymentManager { } yield () } - private def mustFindExternalPaymentsByOrderRef(cordRef: String)( - implicit ec: EC): DbResultT[OrderPayment] = + private def mustFindExternalPaymentsByOrderRef(cordRef: String)(implicit ec: EC): DbResultT[OrderPayment] = OrderPayments .findAllByCordRef(cordRef) .externalPayments .mustFindOneOr(OrderPaymentNotFoundFailure(Order)) - private def processAddPayment( - rma: Return, - payment: OrderPayment, - method: PaymentMethod.Type, - amount: Long)(implicit ec: EC, db: DB, au: AU): DbResultT[ReturnPayment] = + private def processAddPayment(rma: Return, payment: OrderPayment, method: PaymentMethod.Type, amount: Long)( + implicit ec: EC, + db: DB, + au: AU): DbResultT[ReturnPayment] = method match { case PaymentMethod.CreditCard ⇒ addCreditCard(rma.id, payment, amount) case PaymentMethod.GiftCard ⇒ addGiftCard(rma.id, payment, amount) @@ -165,11 +155,11 @@ object ReturnPaymentManager { cc ← * <~ CreditCards.mustFindById404(payment.paymentMethodId) _ ← * <~ deleteCcPayment(returnId) ccRefund ← * <~ ReturnPayments.create( - ReturnPayment(returnId = returnId, - amount = amount, - currency = payment.currency, - paymentMethodId = cc.id, - paymentMethodType = PaymentMethod.CreditCard)) + ReturnPayment(returnId = returnId, + amount = amount, + currency = payment.currency, + paymentMethodId = cc.id, + paymentMethodType = PaymentMethod.CreditCard)) } yield ccRefund private def addApplePayment(returnId: Int, payment: OrderPayment, amount: Long)(implicit ec: EC, @@ -179,37 +169,36 @@ object ReturnPaymentManager { ap ← * <~ ApplePayments.mustFindById404(payment.paymentMethodId) _ ← * <~ deleteApplePayPayment(returnId) applePayRefund ← * <~ ReturnPayments.create( - ReturnPayment(returnId = returnId, - amount = amount, - currency = payment.currency, - paymentMethodId = ap.id, - paymentMethodType = PaymentMethod.ApplePay)) + ReturnPayment(returnId = returnId, + amount = amount, + currency = payment.currency, + paymentMethodId = ap.id, + paymentMethodType = PaymentMethod.ApplePay)) } yield applePayRefund - private def addGiftCard(returnId: Int, payment: OrderPayment, amount: Long)( - implicit ec: EC, - db: DB, - au: AU): DbResultT[ReturnPayment] = + private def addGiftCard(returnId: Int, + payment: OrderPayment, + amount: Long)(implicit ec: EC, db: DB, au: AU): DbResultT[ReturnPayment] = for { _ ← * <~ deleteGcPayment(returnId) origin ← * <~ GiftCardRefunds.create(GiftCardRefund(returnId = returnId)) gc ← * <~ GiftCards.create( - GiftCard( - scope = Scope.current, - originId = origin.id, - originType = GiftCard.RmaProcess, - state = GiftCard.OnHold, - currency = payment.currency, - originalBalance = amount, - availableBalance = amount, - currentBalance = amount - )) + GiftCard( + scope = Scope.current, + originId = origin.id, + originType = GiftCard.RmaProcess, + state = GiftCard.OnHold, + currency = payment.currency, + originalBalance = amount, + availableBalance = amount, + currentBalance = amount + )) pmt ← * <~ ReturnPayments.create( - ReturnPayment(returnId = returnId, - amount = amount, - currency = payment.currency, - paymentMethodId = gc.id, - paymentMethodType = PaymentMethod.GiftCard)) + ReturnPayment(returnId = returnId, + amount = amount, + currency = payment.currency, + paymentMethodId = gc.id, + paymentMethodType = PaymentMethod.GiftCard)) } yield pmt private def addStoreCredit(returnId: Int, accountId: Int, payment: OrderPayment, amount: Long)( @@ -220,44 +209,42 @@ object ReturnPaymentManager { _ ← * <~ deleteScPayment(returnId) origin ← * <~ StoreCreditRefunds.create(StoreCreditRefund(returnId = returnId)) sc ← * <~ StoreCredits.create( - StoreCredit(accountId = accountId, - scope = Scope.current, - originId = origin.id, - originType = StoreCredit.RmaProcess, - state = StoreCredit.OnHold, - currency = payment.currency, - originalBalance = amount, - availableBalance = amount, - currentBalance = amount)) + StoreCredit( + accountId = accountId, + scope = Scope.current, + originId = origin.id, + originType = StoreCredit.RmaProcess, + state = StoreCredit.OnHold, + currency = payment.currency, + originalBalance = amount, + availableBalance = amount, + currentBalance = amount + )) pmt ← * <~ ReturnPayments.create( - ReturnPayment(returnId = returnId, - amount = amount, - currency = payment.currency, - paymentMethodId = sc.id, - paymentMethodType = PaymentMethod.StoreCredit)) + ReturnPayment(returnId = returnId, + amount = amount, + currency = payment.currency, + paymentMethodId = sc.id, + paymentMethodType = PaymentMethod.StoreCredit)) } yield pmt - def deletePayment(refNum: String, paymentMethod: PaymentMethod.Type)( - implicit ec: EC, - ac: AC, - db: DB): DbResultT[ReturnResponse.Root] = + def deletePayment( + refNum: String, + paymentMethod: PaymentMethod.Type)(implicit ec: EC, ac: AC, db: DB): DbResultT[ReturnResponse.Root] = for { rma ← * <~ Returns.mustFindActiveByRefNum404(refNum) paymentWasDeleted ← * <~ processDeletePayment(rma.id, paymentMethod) updated ← * <~ Returns.refresh(rma) response ← * <~ ReturnResponse.fromRma(rma) - _ ← * <~ doOrMeh(paymentWasDeleted, - LogActivity().returnPaymentsDeleted(response, List(paymentMethod))) + _ ← * <~ doOrMeh(paymentWasDeleted, LogActivity().returnPaymentsDeleted(response, List(paymentMethod))) } yield response - private def deletePayments(rma: Return, payments: List[PaymentMethod.Type])( - implicit ec: EC, - db: DB, - ac: AC): DbResultT[ReturnResponse.Root] = + private def deletePayments( + rma: Return, + payments: List[PaymentMethod.Type])(implicit ec: EC, db: DB, ac: AC): DbResultT[ReturnResponse.Root] = for { - deleted ← * <~ payments.map(pmt ⇒ - processDeletePayment(rma.id, pmt).product(DbResultT.pure(pmt))) + deleted ← * <~ payments.map(pmt ⇒ processDeletePayment(rma.id, pmt).product(DbResultT.pure(pmt))) deletedPayments = deleted.collect { case (true, pmt) ⇒ pmt } updated ← * <~ Returns.refresh(rma) response ← * <~ ReturnResponse.fromRma(updated) @@ -316,8 +303,7 @@ object ReturnPaymentManager { } yield somethingWasActuallyDeleted } - def issueRefunds( - rma: Return)(implicit ec: EC, db: DB, au: AU, ac: AC, apis: Apis): DbResultT[Unit] = { + def issueRefunds(rma: Return)(implicit ec: EC, db: DB, au: AU, ac: AC, apis: Apis): DbResultT[Unit] = for { customer ← * <~ Users.mustFindByAccountId(rma.accountId) @@ -330,21 +316,21 @@ object ReturnPaymentManager { sc ← * <~ ReturnPayments.findOnHoldStoreCredits(rma.id).one _ ← * <~ sc.map(issueScRefund(customer, rma, _)) } yield () - } private def issueCcRefund( rma: Return, payment: ReturnPayment)(implicit ec: EC, db: DB, ac: AC, apis: Apis): DbResultT[Unit] = { val authorizeRefund = - ((id: String, amount: Long) ⇒ + ((id: String, + amount: Long) ⇒ for { _ ← * <~ apis.stripe.authorizeRefund(id, amount, RefundReason.RequestedByCustomer) ccPayment = ReturnStripePayment( - returnPaymentId = payment.id, - chargeId = id, - returnId = payment.returnId, - amount = amount, - currency = payment.currency + returnPaymentId = payment.id, + chargeId = id, + returnId = payment.returnId, + amount = amount, + currency = payment.currency ) created ← * <~ ReturnStripePayments.create(ccPayment) } yield created).tupled @@ -402,10 +388,9 @@ object ReturnPaymentManager { amountToRefund = splitAmount(payment.amount, adjustedCcCharges, Vector.empty) refunds ← * <~ amountToRefund.map(authorizeRefund).sequenceU totalRefund = refunds.map(_.amount).sum - _ ← * <~ failIf(totalRefund != payment.amount, - ReturnCcPaymentViolation(refNum = rma.refNum, - issued = totalRefund, - allowed = payment.amount)) + _ ← * <~ failIf( + totalRefund != payment.amount, + ReturnCcPaymentViolation(refNum = rma.refNum, issued = totalRefund, allowed = payment.amount)) _ ← * <~ LogActivity().issueCcRefund(rma, payment) } yield () } @@ -422,9 +407,9 @@ object ReturnPaymentManager { _ ← * <~ LogActivity().issueGcRefund(customer, rma, gc) } yield () - private def issueScRefund(customer: User, - rma: Return, - sc: StoreCredit)(implicit ec: EC, ac: AC, au: AU): DbResultT[Unit] = + private def issueScRefund(customer: User, rma: Return, sc: StoreCredit)(implicit ec: EC, + ac: AC, + au: AU): DbResultT[Unit] = for { sc ← * <~ StoreCredits.update(sc, sc.copy(state = StoreCredit.Active)) _ ← * <~ LogActivity().issueScRefund(customer, rma, sc) diff --git a/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnService.scala b/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnService.scala index 821b402eb6..7137e40178 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnService.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnService.scala @@ -31,18 +31,16 @@ object ReturnService { response ← * <~ ReturnResponse.fromRma(updated) } yield response - def updateStateByCsr(refNum: String, payload: ReturnUpdateStatePayload)( - implicit ec: EC, - db: DB, - au: AU, - ac: AC, - apis: Apis): DbResultT[Root] = + def updateStateByCsr(refNum: String, payload: ReturnUpdateStatePayload)(implicit ec: EC, + db: DB, + au: AU, + ac: AC, + apis: Apis): DbResultT[Root] = for { - rma ← * <~ Returns.mustFindByRefNum(refNum) - _ ← * <~ rma.transitionState(payload.state) - reason ← * <~ payload.reasonId.map(Reasons.findOneById).getOrElse(lift(None)) - _ ← * <~ reason.map(r ⇒ - failIfNot(r.reasonType == Cancellation, InvalidCancellationReasonFailure)) + rma ← * <~ Returns.mustFindByRefNum(refNum) + _ ← * <~ rma.transitionState(payload.state) + reason ← * <~ payload.reasonId.map(Reasons.findOneById).getOrElse(lift(None)) + _ ← * <~ reason.map(r ⇒ failIfNot(r.reasonType == Cancellation, InvalidCancellationReasonFailure)) _ ← * <~ update(rma, reason, payload) updated ← * <~ Returns.refresh(rma) response ← * <~ ReturnResponse.fromRma(updated) @@ -51,12 +49,9 @@ object ReturnService { LogActivity().returnStateChanged(customer, response, payload.state)) } yield response - private def update(rma: Return, reason: Option[Reason], payload: ReturnUpdateStatePayload)( - implicit ec: EC, - db: DB, - au: AU, - ac: AC, - apis: Apis) = + private def update(rma: Return, + reason: Option[Reason], + payload: ReturnUpdateStatePayload)(implicit ec: EC, db: DB, au: AU, ac: AC, apis: Apis) = for { rma ← * <~ Returns .update(rma, rma.copy(state = payload.state, canceledReasonId = reason.map(_.id))) @@ -65,13 +60,11 @@ object ReturnService { } yield rma // todo should be available for non-admin as well - def createByAdmin(admin: User, payload: ReturnCreatePayload)(implicit ec: EC, - db: DB, - ac: AC): DbResultT[Root] = + def createByAdmin(admin: User, + payload: ReturnCreatePayload)(implicit ec: EC, db: DB, ac: AC): DbResultT[Root] = for { - order ← * <~ Orders.mustFindByRefNum(payload.cordRefNum) - _ ← * <~ failIf(order.state != Order.Shipped, - OrderMustBeShippedForReturn(order.refNum, order.state)) + order ← * <~ Orders.mustFindByRefNum(payload.cordRefNum) + _ ← * <~ failIf(order.state != Order.Shipped, OrderMustBeShippedForReturn(order.refNum, order.state)) rma ← * <~ Returns.create(Return.build(order, admin, payload.returnType)) customer ← * <~ Users.mustFindByAccountId(order.accountId) custData ← * <~ CustomersData.mustFindByAccountId(order.accountId) diff --git a/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnValidator.scala b/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnValidator.scala index 0392fb882f..3324214dd7 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnValidator.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/returns/ReturnValidator.scala @@ -11,8 +11,7 @@ trait ReturnValidation { def validate: DbResultT[ReturnValidatorResponse] } -case class ReturnValidatorResponse(alerts: Option[Failures] = None, - warnings: Option[Failures] = None) +case class ReturnValidatorResponse(alerts: Option[Failures] = None, warnings: Option[Failures] = None) case class ReturnValidator(rma: Return)(implicit ec: EC) extends ReturnValidation { @@ -26,31 +25,25 @@ case class ReturnValidator(rma: Return)(implicit ec: EC) extends ReturnValidatio } yield state } - private def hasItems(response: ReturnValidatorResponse): DBIO[ReturnValidatorResponse] = { + private def hasItems(response: ReturnValidatorResponse): DBIO[ReturnValidatorResponse] = ReturnLineItems.filter(_.returnId === rma.id).length.result.map { numItems ⇒ if (numItems == 0) warning(response, EmptyReturn(rma.refNum)) else response } - } /** * TODO: Implement stub methods */ // Query previous completed RMAs, find matches between line items - private def hasNoPreviouslyRefundedItems( - response: ReturnValidatorResponse): DBIO[ReturnValidatorResponse] = { + private def hasNoPreviouslyRefundedItems(response: ReturnValidatorResponse): DBIO[ReturnValidatorResponse] = lift(response) - } // Has at least one payment method // Can refund up to the total charged on that order payment method // Can refund up to the total charged on that order - private def hasValidPaymentMethods( - response: ReturnValidatorResponse): DBIO[ReturnValidatorResponse] = { + private def hasValidPaymentMethods(response: ReturnValidatorResponse): DBIO[ReturnValidatorResponse] = lift(response) - } - private def warning(response: ReturnValidatorResponse, - failure: Failure): ReturnValidatorResponse = - response.copy(warnings = response.warnings.fold(Failures(failure))(current ⇒ - Failures(current.toList :+ failure: _*))) + private def warning(response: ReturnValidatorResponse, failure: Failure): ReturnValidatorResponse = + response.copy( + warnings = response.warnings.fold(Failures(failure))(current ⇒ Failures(current.toList :+ failure: _*))) } diff --git a/phoenix-scala/phoenix/app/phoenix/services/review/ProductReviewManager.scala b/phoenix-scala/phoenix/app/phoenix/services/review/ProductReviewManager.scala index d65c2db6c5..b3fa5c57da 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/review/ProductReviewManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/review/ProductReviewManager.scala @@ -14,9 +14,8 @@ import core.db._ object ProductReviewManager { - def getReview(reviewId: ProductReview#Id)(implicit ec: EC, - oc: OC, - db: DB): DbResultT[ProductReviewResponse] = + def getReview( + reviewId: ProductReview#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[ProductReviewResponse] = for { review ← * <~ ProductReviews.mustFindById404(reviewId) sku ← * <~ Skus.mustFindById404(review.skuId) @@ -26,41 +25,37 @@ object ProductReviewManager { implicit ec: EC, oc: OC, au: AU, - db: DB): DbResultT[ProductReviewResponse] = { - + db: DB): DbResultT[ProductReviewResponse] = for { scope ← * <~ Scope.resolveOverride(payload.scope) sku ← * <~ Skus.mustFindByCode(payload.sku) productReview ← * <~ ProductReviews .findOneByUserAndSku(userId, sku.id) .findOrCreate( - ProductReviews.create(ProductReview(scope = scope, - content = payload.attributes, - userId = userId, - skuId = sku.id))) + ProductReviews.create( + ProductReview(scope = scope, + content = payload.attributes, + userId = userId, + skuId = sku.id))) sku ← * <~ Skus.mustFindById404(productReview.skuId) } yield ProductReviewResponses.build(productReview, sku.code) - } def updateProductReview(reviewId: ProductReview#Id, payload: UpdateProductReviewPayload)( implicit ec: EC, oc: OC, db: DB, - au: AU): DbResultT[ProductReviewResponse] = { - + au: AU): DbResultT[ProductReviewResponse] = for { review ← * <~ ProductReviews.mustFindById404(reviewId) _ ← * <~ failIf(review.archivedAt.isDefined, ProductReviewIsArchived(reviewId)) _ ← * <~ failIf(au.account.id != review.userId, ProductReviewUserMismatch(reviewId)) newValue ← * <~ ProductReviews.update( - review, - review.copy(content = payload.attributes, updatedAt = Instant.now)) + review, + review.copy(content = payload.attributes, updatedAt = Instant.now)) sku ← * <~ Skus.mustFindById404(review.skuId) } yield ProductReviewResponses.build(newValue, sku.code) - } - def archiveByContextAndId( - reviewId: ProductReview#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[Unit] = + def archiveByContextAndId(reviewId: ProductReview#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[Unit] = for { review ← * <~ ProductReviews.mustFindById404(reviewId) archived ← * <~ ProductReviews.update(review, review.copy(archivedAt = Some(Instant.now))) diff --git a/phoenix-scala/phoenix/app/phoenix/services/taxonomy/TaxonomyManager.scala b/phoenix-scala/phoenix/app/phoenix/services/taxonomy/TaxonomyManager.scala index a5b965c499..2a47700d28 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/taxonomy/TaxonomyManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/taxonomy/TaxonomyManager.scala @@ -31,9 +31,7 @@ object TaxonomyManager { implicit val formats: Formats = JsonFormatters.phoenixFormats - case class MoveSpec(taxon: TaxonomyTaxonLink, - parent: Option[TaxonomyTaxonLink], - newPosition: Option[Int]) + case class MoveSpec(taxon: TaxonomyTaxonLink, parent: Option[TaxonomyTaxonLink], newPosition: Option[Int]) extends Validation[MoveSpec] { def fillLinkWithNewPath: MoveSpec = copy(taxon = taxon.copy(path = newPath)) @@ -44,15 +42,13 @@ object TaxonomyManager { override def validate: ValidatedNel[Failure, MoveSpec] = { def validateSameTaxonomy: ValidatedNel[Failure, Unit] = - Validation.validExpr( - taxon.taxonomyId == parent.map(_.taxonomyId).getOrElse(taxon.taxonomyId), - TaxonomyFailures.TaxonomyShouldMatchForParentAndTarget.description) + Validation.validExpr(taxon.taxonomyId == parent.map(_.taxonomyId).getOrElse(taxon.taxonomyId), + TaxonomyFailures.TaxonomyShouldMatchForParentAndTarget.description) - def validateParentToChildMove: ValidatedNel[Failure, Unit] = { + def validateParentToChildMove: ValidatedNel[Failure, Unit] = Validation.validExpr( - !isMoveRequired || taxon.id == 0 || !newPath.value.startsWith(taxon.childPath.value), - CannotMoveParentTaxonUnderChild.description) - } + !isMoveRequired || taxon.id == 0 || !newPath.value.startsWith(taxon.childPath.value), + CannotMoveParentTaxonUnderChild.description) (validateSameTaxonomy |@| validateParentToChildMove).map { case _ ⇒ this @@ -62,17 +58,15 @@ object TaxonomyManager { val newPath: LTree = parent.map(_.childPath).getOrElse(LTree(List())) } - def getTaxonomy(taxonomyFormId: ObjectForm#Id)(implicit ec: EC, - oc: OC, - db: DB): DbResultT[FullTaxonomyResponse] = + def getTaxonomy( + taxonomyFormId: ObjectForm#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[FullTaxonomyResponse] = for { taxonomy ← * <~ ObjectManager.getFullObject(Taxonomies.mustFindByFormId404(taxonomyFormId)) taxons ← * <~ TaxonomyTaxonLinks.queryRightByLeftWithLinks(taxonomy.model) } yield FullTaxonomyResponse.build(taxonomy, taxons) - def createTaxonomy(payload: CreateTaxonomyPayload)(implicit ec: EC, - oc: OC, - au: AU): DbResultT[FullTaxonomyResponse] = { + def createTaxonomy( + payload: CreateTaxonomyPayload)(implicit ec: EC, oc: OC, au: AU): DbResultT[FullTaxonomyResponse] = { val form = ObjectForm.fromPayload(Taxonomy.kind, payload.attributes) val shadow = ObjectShadow.fromPayload(payload.attributes) @@ -80,52 +74,47 @@ object TaxonomyManager { scope ← * <~ Scope.resolveOverride(payload.scope) ins ← * <~ ObjectUtils.insert(form, shadow) taxonomy ← * <~ Taxonomies.create( - Taxonomy(hierarchical = payload.hierarchical, - scope = scope, - contextId = oc.id, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) + Taxonomy(hierarchical = payload.hierarchical, + scope = scope, + contextId = oc.id, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) } yield FullTaxonomyResponse.build(FullObject(taxonomy, ins.form, ins.shadow), Seq()) } - def updateTaxonomy(taxonomyFormId: ObjectForm#Id, payload: UpdateTaxonomyPayload)( - implicit ec: EC, - oc: OC, - db: DB): DbResultT[FullTaxonomyResponse] = { + def updateTaxonomy( + taxonomyFormId: ObjectForm#Id, + payload: UpdateTaxonomyPayload)(implicit ec: EC, oc: OC, db: DB): DbResultT[FullTaxonomyResponse] = { val form = ObjectForm.fromPayload(Taxonomy.kind, payload.attributes) val shadow = ObjectShadow.fromPayload(payload.attributes) for { taxonomy ← * <~ ObjectManager.getFullObject(Taxonomies.mustFindByFormId404(taxonomyFormId)) _ ← * <~ failIf(taxonomy.model.archivedAt.isDefined, TaxonomyIsArchived(taxonomyFormId)) - newTaxonomy ← * <~ ObjectUtils.commitUpdate( - taxonomy, - form.attributes, - taxonomy.shadow.attributes.merge(shadow.attributes), - Taxonomies.updateHead) + newTaxonomy ← * <~ ObjectUtils.commitUpdate(taxonomy, + form.attributes, + taxonomy.shadow.attributes.merge(shadow.attributes), + Taxonomies.updateHead) taxons ← * <~ TaxonomyTaxonLinks.queryRightByLeftWithLinks(newTaxonomy.model) } yield FullTaxonomyResponse.build(newTaxonomy, taxons) } - def archiveByContextAndId( - taxonomyFormId: ObjectForm#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[Unit] = + def archiveByContextAndId(taxonomyFormId: ObjectForm#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[Unit] = for { taxonomy ← * <~ Taxonomies.mustFindByFormId404(taxonomyFormId) archived ← * <~ Taxonomies.update(taxonomy, taxonomy.copy(archivedAt = Some(Instant.now))) } yield {} - def getTaxon( - taxonFormId: ObjectForm#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[FullTaxonResponse] = + def getTaxon(taxonFormId: ObjectForm#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[FullTaxonResponse] = for { taxon ← * <~ ObjectManager.getFullObject(Taxons.mustFindByFormId404(taxonFormId)) response ← * <~ buildSingleTaxonResponse(taxon) } yield response - def createTaxon(taxonomyFormId: ObjectForm#Id, payload: CreateTaxonPayload)( - implicit ec: EC, - oc: OC, - au: AU): DbResultT[FullTaxonResponse] = { + def createTaxon( + taxonomyFormId: ObjectForm#Id, + payload: CreateTaxonPayload)(implicit ec: EC, oc: OC, au: AU): DbResultT[FullTaxonResponse] = { val form = ObjectForm.fromPayload(Taxon.kind, payload.attributes) val shadow = ObjectShadow.fromPayload(payload.attributes) @@ -135,24 +124,23 @@ object TaxonomyManager { ins ← * <~ ObjectUtils.insert(form, shadow) taxon ← * <~ Taxons.create( - Taxon(contextId = oc.id, - scope = scope, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) + Taxon(contextId = oc.id, + scope = scope, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) parentLink ← * <~ payload.location.fold(DbResultT.none[TaxonomyTaxonLink])(location ⇒ - validateLocation(taxonomy, taxon, location)) + validateLocation(taxonomy, taxon, location)) index ← * <~ TaxonomyTaxonLinks.nextIndex(taxonomy.id).result - moveSpec ← * <~ MoveSpec( - TaxonomyTaxonLink(index = index, - taxonomyId = taxonomy.id, - taxonId = taxon.id, - position = 0, - path = LTree("")), - parentLink, - payload.location.flatMap(_.position)).validate.map(_.fillLinkWithNewPath) + moveSpec ← * <~ MoveSpec(TaxonomyTaxonLink(index = index, + taxonomyId = taxonomy.id, + taxonId = taxon.id, + position = 0, + path = LTree("")), + parentLink, + payload.location.flatMap(_.position)).validate.map(_.fillLinkWithNewPath) taxonWithPosition ← * <~ TaxonomyTaxonLinks .preparePosition(moveSpec.taxon, payload.location.flatMap(_.position)) link ← * <~ TaxonomyTaxonLinks.create(taxonWithPosition) @@ -165,37 +153,35 @@ object TaxonomyManager { oc: OC): DbResultT[Option[TaxonomyTaxonLink]] = for { parentLink ← * <~ location.parent.fold(DbResultT.none[TaxonomyTaxonLink])( - pid ⇒ - TaxonomyTaxonLinks - .active() - .mustFindByTaxonomyAndTaxonFormId(taxonomy, pid) - .map(Some(_))) + pid ⇒ + TaxonomyTaxonLinks + .active() + .mustFindByTaxonomyAndTaxonFormId(taxonomy, pid) + .map(Some(_))) _ ← * <~ location.position.fold(DbResultT.unit) { position ⇒ - doOrMeh(position != 0, - TaxonomyTaxonLinks - .active() - .findByPathAndPosition(parentLink.map(_.childPath).getOrElse(LTree("")), - position - 1) - .mustFindOneOr(TaxonomyFailures.NoTaxonAtPosition(location.parent, position)) - .meh) + doOrMeh( + position != 0, + TaxonomyTaxonLinks + .active() + .findByPathAndPosition(parentLink.map(_.childPath).getOrElse(LTree("")), position - 1) + .mustFindOneOr(TaxonomyFailures.NoTaxonAtPosition(location.parent, position)) + .meh + ) } } yield parentLink - def updateTaxon(taxonId: Int, payload: UpdateTaxonPayload)( - implicit ec: EC, - oc: OC, - db: DB): DbResultT[FullTaxonResponse] = { + def updateTaxon(taxonId: Int, payload: UpdateTaxonPayload)(implicit ec: EC, + oc: OC, + db: DB): DbResultT[FullTaxonResponse] = for { - taxon ← * <~ Taxons.mustFindByFormId404(taxonId) - _ ← * <~ failIf(taxon.archivedAt.isDefined, TaxonIsArchived(taxonId)) - newTaxon ← * <~ updateTaxonAttributes(taxon, payload) - _ ← * <~ payload.location.fold(DbResultT.unit)(location ⇒ - updateTaxonomyHierarchy(taxon, location).meh) + taxon ← * <~ Taxons.mustFindByFormId404(taxonId) + _ ← * <~ failIf(taxon.archivedAt.isDefined, TaxonIsArchived(taxonId)) + newTaxon ← * <~ updateTaxonAttributes(taxon, payload) + _ ← * <~ payload.location.fold(DbResultT.unit)(location ⇒ updateTaxonomyHierarchy(taxon, location).meh) taxonFull ← * <~ ObjectManager.getFullObject(DbResultT.good(newTaxon)) response ← * <~ buildSingleTaxonResponse(taxonFull) } yield response - } private def buildSingleTaxonResponse(taxonFull: FullObject[Taxon])( implicit ec: EC): DbResultT[FullTaxonResponse] = @@ -210,10 +196,8 @@ object TaxonomyManager { .getOrElse(lift(None)) } yield FullTaxonResponse.build(taxonFull, taxonomy.formId, parentTaxon.map(_.formId)) - private def updateTaxonomyHierarchy(taxon: Taxon, location: TaxonLocationPayload)( - implicit ec: EC, - db: DB, - oc: OC) = + private def updateTaxonomyHierarchy(taxon: Taxon, + location: TaxonLocationPayload)(implicit ec: EC, db: DB, oc: OC) = for { taxonomy ← * <~ mustFindSingleTaxonomyForTaxon(taxon) parentLink ← * <~ validateLocation(taxonomy.model, taxon, location) @@ -224,15 +208,15 @@ object TaxonomyManager { _ ← * <~ doOrMeh(moveSpec.isMoveRequired, moveTaxon(taxonomy.model, moveSpec)) } yield taxonomy - private def mustFindSingleTaxonomyForTaxon( - taxon: Taxon)(implicit ec: EC, db: DB): DbResultT[FullObject[Taxonomy]] = + private def mustFindSingleTaxonomyForTaxon(taxon: Taxon)(implicit ec: EC, + db: DB): DbResultT[FullObject[Taxonomy]] = for { taxonomies ← * <~ TaxonomyTaxonLinks.queryLeftByRight(taxon) taxonomy ← * <~ (taxonomies.toList match { - case t :: Nil ⇒ DbResultT.good(t) - case _ ⇒ - DbResultT.failure(InvalidTaxonomiesForTaxon(taxon, taxonomies.length)) - }) + case t :: Nil ⇒ DbResultT.good(t) + case _ ⇒ + DbResultT.failure(InvalidTaxonomiesForTaxon(taxon, taxonomies.length)) + }) } yield taxonomy private def moveTaxon(taxon: Taxonomy, moveSpec: MoveSpec)(implicit ec: EC, oc: OC, db: DB) = @@ -240,32 +224,30 @@ object TaxonomyManager { _ ← * <~ TaxonomyTaxonLinks.archive(moveSpec.taxon) newPath = moveSpec.newPath beforePositioning ← * <~ moveSpec.taxon.copy(id = 0, position = 0, path = newPath) - linkToCreate ← * <~ TaxonomyTaxonLinks.preparePosition(beforePositioning, - moveSpec.newPosition) + linkToCreate ← * <~ TaxonomyTaxonLinks.preparePosition(beforePositioning, moveSpec.newPosition) newLink ← * <~ TaxonomyTaxonLinks.create(linkToCreate) _ ← * <~ TaxonomyTaxonLinks.updatePaths( - taxon.id, - moveSpec.taxon.childPath, - newPath.copy(value = newPath.value ::: List(moveSpec.taxon.index.toString))) + taxon.id, + moveSpec.taxon.childPath, + newPath.copy(value = newPath.value ::: List(moveSpec.taxon.index.toString))) } yield {} - private def updateTaxonAttributes( - taxon: Taxon, - payload: UpdateTaxonPayload)(implicit ec: EC, db: DB, oc: OC): DbResultT[Taxon] = { + private def updateTaxonAttributes(taxon: Taxon, payload: UpdateTaxonPayload)(implicit ec: EC, + db: DB, + oc: OC): DbResultT[Taxon] = { val form = ObjectForm.fromPayload(Taxon.kind, payload.attributes) val shadow = ObjectShadow.fromPayload(payload.attributes) for { fullTaxon ← * <~ ObjectManager.getFullObject(DbResultT.good(taxon)) - newTaxon ← * <~ ObjectUtils.commitUpdate( - fullTaxon, - form.attributes, - fullTaxon.shadow.attributes.merge(shadow.attributes), - Taxons.updateHead) + newTaxon ← * <~ ObjectUtils.commitUpdate(fullTaxon, + form.attributes, + fullTaxon.shadow.attributes.merge(shadow.attributes), + Taxons.updateHead) } yield newTaxon.model } @@ -276,15 +258,13 @@ object TaxonomyManager { _ ← * <~ Taxons.update(taxon, taxon.copy(archivedAt = Some(Instant.now))) links ← * <~ TaxonomyTaxonLinks.filterByTaxonFormId(taxonFormId).result children ← * <~ links.map(link ⇒ TaxonomyTaxonLinks.hasChildren(link).result.dbresult) - _ ← * <~ failIf(children.exists(identity), - TaxonomyFailures.CannotArchiveParentTaxon(taxonFormId)) - _ ← * <~ links.map(TaxonomyTaxonLinks.archive) + _ ← * <~ failIf(children.exists(identity), TaxonomyFailures.CannotArchiveParentTaxon(taxonFormId)) + _ ← * <~ links.map(TaxonomyTaxonLinks.archive) } yield {} - def assignProduct(taxonFormId: ObjectForm#Id, productFormId: ObjectForm#Id)( - implicit ec: EC, - oc: OC, - db: DB): DbResultT[Seq[AssignedTaxonsResponse]] = + def assignProduct( + taxonFormId: ObjectForm#Id, + productFormId: ObjectForm#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[Seq[AssignedTaxonsResponse]] = for { taxon ← * <~ Taxons.mustFindByFormId404(taxonFormId) product ← * <~ Products.mustFindByFormId404(productFormId) @@ -292,10 +272,9 @@ object TaxonomyManager { assigned ← * <~ getAssignedTaxons(product) } yield assigned - def unassignProduct(taxonFormId: ObjectForm#Id, productFormId: ObjectForm#Id)( - implicit ec: EC, - oc: OC, - db: DB): DbResultT[Seq[AssignedTaxonsResponse]] = + def unassignProduct( + taxonFormId: ObjectForm#Id, + productFormId: ObjectForm#Id)(implicit ec: EC, oc: OC, db: DB): DbResultT[Seq[AssignedTaxonsResponse]] = for { taxon ← * <~ Taxons.mustFindByFormId404(taxonFormId) product ← * <~ Products.mustFindByFormId404(productFormId) @@ -303,23 +282,19 @@ object TaxonomyManager { .filterLeft(product) .filter(_.rightId === taxon.id) .deleteAll(DbResultT.none, - DbResultT.failure( - TaxonomyFailures.CannotUnassignProduct(taxon.formId, product.formId))) + DbResultT.failure(TaxonomyFailures.CannotUnassignProduct(taxon.formId, product.formId))) assigned ← * <~ getAssignedTaxons(product) } yield assigned - def getAssignedTaxons(productRef: ProductReference)( - implicit ec: EC, - oc: OC, - db: DB): DbResultT[Seq[AssignedTaxonsResponse]] = + def getAssignedTaxons( + productRef: ProductReference)(implicit ec: EC, oc: OC, db: DB): DbResultT[Seq[AssignedTaxonsResponse]] = for { product ← * <~ Products.mustFindByReference(productRef) assigned ← * <~ getAssignedTaxons(product) } yield assigned - def getAssignedTaxons(product: Product)(implicit ec: EC, - oc: OC, - db: DB): DbResultT[Seq[AssignedTaxonsResponse]] = { + def getAssignedTaxons( + product: Product)(implicit ec: EC, oc: OC, db: DB): DbResultT[Seq[AssignedTaxonsResponse]] = { val assignedTaxons = ProductTaxonLinks.filterLeft(product).flatMap(_.right) @@ -328,12 +303,13 @@ object TaxonomyManager { .join(assignedTaxons) .on { case (link, taxons) ⇒ link.rightId === taxons.id } .join(Taxonomies) - .on { case ((link, _), taxonomy) ⇒ link.leftId === taxonomy.id } + .on { case ((link, _), taxonomy) ⇒ link.leftId === taxonomy.id } .map { case ((_, taxon), taxonomy) ⇒ (taxonomy, taxon) } for { assignedTaxonomies ← * <~ assignedTaxonomiesQuery.result - (taxonomies, taxons) = assignedTaxonomies.groupBy { case (taxonomy, _) ⇒ taxonomy } + (taxonomies, taxons) = assignedTaxonomies + .groupBy { case (taxonomy, _) ⇒ taxonomy } .mapValues(_.map { case (_, taxon) ⇒ taxon }) .unzip diff --git a/phoenix-scala/phoenix/app/phoenix/services/tree/TreeManager.scala b/phoenix-scala/phoenix/app/phoenix/services/tree/TreeManager.scala index bfa02647eb..f1ba92360f 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/tree/TreeManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/tree/TreeManager.scala @@ -15,17 +15,15 @@ import phoenix.responses.GenericTreeResponses._ object TreeManager { - def getFullTree(treeName: String, contextName: String)(implicit ec: EC, - db: DB): DbResultT[Root] = + def getFullTree(treeName: String, contextName: String)(implicit ec: EC, db: DB): DbResultT[Root] = for { context ← * <~ ObjectManager.mustFindByName404(contextName) response ← * <~ getFullTree(treeName, context) } yield response - def updateTree(treeName: String, - contextName: String, - newTree: NodePayload, - path: Option[String] = None)(implicit ec: EC, db: DB): DbResultT[Root] = + def updateTree(treeName: String, contextName: String, newTree: NodePayload, path: Option[String] = None)( + implicit ec: EC, + db: DB): DbResultT[Root] = for { context ← * <~ ObjectManager.mustFindByName404(contextName) tree ← * <~ getOrCreateDbTree(treeName, context, path.isEmpty) @@ -43,9 +41,8 @@ object TreeManager { resultTree ← * <~ getFullTree(treeName, context) } yield resultTree - def moveNode(treeName: String, contextName: String, moveSpec: MoveNodePayload)( - implicit ec: EC, - db: DB): DbResultT[Root] = + def moveNode(treeName: String, contextName: String, moveSpec: MoveNodePayload)(implicit ec: EC, + db: DB): DbResultT[Root] = for { context ← * <~ ObjectManager.mustFindByName404(contextName) tree ← * <~ getOrCreateDbTree(treeName, context) @@ -55,11 +52,11 @@ object TreeManager { shouldBeDeleted = moveSpec.index.isEmpty _ ← * <~ (if (shouldBeDeleted) GenericTreeNodes.deleteById( - newChildNode.id, - DbResultT.unit, - _ ⇒ - DatabaseFailure( - s"cannot delete node: index=${newChildNode.index}, tree=$treeName, context=$contextName")) + newChildNode.id, + DbResultT.unit, + _ ⇒ + DatabaseFailure( + s"cannot delete node: index=${newChildNode.index}, tree=$treeName, context=$contextName")) else moveNode(tree.id, moveSpec.index.get, newChildNode)) resultTree ← * <~ getFullTree(treeName, context) } yield resultTree @@ -78,8 +75,7 @@ object TreeManager { result ← * <~ getFullTree(treeName, context) } yield result - def getByNameAndContext(name: String, context: ObjectContext)( - implicit ec: EC): DbResultT[GenericTree] = + def getByNameAndContext(name: String, context: ObjectContext)(implicit ec: EC): DbResultT[GenericTree] = GenericTrees .filterByNameAndContext(name, context.id) .mustFindOneOr(TreeNotFound(name, context.name)) @@ -95,10 +91,9 @@ object TreeManager { fullTreeResponse = build(response, List()) } yield fullTreeResponse - private def getOrCreateDbTree( - treeName: String, - context: ObjectContext, - createIfNotFound: Boolean = false)(implicit ec: EC, db: DB): DbResultT[GenericTree] = { + private def getOrCreateDbTree(treeName: String, context: ObjectContext, createIfNotFound: Boolean = false)( + implicit ec: EC, + db: DB): DbResultT[GenericTree] = { val ifEmptyAction: DbResultT[GenericTree] = if (createIfNotFound) GenericTrees.create(GenericTree(0, treeName, context.id)) @@ -110,9 +105,8 @@ object TreeManager { } yield tree } - private def moveNode(treeId: Int, parentIndex: Int, childNode: GenericTreeNode)( - implicit ec: EC, - db: DB): DbResultT[Int] = + private def moveNode(treeId: Int, parentIndex: Int, childNode: GenericTreeNode)(implicit ec: EC, + db: DB): DbResultT[Int] = for { parentNode ← * <~ GenericTreeNodes .findNodesByIndex(treeId, parentIndex) diff --git a/phoenix-scala/phoenix/app/phoenix/services/variant/VariantManager.scala b/phoenix-scala/phoenix/app/phoenix/services/variant/VariantManager.scala index 1a76456a43..faa832228c 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/variant/VariantManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/variant/VariantManager.scala @@ -22,10 +22,9 @@ object VariantManager { implicit val formats: Formats = JsonFormatters.phoenixFormats - def createVariant(contextName: String, payload: VariantPayload)( - implicit ec: EC, - db: DB, - au: AU): DbResultT[IlluminatedVariantResponse.Root] = + def createVariant( + contextName: String, + payload: VariantPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[IlluminatedVariantResponse.Root] = for { context ← * <~ ObjectManager.mustFindByName404(contextName) fullVariant ← * <~ createVariantInner(context, payload) @@ -40,26 +39,24 @@ object VariantManager { .toMap } yield IlluminatedVariantResponse.build( - variant = IlluminatedVariant.illuminate(context, variant), - variantValues = values, - variantValueSkus = variantToSkuMapping + variant = IlluminatedVariant.illuminate(context, variant), + variantValues = values, + variantValueSkus = variantToSkuMapping ) - def getVariant(contextName: String, variantId: Int)( - implicit ec: EC, - db: DB): DbResultT[IlluminatedVariantResponse.Root] = + def getVariant(contextName: String, variantId: Int)(implicit ec: EC, + db: DB): DbResultT[IlluminatedVariantResponse.Root] = for { - context ← * <~ ObjectManager.mustFindByName404(contextName) - fullVariant ← * <~ ObjectManager.getFullObject( - mustFindVariantByContextAndForm(context.id, variantId)) + context ← * <~ ObjectManager.mustFindByName404(contextName) + fullVariant ← * <~ ObjectManager.getFullObject(mustFindVariantByContextAndForm(context.id, variantId)) values ← * <~ VariantValueLinks.queryRightByLeft(fullVariant.model) variantValueSkuCodes ← * <~ VariantManager.getVariantValueSkuCodes(values.map(_.model.id)) } yield IlluminatedVariantResponse.build( - variant = IlluminatedVariant.illuminate(context, fullVariant), - variantValues = values, - variantValueSkus = variantValueSkuCodes + variant = IlluminatedVariant.illuminate(context, fullVariant), + variantValues = values, + variantValueSkus = variantValueSkuCodes ) def updateVariant(contextName: String, variantId: Int, payload: VariantPayload)( @@ -73,14 +70,13 @@ object VariantManager { variantValueSkuCodes ← * <~ VariantManager.getVariantValueSkuCodes(values.map(_.model.id)) } yield IlluminatedVariantResponse.build( - variant = IlluminatedVariant.illuminate(context, variant), - variantValues = values, - variantValueSkus = variantValueSkuCodes + variant = IlluminatedVariant.illuminate(context, variant), + variantValues = values, + variantValueSkus = variantValueSkuCodes ) - def createVariantInner( - context: ObjectContext, - payload: VariantPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[FullVariant] = { + def createVariantInner(context: ObjectContext, + payload: VariantPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[FullVariant] = { val form = ObjectForm.fromPayload(Variant.kind, payload.attributes) val shadow = ObjectShadow.fromPayload(payload.attributes) @@ -90,27 +86,25 @@ object VariantManager { scope ← * <~ Scope.resolveOverride(payload.scope) ins ← * <~ ObjectUtils.insert(form, shadow, payload.schema) variant ← * <~ Variants.create( - Variant(scope = scope, - contextId = context.id, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) + Variant(scope = scope, + contextId = context.id, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) values ← * <~ variantValues.map(createVariantValueInner(context, variant, _)) } yield (FullObject(variant, ins.form, ins.shadow), values) } - def updateVariantInner(context: ObjectContext, variantId: Int, payload: VariantPayload)( - implicit ec: EC, - db: DB, - au: AU): DbResultT[FullVariant] = { + def updateVariantInner(context: ObjectContext, + variantId: Int, + payload: VariantPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[FullVariant] = { val newFormAttrs = ObjectForm.fromPayload(Variant.kind, payload.attributes).attributes val newShadowAttrs = ObjectShadow.fromPayload(payload.attributes).attributes val valuePayloads = payload.values.getOrElse(Seq.empty) for { - oldVariant ← * <~ ObjectManager.getFullObject( - mustFindVariantByContextAndForm(context.id, variantId)) + oldVariant ← * <~ ObjectManager.getFullObject(mustFindVariantByContextAndForm(context.id, variantId)) mergedAttrs = oldVariant.shadow.attributes.merge(newShadowAttrs) updated ← * <~ ObjectUtils.update(oldVariant.form.id, @@ -127,19 +121,16 @@ object VariantManager { } yield (FullObject(updatedHead, updated.form, updated.shadow), values) } - def updateOrCreateVariant( - context: ObjectContext, - payload: VariantPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[FullVariant] = { - + def updateOrCreateVariant(context: ObjectContext, payload: VariantPayload)(implicit ec: EC, + db: DB, + au: AU): DbResultT[FullVariant] = payload.id match { case Some(id) ⇒ updateVariantInner(context, id, payload) case None ⇒ createVariantInner(context, payload) } - } - private def updateHead(variant: Variant, - shadow: ObjectShadow, - maybeCommit: Option[ObjectCommit])(implicit ec: EC): DbResultT[Variant] = + private def updateHead(variant: Variant, shadow: ObjectShadow, maybeCommit: Option[ObjectCommit])( + implicit ec: EC): DbResultT[Variant] = maybeCommit match { case Some(commit) ⇒ Variants.update(variant, variant.copy(shadowId = shadow.id, commitId = commit.id)) @@ -159,9 +150,7 @@ object VariantManager { value ← * <~ createVariantValueInner(context, variant, payload) } yield IlluminatedVariantValueResponse.build(value, payload.skuCodes) - private def createVariantValueInner(context: ObjectContext, - variant: Variant, - payload: VariantValuePayload)( + private def createVariantValueInner(context: ObjectContext, variant: Variant, payload: VariantValuePayload)( implicit ec: EC, db: DB, au: AU): DbResultT[FullObject[VariantValue]] = { @@ -171,21 +160,17 @@ object VariantManager { for { scope ← * <~ Scope.resolveOverride(payload.scope) skuCodes ← * <~ payload.skuCodes.map(SkuManager.mustFindSkuByContextAndCode(context.id, _)) - _ ← * <~ skuCodes.map(sku ⇒ - DbResultT.fromEither(sku.mustNotBeArchived(Variant, variant.formId))) - ins ← * <~ ObjectUtils.insert(form, shadow, payload.schema) + _ ← * <~ skuCodes.map(sku ⇒ DbResultT.fromEither(sku.mustNotBeArchived(Variant, variant.formId))) + ins ← * <~ ObjectUtils.insert(form, shadow, payload.schema) variantValue ← * <~ VariantValues.create( - VariantValue(scope = scope, - contextId = context.id, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) - _ ← * <~ VariantValueLinks.create( - VariantValueLink(leftId = variant.id, rightId = variantValue.id)) - _ ← * <~ skuCodes.map( - s ⇒ - VariantValueSkuLinks.create( - VariantValueSkuLink(leftId = variantValue.id, rightId = s.id))) + VariantValue(scope = scope, + contextId = context.id, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) + _ ← * <~ VariantValueLinks.create(VariantValueLink(leftId = variant.id, rightId = variantValue.id)) + _ ← * <~ skuCodes.map(s ⇒ + VariantValueSkuLinks.create(VariantValueSkuLink(leftId = variantValue.id, rightId = s.id))) } yield FullObject(variantValue, ins.form, ins.shadow) } @@ -215,26 +200,21 @@ object VariantManager { toCreate = newSkuIds.diff(linkedSkuIds) _ ← * <~ VariantValueSkuLinks.createAll( - toCreate.map(id ⇒ VariantValueSkuLink(leftId = value.id, rightId = id))) + toCreate.map(id ⇒ VariantValueSkuLink(leftId = value.id, rightId = id))) _ ← * <~ VariantValueSkuLinks.filter(_.id inSet toDelete.map(_.id)).delete } yield FullObject(updatedHead, updated.form, updated.shadow) } - private def updateOrCreateVariantValue( - variant: Variant, - context: ObjectContext, - payload: VariantValuePayload)(implicit ec: EC, db: DB, au: AU) = { - + private def updateOrCreateVariantValue(variant: Variant, + context: ObjectContext, + payload: VariantValuePayload)(implicit ec: EC, db: DB, au: AU) = payload.id match { case Some(id) ⇒ updateVariantValueInner(id, context.id, payload) case None ⇒ createVariantValueInner(context, variant, payload) } - } - private def updateValueHead( - value: VariantValue, - shadow: ObjectShadow, - maybeCommit: Option[ObjectCommit])(implicit ec: EC): DbResultT[VariantValue] = + private def updateValueHead(value: VariantValue, shadow: ObjectShadow, maybeCommit: Option[ObjectCommit])( + implicit ec: EC): DbResultT[VariantValue] = maybeCommit match { case Some(commit) ⇒ VariantValues.update(value, value.copy(shadowId = shadow.id, commitId = commit.id)) @@ -250,18 +230,19 @@ object VariantManager { values ← * <~ variants.map(findValuesForVariant) } yield variants.zip(values) - def findValuesForVariant(variant: FullObject[Variant])( - implicit ec: EC, - db: DB): DbResultT[Seq[FullObject[VariantValue]]] = + def findValuesForVariant(variant: FullObject[Variant])(implicit ec: EC, + db: DB): DbResultT[Seq[FullObject[VariantValue]]] = VariantValueLinks.queryRightByLeft(variant.model) - def getVariantValueSkuCodes( - variantValueHeadIds: Seq[Int])(implicit ec: EC, db: DB): DbResultT[Map[Int, Seq[String]]] = + def getVariantValueSkuCodes(variantValueHeadIds: Seq[Int])(implicit ec: EC, + db: DB): DbResultT[Map[Int, Seq[String]]] = for { links ← * <~ VariantValueSkuLinks.findSkusForVariantValues(variantValueHeadIds).result - linksMapping = links.groupBy { case (valueId, _) ⇒ valueId }.mapValues(_.map { - case (_, skuCode) ⇒ skuCode - }) + linksMapping = links + .groupBy { case (valueId, _) ⇒ valueId } + .mapValues(_.map { + case (_, skuCode) ⇒ skuCode + }) } yield linksMapping private def mustFindVariantValueByContextAndForm(contextId: Int, formId: Int)( @@ -303,8 +284,7 @@ object VariantManager { .mustFindOneOr(VariantNotFoundForContext(form.id, contextId)) } yield FullObject(variant, form, shadow) - def mustFindFullVariantWithValuesById( - id: Int)(implicit ec: EC, db: DB, oc: OC): DbResultT[FullVariant] = + def mustFindFullVariantWithValuesById(id: Int)(implicit ec: EC, db: DB, oc: OC): DbResultT[FullVariant] = for { fullVariant ← * <~ ObjectManager.getFullObject(Variants.mustFindById404(id)) values ← * <~ findValuesForVariant(fullVariant) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/ElasticsearchApi.scala b/phoenix-scala/phoenix/app/phoenix/utils/ElasticsearchApi.scala index 5924c410a0..65338d0523 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/ElasticsearchApi.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/ElasticsearchApi.scala @@ -50,7 +50,7 @@ case class ElasticsearchApi(config: ESConfig)(implicit ec: EC) extends LazyLoggi val request = search in indexAndType rawQuery queryString aggregations ( - aggregation filter aggregationName filter termsQuery(fieldName, references.toList: _*) + aggregation filter aggregationName filter termsQuery(fieldName, references.toList: _*) ) size 0 logQuery(indexAndType, request.show) @@ -82,26 +82,26 @@ case class ElasticsearchApi(config: ESConfig)(implicit ec: EC) extends LazyLoggi val indexAndType = getIndexAndType(searchView) val request = search in indexAndType rawQuery queryString aggregations ( - aggregation terms aggregationName script s"doc['$fieldName'].value" - ) size 0 + aggregation terms aggregationName script s"doc['$fieldName'].value" + ) size 0 logQuery(indexAndType, request.show) client.execute(request).map(getBuckets) } def numResults(searchView: SearchView, esQuery: Json): Future[Long] = - client.execute { - search in getIndexAndType(searchView) rawQuery compact(render(esQuery)) size 0 - }.map(_.totalHits) + client + .execute { + search in getIndexAndType(searchView) rawQuery compact(render(esQuery)) size 0 + } + .map(_.totalHits) /** * Render compact query for logging */ - private def logQuery(indexAndType: IndexAndType, query: String): Unit = { - logger.debug( - s"Preparing Elasticsearch query to ${indexAndType.index}/${indexAndType.`type`}: ${compact( - render(parse(query)))}") - } + private def logQuery(indexAndType: IndexAndType, query: String): Unit = + logger.debug(s"Preparing Elasticsearch query to ${indexAndType.index}/${indexAndType.`type`}: ${compact( + render(parse(query)))}") } @@ -130,9 +130,7 @@ object ElasticsearchApi { def fromConfig(config: FoxConfig)(implicit ec: EC): ElasticsearchApi = ElasticsearchApi(config.apis.elasticsearch) - protected def injectFilterReferences(query: Json, - fieldName: String, - references: Seq[String]): Json = { + protected def injectFilterReferences(query: Json, fieldName: String, references: Seq[String]): Json = { val refFilter = JObject("terms" → JObject(fieldName → JArray(references.map(JString).toList))) val currentFilter = query \ "bool" \ "filter" currentFilter match { diff --git a/phoenix-scala/phoenix/app/phoenix/utils/FSM.scala b/phoenix-scala/phoenix/app/phoenix/utils/FSM.scala index 0ef2cd5d53..6c1d2a2678 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/FSM.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/FSM.scala @@ -23,11 +23,10 @@ trait FSM[S, M <: FSM[S, M]] { self: M ⇒ case Some(states) if states.contains(newState) ⇒ Either.right(stateLens.set(this)(newState)) case _ ⇒ - Either.left( - StateTransitionNotAllowed(self, - currentState.toString, - newState.toString, - primarySearchKey).single) + Either.left(StateTransitionNotAllowed(self, + currentState.toString, + newState.toString, + primarySearchKey).single) } def transitionAllowed(newState: S): Boolean = transitionState(newState).isRight diff --git a/phoenix-scala/phoenix/app/phoenix/utils/HashPasswords.scala b/phoenix-scala/phoenix/app/phoenix/utils/HashPasswords.scala index c05a5e2e48..f6d393de9c 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/HashPasswords.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/HashPasswords.scala @@ -38,13 +38,11 @@ object HashPasswords { } case class SCryptImpl(cpuCost: Int, memCost: Int, parallelization: Int) extends HashPasswords { - def generateHash(password: String): String = { + def generateHash(password: String): String = SCryptUtil.scrypt(password, cpuCost, memCost, parallelization) - } - def checkHash(password: String, hash: String): Boolean = { + def checkHash(password: String, hash: String): Boolean = Try { SCryptUtil.check(password, hash) }.getOrElse(false) - } } case class UnknownAlgorithm(code: Int = 65535) extends HashAlgorithm with HashPasswords { diff --git a/phoenix-scala/phoenix/app/phoenix/utils/TestStripeSupport.scala b/phoenix-scala/phoenix/app/phoenix/utils/TestStripeSupport.scala index 339b7b1cd1..0b2694fe1f 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/TestStripeSupport.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/TestStripeSupport.scala @@ -32,46 +32,46 @@ object TestStripeSupport { expMonth: Int, cvv: Int, address: Address): Result[Token] = { - val card = Map[String, Any]("number" → cardNumber, - "exp_month" → expMonth, - "exp_year" → expYear, - "cvc" → cvv, - "name" → address.name, - "address_line1" → address.address1, - "address_line2" → address.address2.orNull, - "address_city" → address.city, - "address_zip" → address.zip) + val card = Map[String, Any]( + "number" → cardNumber, + "exp_month" → expMonth, + "exp_year" → expYear, + "cvc" → cvv, + "name" → address.name, + "address_line1" → address.address1, + "address_line2" → address.address2.orNull, + "address_city" → address.city, + "address_zip" → address.zip + ) stripe.inBlockingPool(Token.create(Map("card" → mapAsJavaMap(card)))) } - def getCustomer(id: String): Result[StripeCustomer] = { + def getCustomer(id: String): Result[StripeCustomer] = stripe.findCustomer(id) - } - def deleteCustomer(customer: StripeCustomer): Result[DeletedCustomer] = { + def deleteCustomer(customer: StripeCustomer): Result[DeletedCustomer] = stripe.inBlockingPool(customer.delete) - } // https://stripe.com/docs/testing#cards private[this] val successfulCards = Map( - "Visa" → "4242424242424242", - "Visa (debit)" → "4000056655665556", - "MasterCard" → "5555555555554444", - "MasterCard (debit)" → "5200828282828210", - "MasterCard (prepaid)" → "5105105105105100", - "American Express" → "378282246310005", - "Discover" → "6011111111111117", - "Diners Club" → "30569309025904", - "JCB" → "3530111333300000" + "Visa" → "4242424242424242", + "Visa (debit)" → "4000056655665556", + "MasterCard" → "5555555555554444", + "MasterCard (debit)" → "5200828282828210", + "MasterCard (prepaid)" → "5105105105105100", + "American Express" → "378282246310005", + "Discover" → "6011111111111117", + "Diners Club" → "30569309025904", + "JCB" → "3530111333300000" ) // https://stripe.com/docs/testing#cards private[this] val failureCards = Map( - "card_declined" → "4000000000000002", - "incorrect_number" → "4242424242424241", // fails the Luhn check - "expired_card" → "4000000000000069", - "incorrect_cvc_code" → "4000000000000127" + "card_declined" → "4000000000000002", + "incorrect_number" → "4242424242424241", // fails the Luhn check + "expired_card" → "4000000000000069", + "incorrect_cvc_code" → "4000000000000127" ) def successfulCard: String = diff --git a/phoenix-scala/phoenix/app/phoenix/utils/Typeclasses.scala b/phoenix-scala/phoenix/app/phoenix/utils/Typeclasses.scala index 066a147f14..8d78e41e4e 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/Typeclasses.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/Typeclasses.scala @@ -39,7 +39,7 @@ trait ADT[F] extends Read[F] with Show[F] { self ⇒ */ def jsonFormat(implicit m: Manifest[F]): CustomSerializer[F] = new CustomSerializer[F](format ⇒ - ({ + ({ case JString(str) ⇒ read(str) .getOrError(s"No such element: $str") // if we cannot deserialize then we throw. Yes, I know it's not *pure*. @@ -52,7 +52,7 @@ trait ADT[F] extends Read[F] with Show[F] { self ⇒ // thanks json4s! def jsonKeyFormat(implicit m: Manifest[F]): CustomKeySerializer[F] = new CustomKeySerializer[F](format ⇒ - ({ + ({ case str ⇒ read(str) .getOrError(s"No such element: $str") // if we cannot deserialize then we throw. Yes, I know it's not *pure*. @@ -67,8 +67,7 @@ trait ADT[F] extends Read[F] with Show[F] { self ⇒ case f ⇒ read(f).getOrError(s"No such element: $f") }) - lazy val pathMatcher: PathMatcher1[F] = PathMatcher( - TreeMap(typeMap.toList: _*)(Ordering[String].reverse)) + lazy val pathMatcher: PathMatcher1[F] = PathMatcher(TreeMap(typeMap.toList: _*)(Ordering[String].reverse)) } object ADT { @inline def apply[T](implicit adt: ADT[T]): ADT[T] = adt @@ -106,9 +105,11 @@ object Chunkable { private[this] val fieldsSet = fields.toSet def bytes(t: CsvData): ByteString = - ByteString(t.collect { - case (field, value) if fieldsSet.contains(field) ⇒ value - }.mkString(",")) + ByteString( + t.collect { + case (field, value) if fieldsSet.contains(field) ⇒ value + } + .mkString(",")) override def bytes(s: Source[CsvData, NotUsed]): Source[ByteString, NotUsed] = { val elSep = ByteString("\n") diff --git a/phoenix-scala/phoenix/app/phoenix/utils/apis/AmazonApi.scala b/phoenix-scala/phoenix/app/phoenix/utils/apis/AmazonApi.scala index c5e3c83365..8189ab62e3 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/apis/AmazonApi.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/apis/AmazonApi.scala @@ -26,14 +26,13 @@ class AmazonS3 extends AmazonApi with LazyLogging { private[this] val credentials = new BasicAWSCredentials(accessKey, secretKey) private[this] val client = new AmazonS3Client(credentials) - def uploadFileF(fileName: String, file: File)(implicit ec: EC): Future[String] = { + def uploadFileF(fileName: String, file: File)(implicit ec: EC): Future[String] = Future { val putRequest = new PutObjectRequest(s3Bucket, fileName, file) .withCannedAcl(CannedAccessControlList.PublicRead) client.putObject(putRequest) s"https://s3-$s3Region.amazonaws.com/$s3Bucket/$fileName" } - } def uploadFile(fileName: String, file: File)(implicit ec: EC): Result[String] = { val f = uploadFileF(fileName, file).map(Either.right).recover { diff --git a/phoenix-scala/phoenix/app/phoenix/utils/apis/FoxStripe.scala b/phoenix-scala/phoenix/app/phoenix/utils/apis/FoxStripe.scala index 708bf5433c..8dc77653e4 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/apis/FoxStripe.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/apis/FoxStripe.scala @@ -18,33 +18,34 @@ import scala.collection.JavaConversions._ */ class FoxStripe(stripe: StripeWrapper)(implicit ec: EC) extends FoxStripeApi { - def createCardFromToken( - email: Option[String], - token: String, - stripeCustomerId: Option[String], - address: Address)(implicit ec: EC): Result[(StripeCustomer, StripeCard)] = email match { - case Some(e) ⇒ - createCardAndMaybeCustomer(e, Map("source" → token), stripeCustomerId, address) - case _ ⇒ - Result.failure(CustomerMustHaveCredentials) - } + def createCardFromToken(email: Option[String], + token: String, + stripeCustomerId: Option[String], + address: Address)(implicit ec: EC): Result[(StripeCustomer, StripeCard)] = + email match { + case Some(e) ⇒ + createCardAndMaybeCustomer(e, Map("source" → token), stripeCustomerId, address) + case _ ⇒ + Result.failure(CustomerMustHaveCredentials) + } @deprecated(message = "Use `createCardFromToken` instead", "Until we are PCI compliant") - def createCardFromSource( - email: Option[String], - card: CreateCreditCardFromSourcePayload, - stripeCustomerId: Option[String], - address: Address)(implicit ec: EC): Result[(StripeCustomer, StripeCard)] = { - lazy val details = Map[String, Object]("object" → "card", - "number" → card.cardNumber, - "exp_month" → card.expMonth.toString, - "exp_year" → card.expYear.toString, - "cvc" → card.cvv, - "name" → card.holderName, - "address_line1" → address.address1, - "address_line2" → address.address2.orNull, - "address_city" → address.city, - "address_zip" → address.zip) + def createCardFromSource(email: Option[String], + card: CreateCreditCardFromSourcePayload, + stripeCustomerId: Option[String], + address: Address)(implicit ec: EC): Result[(StripeCustomer, StripeCard)] = { + lazy val details = Map[String, Object]( + "object" → "card", + "number" → card.cardNumber, + "exp_month" → card.expMonth.toString, + "exp_year" → card.expYear.toString, + "cvc" → card.cvv, + "name" → card.holderName, + "address_line1" → address.address1, + "address_line2" → address.address2.orNull, + "address_city" → address.city, + "address_zip" → address.zip + ) lazy val source = Map("source" → mapAsJavaMap(details)) email match { @@ -58,18 +59,17 @@ class FoxStripe(stripe: StripeWrapper)(implicit ec: EC) extends FoxStripeApi { source: Map[String, Object], stripeCustomerId: Option[String], address: Address)(implicit ec: EC): Result[(StripeCustomer, StripeCard)] = { - def existingCustomer(id: String): Result[(StripeCustomer, StripeCard)] = { + def existingCustomer(id: String): Result[(StripeCustomer, StripeCard)] = for { cust ← stripe.findCustomer(id) card ← stripe.createCard(cust, source) } yield (cust, card) - } def newCustomer: Result[(StripeCustomer, StripeCard)] = { val params = Map[String, Object]( - "description" → "FoxCommerce", - "email" → email - ) ++ source + "description" → "FoxCommerce", + "email" → email + ) ++ source for { cust ← stripe.createCustomer(params) @@ -87,10 +87,10 @@ class FoxStripe(stripe: StripeWrapper)(implicit ec: EC) extends FoxStripeApi { import scala.collection.mutable val chargeMap: mutable.Map[String, AnyRef] = mutable.Map( - "amount" → amount.toString, - "currency" → currency.toString, - "source" → paymentSourceId, - "capture" → (false: java.lang.Boolean) + "amount" → amount.toString, + "currency" → currency.toString, + "source" → paymentSourceId, + "capture" → (false: java.lang.Boolean) ) // we must pass customer.id for cc and must not for Apple Pay @@ -103,23 +103,21 @@ class FoxStripe(stripe: StripeWrapper)(implicit ec: EC) extends FoxStripeApi { stripe.captureCharge(chargeId, Map[String, Object]("amount" → amount.toString)) def authorizeRefund(chargeId: String, amount: Long, reason: RefundReason): Result[StripeCharge] = - stripe.refundCharge( - chargeId, - Map[String, Object]("amount" → amount.toString, "reason" → reason.apiValue)) + stripe.refundCharge(chargeId, Map[String, Object]("amount" → amount.toString, "reason" → reason.apiValue)) def editCard(cc: CreditCard): Result[StripeCard] = { def update(stripeCard: StripeCard): Result[StripeCard] = { val params = Map[String, Object]( - "address_line1" → cc.address.address1, - "address_line2" → cc.address.address2, - // ("address_state" → cc.region), - "address_zip" → cc.address.zip, - "address_city" → cc.address.city, - "name" → cc.address.name, - "exp_year" → cc.expYear.toString, - "exp_month" → cc.expMonth.toString + "address_line1" → cc.address.address1, + "address_line2" → cc.address.address2, + // ("address_state" → cc.region), + "address_zip" → cc.address.zip, + "address_city" → cc.address.city, + "name" → cc.address.name, + "exp_year" → cc.expYear.toString, + "exp_month" → cc.expMonth.toString ) stripe.updateCard(stripeCard, params) @@ -134,12 +132,11 @@ class FoxStripe(stripe: StripeWrapper)(implicit ec: EC) extends FoxStripeApi { private def getCard(gatewayCustomerId: String, gatewayCardId: String): Result[StripeCard] = stripe.findCardByCustomerId(gatewayCustomerId, gatewayCardId) - def deleteCard(cc: CreditCard): Result[DeletedCard] = { + def deleteCard(cc: CreditCard): Result[DeletedCard] = for { stripeCard ← getCard(cc.gatewayCustomerId, cc.gatewayCardId) updated ← stripe.deleteCard(stripeCard) } yield updated - } def retrieveToken(t: String): Result[StripeToken] = stripe.retrieveToken(t) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/apis/MiddlewarehouseApi.scala b/phoenix-scala/phoenix/app/phoenix/utils/apis/MiddlewarehouseApi.scala index be08fd4c17..392595b661 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/apis/MiddlewarehouseApi.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/apis/MiddlewarehouseApi.scala @@ -35,7 +35,7 @@ class Middlewarehouse(url: String) extends MiddlewarehouseApi with LazyLogging { strings.flatMap(errors ⇒ Failures(errors.map(MiddlewarehouseError): _*)) private def parseListOfMwhInfoErrors( - maybeErrors: Option[List[MiddlewarehouseErrorInfo]]): Option[Failures] = { + maybeErrors: Option[List[MiddlewarehouseErrorInfo]]): Option[Failures] = maybeErrors match { case Some(errors) ⇒ logger.info("Middlewarehouse errors:") @@ -46,7 +46,6 @@ class Middlewarehouse(url: String) extends MiddlewarehouseApi with LazyLogging { logger.warn("No errors in failed Middlewarehouse response!") Some(UnableToHoldLineItems.single) } - } //NOTE: This is public only for test purposes def parseMwhErrors(message: String): Failures = { @@ -86,10 +85,10 @@ class Middlewarehouse(url: String) extends MiddlewarehouseApi with LazyLogging { //Note cart ref becomes order ref num after cart turns into order override def cancelHold(orderRefNum: String)(implicit ec: EC, au: AU): Result[Unit] = { - val reqUrl = dispatch.url(s"$url/v1/private/reservations/hold/${orderRefNum}") + val reqUrl = dispatch.url(s"$url/v1/private/reservations/hold/$orderRefNum") val jwt = AuthPayload.jwt(au.token) val req = reqUrl.setContentType("application/json", "UTF-8") <:< Map("JWT" → jwt) - logger.info(s"middlewarehouse cancel hold: ${orderRefNum}") + logger.info(s"middlewarehouse cancel hold: $orderRefNum") val f = Http(req.DELETE OK as.String).either.map { case Right(_) ⇒ Either.right(()) case Left(error) ⇒ Either.left(UnableToCancelHoldLineItems.single) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/apis/StripeMappings.scala b/phoenix-scala/phoenix/app/phoenix/utils/apis/StripeMappings.scala index bf6d838233..3175af1449 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/apis/StripeMappings.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/apis/StripeMappings.scala @@ -6,17 +6,17 @@ import phoenix.failures.CreditCardFailures._ private[utils] object StripeMappings { val cardExceptionMap: Map[String, Failure] = Map( - "invalid_number" → InvalidNumber, - "invalid_expiry_month" → MonthExpirationInvalid, - "invalid_expiry_year" → YearExpirationInvalid, - "invalid_cvc" → InvalidCvc, - "incorrect_number" → IncorrectNumber, - "expired_card" → ExpiredCard, - "incorrect_cvc" → IncorrectCvc, - "incorrect_zip" → IncorrectZip, - "card_declined" → CardDeclined, - "missing" → Missing, - "processing_error" → ProcessingError + "invalid_number" → InvalidNumber, + "invalid_expiry_month" → MonthExpirationInvalid, + "invalid_expiry_year" → YearExpirationInvalid, + "invalid_cvc" → InvalidCvc, + "incorrect_number" → IncorrectNumber, + "expired_card" → ExpiredCard, + "incorrect_cvc" → IncorrectCvc, + "incorrect_zip" → IncorrectZip, + "card_declined" → CardDeclined, + "missing" → Missing, + "processing_error" → ProcessingError ) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/apis/StripeWrapper.scala b/phoenix-scala/phoenix/app/phoenix/utils/apis/StripeWrapper.scala index eec49cbccd..9a51b1faaa 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/apis/StripeWrapper.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/apis/StripeWrapper.scala @@ -33,14 +33,12 @@ class StripeWrapper extends StripeApiWrapper with LazyLogging { } def findCardByCustomerId(gatewayCustomerId: String, gatewayCardId: String): Result[StripeCard] = { - logger.info( - s"Find card for customer, customer id: $gatewayCustomerId, card id: $gatewayCardId") + logger.info(s"Find card for customer, customer id: $gatewayCustomerId, card id: $gatewayCardId") inBlockingPool(StripeCustomer.retrieve(gatewayCustomerId).getSources.retrieve(gatewayCardId)) .flatMapEither(accountToCard) } - def findCardForCustomer(stripeCustomer: StripeCustomer, - gatewayCardId: String): Result[StripeCard] = { + def findCardForCustomer(stripeCustomer: StripeCustomer, gatewayCardId: String): Result[StripeCard] = { logger.info(s"Find card for customer, customer: $stripeCustomer, card id: $gatewayCardId") inBlockingPool(stripeCustomer.getSources.retrieve(gatewayCardId)).flatMapEither(accountToCard) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/config.scala b/phoenix-scala/phoenix/app/phoenix/utils/config.scala index 358e990464..6bf75565ed 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/config.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/config.scala @@ -52,16 +52,16 @@ object FoxConfig extends StrictLogging { implicit def configConvertADT[T: ADT: ClassTag]: ConfigConvert[T] = ConfigConvert.nonEmptyStringConvert( - s ⇒ - ADT[T].read(s).map(Success(_)).getOrElse { - val err = - s"Could not interpret '$s' as a member of ${classTag[T].runtimeClass.getSimpleName}." - Failure(new IllegalArgumentException(err)) - }, - ADT[T].show) + s ⇒ + ADT[T].read(s).map(Success(_)).getOrElse { + val err = + s"Could not interpret '$s' as a member of ${classTag[T].runtimeClass.getSimpleName}." + Failure(new IllegalArgumentException(err)) + }, + ADT[T].show + ) - case class App(defaultContextId: Int, - overrideHashPasswordAlgorithm: Option[HashPasswords.HashAlgorithm]) + case class App(defaultContextId: Int, overrideHashPasswordAlgorithm: Option[HashPasswords.HashAlgorithm]) // auth case class Auth(cookie: Cookie, @@ -91,11 +91,7 @@ object FoxConfig extends StrictLogging { case class Cookie(domain: Option[String], ttl: Option[Long], secure: Boolean = true) // apis - case class Apis(aws: AWS, - elasticsearch: ESConfig, - middlewarehouse: MWH, - stripe: Stripe, - kafka: Kafka) + case class Apis(aws: AWS, elasticsearch: ESConfig, middlewarehouse: MWH, stripe: Stripe, kafka: Kafka) case class AWS(accessKey: String, secretKey: String, s3Bucket: String, s3Region: String) case class ESConfig(host: String, cluster: String, index: String) case class MWH(url: String) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/db/Flyway.scala b/phoenix-scala/phoenix/app/phoenix/utils/db/Flyway.scala index 23477d2890..4da5c4c87f 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/db/Flyway.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/db/Flyway.scala @@ -28,7 +28,7 @@ object flyway { def debug(message: String) = {} def info(message: String) = {} def warn(message: String) = {} - def error(message: String) = { Console.err.println(message) } + def error(message: String) = Console.err.println(message) def error(message: String, e: Exception) = { Console.err.println(message) Console.err.println(e.getMessage) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/http/CustomDirectives.scala b/phoenix-scala/phoenix/app/phoenix/utils/http/CustomDirectives.scala index 92d8b92ba1..48b4a7e9b5 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/http/CustomDirectives.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/http/CustomDirectives.scala @@ -29,14 +29,13 @@ object CustomDirectives { val DefaultContextName = SimpleContext.default object ProductRef extends PathMatcher1[ProductReference] { - def apply(path: Path) = { + def apply(path: Path) = path match { case Path.Segment(segment, tail) if segment.exists(_.isLetter) ⇒ Matched(tail, Tuple1(ProductReference(segment))) - case _ ⇒ + case _ ⇒ IntNumber.apply(path).map { case Tuple1(id) ⇒ Tuple1(ProductReference(id)) } } - } } def activityContext(au: AU): Directive1[ActivityContext] = { @@ -45,10 +44,7 @@ object CustomDirectives { optionalHeaderValueByName("x-request-id").map { case (Some(uuid)) ⇒ - ActivityContext(userId = user.accountId, - userType = "user", - transactionId = uuid, - scope = scope) + ActivityContext(userId = user.accountId, userType = "user", transactionId = uuid, scope = scope) case (None) ⇒ ActivityContext(userId = user.accountId, userType = "user", @@ -57,32 +53,26 @@ object CustomDirectives { } } - def activityContext(scope: LTree): Directive1[ActivityContext] = { + def activityContext(scope: LTree): Directive1[ActivityContext] = optionalHeaderValueByName("x-request-id").map { case (Some(uuid)) ⇒ ActivityContext(userId = 0, userType = "guest", transactionId = uuid, scope = scope) case (None) ⇒ - ActivityContext(userId = 0, - userType = "guest", - transactionId = generateUuid, - scope = scope) + ActivityContext(userId = 0, userType = "guest", transactionId = generateUuid, scope = scope) } - } /** * At the moment we support one context. The input to this function will * and it will become a combination of of things which will then search * for the correct context. */ - def determineObjectContext(implicit db: DB, ec: EC): Directive1[ObjectContext] = { + def determineObjectContext(implicit db: DB, ec: EC): Directive1[ObjectContext] = optionalHeaderValueByName("Accept-Language").flatMap { case Some(lang) ⇒ onSuccess(getContextByLanguage(lang)) case None ⇒ onSuccess(getContextByName(DefaultContextName)) } - } - def adminObjectContext(contextName: String)(route: ObjectContext ⇒ Route)(implicit db: DB, - ec: EC): Route = { + def adminObjectContext(contextName: String)(route: ObjectContext ⇒ Route)(implicit db: DB, ec: EC): Route = { import scala.util.{Failure, Success} onComplete(tryGetContextByName(contextName)) { case Success(Right(ctx)) ⇒ @@ -121,8 +111,7 @@ object CustomDirectives { complete(renderRaw(a)) def goodOrFailures[A <: AnyRef](a: Result[A])(implicit ec: EC): StandardRoute = - complete( - a.runEmpty.value.map(_.fold(renderFailure(_), { case (uiInfo, a) ⇒ render(a, uiInfo) }))) + complete(a.runEmpty.value.map(_.fold(renderFailure(_), { case (uiInfo, a) ⇒ render(a, uiInfo) }))) def getOrFailures[A <: AnyRef](a: DbResultT[A])(implicit ec: EC, db: DB): StandardRoute = goodOrFailures(a.runDBIO()) @@ -131,16 +120,17 @@ object CustomDirectives { goodOrFailures(a.runTxn()) def mutateWithNewTokenOrFailures[A <: AnyRef](a: DbResultT[(A, AuthPayload)])(implicit ec: EC, - db: DB): Route = { + db: DB): Route = onSuccess(a.runTxn().runEmpty.value) { result ⇒ - result.fold(f ⇒ complete(renderFailure(f)), { resp ⇒ - val (uiInfo, (body, auth)) = resp - respondWithHeader(RawHeader("JWT", auth.jwt)).&(setCookie(JwtCookie(auth))) { - complete(render(body, uiInfo)) + result.fold( + f ⇒ complete(renderFailure(f)), { resp ⇒ + val (uiInfo, (body, auth)) = resp + respondWithHeader(RawHeader("JWT", auth.jwt)).&(setCookie(JwtCookie(auth))) { + complete(render(body, uiInfo)) + } } - }) + ) } - } def deleteOrFailures(a: DbResultT[_])(implicit ec: EC, db: DB): StandardRoute = doOrFailures(a) @@ -162,9 +152,7 @@ object CustomDirectives { case Failure(Unmarshaller.UnsupportedContentTypeException(x)) ⇒ reject(UnsupportedRequestContentTypeRejection(x)) case Failure(x: Throwable) ⇒ - ctx.log.error("Error unmarshalling request {} body: {}", - ctx.request, - failure.description) + ctx.log.error("Error unmarshalling request {} body: {}", ctx.request, failure.description) reject(MalformedRequestContentRejection(s"${failure.description}", x)) } } & cancelRejections(RequestEntityExpectedRejection.getClass, diff --git a/phoenix-scala/phoenix/app/phoenix/utils/http/CustomHandlers.scala b/phoenix-scala/phoenix/app/phoenix/utils/http/CustomHandlers.scala index e85165ded2..3fc0d4d0ec 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/http/CustomHandlers.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/http/CustomHandlers.scala @@ -40,12 +40,11 @@ object CustomHandlers { } } }(defaultRejectionHandler(immutable.Seq(rejection)).getOrError( - "defaultRejectionHandler(immutable.Seq(rejection)) should be defined")) + "defaultRejectionHandler(immutable.Seq(rejection)) should be defined")) } .handleNotFound { complete( - HttpResponse(NotFound, - entity = errorsJsonEntity("The requested resource could not be found."))) + HttpResponse(NotFound, entity = errorsJsonEntity("The requested resource could not be found."))) } .result() @@ -62,17 +61,17 @@ object CustomHandlers { ctx.complete(HttpResponse(status, entity = errorsJsonEntity(info.format(env.isProd)))) } - case e: IllegalArgumentException ⇒ + case e: IllegalArgumentException ⇒ ctx ⇒ { ctx.log.warning("Bad request: {}", ctx.request) ctx.complete(HttpResponse(BadRequest, entity = errorsJsonEntity(e.getMessage))) } - // This is not a part of our control flow, but I'll leave it here just in case of unanticipated DBIO.failed - case FoxFailureException(failures) ⇒ + // This is not a part of our control flow, but I'll leave it here just in case of unanticipated DBIO.failed + case FoxFailureException(failures) ⇒ ctx ⇒ ctx.complete(Http.renderFailure(failures)) - case NonFatal(e) ⇒ + case NonFatal(e) ⇒ ctx ⇒ { val errMsg = if (env.isProd) "There was an internal server error." else e.getMessage diff --git a/phoenix-scala/phoenix/app/phoenix/utils/http/Http.scala b/phoenix-scala/phoenix/app/phoenix/utils/http/Http.scala index 150c25d55c..b473518952 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/http/Http.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/http/Http.scala @@ -3,13 +3,13 @@ package phoenix.utils.http import akka.NotUsed import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.model._ -import akka.http.scaladsl.model.headers.{ContentDispositionTypes, `Content-Disposition`} +import akka.http.scaladsl.model.headers.{`Content-Disposition`, ContentDispositionTypes} import akka.stream.scaladsl.Source import core.db.MetaResponse import core.failures.{Failures, NotFoundFailure404} import org.json4s.jackson.Serialization import org.json4s.jackson.Serialization.{write ⇒ json} -import org.json4s.{Formats, jackson} +import org.json4s.{jackson, Formats} import phoenix.responses.{BatchMetadata, TheResponse} import phoenix.utils.Chunkable @@ -44,18 +44,21 @@ object Http { // FIXME: get rid of `TheResponse` and s/AnyRef/Any/ around here. @michalrus case TheResponse(res, alerts, errors, warnings, batch) ⇒ SuccessfulResponse( - result = res, - warnings = emptyToNoneNonemptyToSome( - uiInfoWarnings ::: alerts.toList.flatten ::: warnings.toList.flatten), - errors = emptyToNoneNonemptyToSome(uiInfoErrors ::: errors.toList.flatten), - // FIXME: uncomment this & pull BatchMetadata from phoenix into starfish, when getting rid of TheResponse @michalrus - batch = /* uiInfoBatches orElse */ batch) + result = res, + warnings = + emptyToNoneNonemptyToSome(uiInfoWarnings ::: alerts.toList.flatten ::: warnings.toList.flatten), + errors = emptyToNoneNonemptyToSome(uiInfoErrors ::: errors.toList.flatten), + // FIXME: uncomment this & pull BatchMetadata from phoenix into starfish, when getting rid of TheResponse @michalrus + batch = /* uiInfoBatches orElse */ batch + ) case raw ⇒ - SuccessfulResponse(result = raw, - warnings = emptyToNoneNonemptyToSome(uiInfoWarnings), - errors = emptyToNoneNonemptyToSome(uiInfoErrors), - // FIXME: uncomment this & pull BatchMetadata from phoenix into starfish, when getting rid of TheResponse @michalrus - batch = None /* uiInfoBatches */ ) + SuccessfulResponse( + result = raw, + warnings = emptyToNoneNonemptyToSome(uiInfoWarnings), + errors = emptyToNoneNonemptyToSome(uiInfoErrors), + // FIXME: uncomment this & pull BatchMetadata from phoenix into starfish, when getting rid of TheResponse @michalrus + batch = None /* uiInfoBatches */ + ) } } } @@ -78,24 +81,19 @@ object Http { def renderPlain(text: String): HttpResponse = HttpResponse(StatusCodes.OK, entity = HttpEntity(ContentTypes.`text/plain(UTF-8)`, text)) - def renderChunked[T: Chunkable](headers: List[HttpHeader])( - source: Source[T, NotUsed]): HttpResponse = { + def renderChunked[T: Chunkable](headers: List[HttpHeader])(source: Source[T, NotUsed]): HttpResponse = HttpResponse(StatusCodes.OK, headers = headers, - entity = - HttpEntity.Chunked.fromData(Chunkable().contentType, Chunkable().bytes(source))) - } + entity = HttpEntity.Chunked.fromData(Chunkable().contentType, Chunkable().bytes(source))) def renderAttachment[T: Chunkable](fileName: String)(source: Source[T, NotUsed]): HttpResponse = renderChunked( - List(`Content-Disposition`(ContentDispositionTypes.attachment, - Map("filename" → fileName))))(source) + List(`Content-Disposition`(ContentDispositionTypes.attachment, Map("filename" → fileName))))(source) def renderFailure(failures: Failures, statusCode: ClientError = BadRequest): HttpResponse = { val failuresList = failures.toList val notFound = failuresList.collectFirst { case f: NotFoundFailure404 ⇒ f } - notFound.fold(HttpResponse(statusCode, - entity = jsonEntity("errors" → failuresList.map(_.description)))) { + notFound.fold(HttpResponse(statusCode, entity = jsonEntity("errors" → failuresList.map(_.description)))) { nf ⇒ renderNotFoundFailure(nf) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/http/HttpLogger.scala b/phoenix-scala/phoenix/app/phoenix/utils/http/HttpLogger.scala index 45657a7960..53a603bcec 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/http/HttpLogger.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/http/HttpLogger.scala @@ -9,7 +9,7 @@ import akka.stream.scaladsl.Sink import cats.implicits._ import org.json4s.JsonAST.{JField, JString} import org.json4s._ -import org.json4s.jackson.{Serialization, parseJson} +import org.json4s.jackson.{parseJson, Serialization} import phoenix.utils.JsonFormatters import phoenix.utils.aliases._ @@ -42,22 +42,22 @@ object HttpLogger { DebuggingDirectives.logRequestResult(LoggingMagnet(_ ⇒ loggingFn(logger)))(route) } - private def logError(request: HttpRequest, response: HttpResponse)( - implicit mat: Mat, - ec: EC): Future[Option[LogEntry]] = { + private def logError(request: HttpRequest, response: HttpResponse)(implicit mat: Mat, + ec: EC): Future[Option[LogEntry]] = for { requestEntity ← entityToString(request.entity) responseEntity ← entityToString(response.entity) } yield { val requestJson = maskSensitiveData(parseJson(requestEntity)) val responseJson = parseJson(responseEntity) - LogEntry(s"""|${request.method.name} ${request.uri}: ${response.status} + LogEntry( + s"""|${request.method.name} ${request.uri}: ${response.status} |Request entity: ${Serialization.write(requestJson)} |Response entity: ${Serialization.write(responseJson)}""".stripMargin, - marker, - errorLevel).some + marker, + errorLevel + ).some } - } private def maskSensitiveData(json: Json): Json = json.transformField { diff --git a/phoenix-scala/phoenix/app/phoenix/utils/http/JsonSupport.scala b/phoenix-scala/phoenix/app/phoenix/utils/http/JsonSupport.scala index 30edf801ed..69e4e7914d 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/http/JsonSupport.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/http/JsonSupport.scala @@ -19,7 +19,6 @@ object JsonSupport extends Json4sSupport { implicit def json4sValidationUnmarshaller[A <: Validation[_]: Manifest]( implicit serialization: Serialization, - formats: Formats): FromEntityUnmarshaller[A] = { + formats: Formats): FromEntityUnmarshaller[A] = json4sUnmarshaller[A].flatMap(implicit ec ⇒ mat ⇒ validateData) - } } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/io/ByteBufferInputStream.scala b/phoenix-scala/phoenix/app/phoenix/utils/io/ByteBufferInputStream.scala index a84c2b18e5..d686ae5ad0 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/io/ByteBufferInputStream.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/io/ByteBufferInputStream.scala @@ -10,14 +10,13 @@ class ByteBufferInputStream(buf: ByteBuffer) extends InputStream { buf.get & 0xFF } - override def read(bytes: Array[Byte], off: Int, len: Int): Int = { + override def read(bytes: Array[Byte], off: Int, len: Int): Int = if (!buf.hasRemaining) -1 else { val readLen = Math.min(len, buf.remaining) buf.get(bytes, off, readLen) readLen } - } override def markSupported(): Boolean = true diff --git a/phoenix-scala/phoenix/app/phoenix/utils/json.scala b/phoenix-scala/phoenix/app/phoenix/utils/json.scala index d168e6ca46..6d83773b73 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/json.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/json.scala @@ -3,7 +3,7 @@ package phoenix.utils import com.github.tminglei.slickpg.LTree import core.utils.Money import org.json4s.JsonAST.JString -import org.json4s.{CustomSerializer, Formats, JNull, TypeHints, jackson} +import org.json4s.{jackson, CustomSerializer, Formats, JNull, TypeHints} import phoenix.models.admin.AdminData import phoenix.models.auth.Identity.IdentityKind import phoenix.models.cord.lineitems._ @@ -93,7 +93,7 @@ object JsonFormatters { object LTreeFormat extends CustomSerializer[LTree](format ⇒ - ({ + ({ case JString(s) ⇒ LTree(s) case JNull ⇒ LTree("") }, { case value: LTree ⇒ JString(value.toString) })) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/AddressSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/AddressSeeds.scala index a382c767f1..5a19b5dee1 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/AddressSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/AddressSeeds.scala @@ -11,27 +11,29 @@ trait AddressSeeds { def createAddresses(customers: CustomerSeeds#CustomerIds): DbResultT[Unit] = for { _ ← * <~ Addresses.createAll( - Seq( - usAddress1.copy(accountId = customers._1), - usAddress2.copy(accountId = customers._1), - usAddress3.copy(accountId = customers._2), - usAddress4.copy(accountId = customers._2), - canadaAddress1.copy(accountId = customers._3), - canadaAddress2.copy(accountId = customers._3), - rowAddress1.copy(accountId = customers._4) - )) + Seq( + usAddress1.copy(accountId = customers._1), + usAddress2.copy(accountId = customers._1), + usAddress3.copy(accountId = customers._2), + usAddress4.copy(accountId = customers._2), + canadaAddress1.copy(accountId = customers._3), + canadaAddress2.copy(accountId = customers._3), + rowAddress1.copy(accountId = customers._4) + )) } yield {} def usAddress1 = - Address(accountId = 0, - regionId = 4177, - name = "Curt Cobain", - address1 = "555 E Lake Union St.", - address2 = None, - city = "Seattle", - zip = "12345", - isDefaultShipping = true, - phoneNumber = None) + Address( + accountId = 0, + regionId = 4177, + name = "Curt Cobain", + address1 = "555 E Lake Union St.", + address2 = None, + city = "Seattle", + zip = "12345", + isDefaultShipping = true, + phoneNumber = None + ) def address = usAddress1 @@ -46,55 +48,65 @@ trait AddressSeeds { phoneNumber = None) def usAddress3 = - Address(accountId = 0, - regionId = 4154, - name = "Mark Sandman", - address1 = "3104 Canterbury Court", - address2 = "Morphine".some, - city = "Cornelius", - zip = "28031", - phoneNumber = "2025550113".some) + Address( + accountId = 0, + regionId = 4154, + name = "Mark Sandman", + address1 = "3104 Canterbury Court", + address2 = "Morphine".some, + city = "Cornelius", + zip = "28031", + phoneNumber = "2025550113".some + ) def usAddress4 = - Address(accountId = 0, - regionId = 4162, - name = "Jim Morrison", - address1 = "3345 Orchard Lane", - address2 = None, - city = "Avon Lake", - zip = "44012", - phoneNumber = None, - isDefaultShipping = true) + Address( + accountId = 0, + regionId = 4162, + name = "Jim Morrison", + address1 = "3345 Orchard Lane", + address2 = None, + city = "Avon Lake", + zip = "44012", + phoneNumber = None, + isDefaultShipping = true + ) def canadaAddress1 = - Address(accountId = 0, - regionId = 545, - name = "Ozzy Osbourne", - address1 = "4177 Crystal Downs", - address2 = None, - city = "Goodnews Bay", - zip = "B9P-4U0", - phoneNumber = "9024655753".some, - isDefaultShipping = true) + Address( + accountId = 0, + regionId = 545, + name = "Ozzy Osbourne", + address1 = "4177 Crystal Downs", + address2 = None, + city = "Goodnews Bay", + zip = "B9P-4U0", + phoneNumber = "9024655753".some, + isDefaultShipping = true + ) def canadaAddress2 = - Address(accountId = 0, - regionId = 547, - name = "Stevie Wonder", - address1 = "8321 Harvest Woods", - address2 = None, - city = "Ptarmigan", - zip = "X9M-9W6", - phoneNumber = "8671002677".some) + Address( + accountId = 0, + regionId = 547, + name = "Stevie Wonder", + address1 = "8321 Harvest Woods", + address2 = None, + city = "Ptarmigan", + zip = "X9M-9W6", + phoneNumber = "8671002677".some + ) def rowAddress1 = - Address(accountId = 0, - regionId = 789, - name = "Amy Winehouse", - address1 = "Příční 151", - address2 = None, - city = "Bystricka", - zip = "756 24", - phoneNumber = "578660629".some, - isDefaultShipping = true) + Address( + accountId = 0, + regionId = 789, + name = "Amy Winehouse", + address1 = "Příční 151", + address2 = None, + city = "Bystricka", + zip = "756 24", + phoneNumber = "578660629".some, + isDefaultShipping = true + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/AmazonOrdersSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/AmazonOrdersSeeds.scala index 108a6c7f3c..9896c12f72 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/AmazonOrdersSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/AmazonOrdersSeeds.scala @@ -11,16 +11,18 @@ import core.utils.Money.Currency trait AmazonOrdersSeeds { def amazonOrder = - AmazonOrder(id = 0, - amazonOrderId = "112233", - orderTotal = 4500, - paymentMethodDetail = "CreditCard", - orderType = "StandardOrder", - currency = Currency.USD, - orderStatus = "Shipped", - purchaseDate = Instant.now, - scope = LTree("1"), - accountId = 0, - createdAt = Instant.now, - updatedAt = Instant.now) + AmazonOrder( + id = 0, + amazonOrderId = "112233", + orderTotal = 4500, + paymentMethodDetail = "CreditCard", + orderType = "StandardOrder", + currency = Currency.USD, + orderStatus = "Shipped", + purchaseDate = Instant.now, + scope = LTree("1"), + accountId = 0, + createdAt = Instant.now, + updatedAt = Instant.now + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/CouponSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/CouponSeeds.scala index b8453ec3a1..fb72bbafac 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/CouponSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/CouponSeeds.scala @@ -32,10 +32,9 @@ trait CouponSeeds { import CouponSeeds._ - def createCoupons(promotions: Seq[BasePromotion])( - implicit db: DB, - ac: AC, - au: AU): DbResultT[Seq[(BaseCoupon, Seq[CouponCode])]] = + def createCoupons(promotions: Seq[BasePromotion])(implicit db: DB, + ac: AC, + au: AU): DbResultT[Seq[(BaseCoupon, Seq[CouponCode])]] = for { context ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) results ← * <~ promotions.map { promotion ⇒ @@ -55,12 +54,12 @@ trait CouponSeeds { shadow ← * <~ ObjectShadow(attributes = payload.shadow.attributes) ins ← * <~ ObjectUtils.insert(form, shadow, None) coupon ← * <~ Coupons.create( - Coupon(scope = scope, - contextId = context.id, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id, - promotionId = payload.promotion)) + Coupon(scope = scope, + contextId = context.id, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id, + promotionId = payload.promotion)) // Generate codes for it codes ← * <~ CouponCodes.generateCodes(codePrefix, codeLength, codesQty) unsaved = codes.map { c ⇒ diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/CreditCardSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/CreditCardSeeds.scala index 3c698e12d9..ddbaf5167f 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/CreditCardSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/CreditCardSeeds.scala @@ -13,102 +13,109 @@ trait CreditCardSeeds extends CreditCardGenerator { def createCreditCards(customers: CustomerSeeds#CustomerIds): DbResultT[Unit] = for { _ ← * <~ CreditCards.createAll( - Seq(creditCard1.copy(accountId = customers._1), - creditCard2.copy(accountId = customers._1), - creditCard3.copy(accountId = customers._2), - creditCard4.copy(accountId = customers._3), - creditCard5.copy(accountId = customers._4))) + Seq( + creditCard1.copy(accountId = customers._1), + creditCard2.copy(accountId = customers._1), + creditCard3.copy(accountId = customers._2), + creditCard4.copy(accountId = customers._3), + creditCard5.copy(accountId = customers._4) + )) } yield {} - def creditCard1 = { - CreditCard(accountId = 0, - gatewayCustomerId = gatewayCustomerId, - gatewayCardId = "", - holderName = "Yax", - lastFour = "4242", - expMonth = today.getMonthValue, - expYear = today.getYear + 2, - isDefault = true, - address = BillingAddress(regionId = 4129, - name = "Old Jeff", - address1 = "95 W. 5th Ave.", - address2 = Some("Apt. 437"), - city = "San Mateo", - zip = "94402"), - brand = "Visa") - } + def creditCard1 = + CreditCard( + accountId = 0, + gatewayCustomerId = gatewayCustomerId, + gatewayCardId = "", + holderName = "Yax", + lastFour = "4242", + expMonth = today.getMonthValue, + expYear = today.getYear + 2, + isDefault = true, + address = BillingAddress(regionId = 4129, + name = "Old Jeff", + address1 = "95 W. 5th Ave.", + address2 = Some("Apt. 437"), + city = "San Mateo", + zip = "94402"), + brand = "Visa" + ) def creditCard = creditCard1 - def creditCard2 = { - CreditCard(accountId = 0, - gatewayCustomerId = gatewayCustomerId, - gatewayCardId = "", - holderName = "Yax", - lastFour = "8752", - expMonth = 4, - expYear = today.getYear + 4, - isDefault = false, - address = BillingAddress(regionId = 4141, - name = "West Ave", - address1 = "3590 West Avenue", - address2 = None, - city = "Indianapolis", - zip = "46201"), - brand = "Visa") - } + def creditCard2 = + CreditCard( + accountId = 0, + gatewayCustomerId = gatewayCustomerId, + gatewayCardId = "", + holderName = "Yax", + lastFour = "8752", + expMonth = 4, + expYear = today.getYear + 4, + isDefault = false, + address = BillingAddress(regionId = 4141, + name = "West Ave", + address1 = "3590 West Avenue", + address2 = None, + city = "Indianapolis", + zip = "46201"), + brand = "Visa" + ) - def creditCard3 = { - CreditCard(accountId = 0, - gatewayCustomerId = gatewayCustomerId, - gatewayCardId = "", - holderName = "Adil", - lastFour = "3436", - expMonth = 7, - expYear = today.getYear + 3, - isDefault = true, - address = BillingAddress(regionId = 4164, - name = "Haymond Rocks", - address1 = "3564 Haymond Rocks Road", - address2 = None, - city = "Grants Pass", - zip = "97526"), - brand = "Visa") - } + def creditCard3 = + CreditCard( + accountId = 0, + gatewayCustomerId = gatewayCustomerId, + gatewayCardId = "", + holderName = "Adil", + lastFour = "3436", + expMonth = 7, + expYear = today.getYear + 3, + isDefault = true, + address = BillingAddress(regionId = 4164, + name = "Haymond Rocks", + address1 = "3564 Haymond Rocks Road", + address2 = None, + city = "Grants Pass", + zip = "97526"), + brand = "Visa" + ) - def creditCard4 = { - CreditCard(accountId = 0, - gatewayCustomerId = gatewayCustomerId, - gatewayCardId = "", - holderName = "John", - lastFour = "3436", - expMonth = 3, - expYear = today.getYear + 3, - isDefault = true, - address = BillingAddress(regionId = 551, - name = "Bright Quay", - address1 = "1851 Bright Quay", - address2 = None, - city = "Tonganoxie", - zip = "S0R-9U4"), - brand = "Visa") - } + def creditCard4 = + CreditCard( + accountId = 0, + gatewayCustomerId = gatewayCustomerId, + gatewayCardId = "", + holderName = "John", + lastFour = "3436", + expMonth = 3, + expYear = today.getYear + 3, + isDefault = true, + address = BillingAddress(regionId = 551, + name = "Bright Quay", + address1 = "1851 Bright Quay", + address2 = None, + city = "Tonganoxie", + zip = "S0R-9U4"), + brand = "Visa" + ) - def creditCard5 = { - CreditCard(accountId = 0, - gatewayCustomerId = gatewayCustomerId, - gatewayCardId = "", - holderName = "František", - lastFour = "1258", - expMonth = 11, - expYear = today.getYear + 1, - isDefault = true, - brand = "Visa", - address = BillingAddress(regionId = 787, - name = "Výchozí", - address1 = "Rvačov 829", - address2 = None, - city = "Rvačov 829", - zip = "413 01")) - } + def creditCard5 = + CreditCard( + accountId = 0, + gatewayCustomerId = gatewayCustomerId, + gatewayCardId = "", + holderName = "František", + lastFour = "1258", + expMonth = 11, + expYear = today.getYear + 1, + isDefault = true, + brand = "Visa", + address = BillingAddress(regionId = 787, + name = "Výchozí", + address1 = "Rvačov 829", + address2 = None, + city = "Rvačov 829", + zip = "413 01") + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/CustomerSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/CustomerSeeds.scala index 946ef86f14..127faee460 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/CustomerSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/CustomerSeeds.scala @@ -37,15 +37,14 @@ trait CustomerSeeds { def createCustomers(scopeId: Int)(implicit db: DB, ac: AC): DbResultT[CustomerIds] = for { users ← * <~ customers.map( - c ⇒ - createCustomer(user = c, - isGuest = c.accountId == 100, - scopeId = scopeId, - password = "password".some)) + c ⇒ + createCustomer(user = c, + isGuest = c.accountId == 100, + scopeId = scopeId, + password = "password".some)) accountIds = users.map(_.accountId) scope ← * <~ Scopes.mustFindById400(scopeId) - _ ← * <~ Notes.createAll( - customerNotes(LTree(scope.path)).map(_.copy(referenceId = accountIds.head))) + _ ← * <~ Notes.createAll(customerNotes(LTree(scope.path)).map(_.copy(referenceId = accountIds.head))) } yield accountIds.toList match { case c1 :: c2 :: c3 :: c4 :: Nil ⇒ (c1, c2, c3, c4) @@ -53,16 +52,10 @@ trait CustomerSeeds { } def usCustomer1 = - User(accountId = 0, - name = "Yax Man".some, - email = "yax@yax.com".some, - phoneNumber = Some("123-444-4388")) + User(accountId = 0, name = "Yax Man".some, email = "yax@yax.com".some, phoneNumber = Some("123-444-4388")) def usCustomer2 = - User(accountId = 0, - email = "adil@adil.com".some, - phoneNumber = "123-444-0909".some, - isDisabled = true) // FIXME: `disabledBy` is not required for `isDisabled`=true + User(accountId = 0, email = "adil@adil.com".some, phoneNumber = "123-444-0909".some, isDisabled = true) // FIXME: `disabledBy` is not required for `isDisabled`=true def canadaCustomer = User(accountId = 100, //hack to make one guest @@ -82,16 +75,12 @@ trait CustomerSeeds { def customerNotes(scope: LTree): Seq[Note] = { def newNote(body: String) = - Note(referenceId = 1, - referenceType = Note.Customer, - storeAdminId = 1, - body = body, - scope = scope) + Note(referenceId = 1, referenceType = Note.Customer, storeAdminId = 1, body = body, scope = scope) Seq( - newNote("This customer is a donkey."), - newNote("No, seriously."), - newNote("Like, an actual donkey."), - newNote("How did a donkey even place an order on our website?") + newNote("This customer is a donkey."), + newNote("No, seriously."), + newNote("Like, an actual donkey."), + newNote("How did a donkey even place an order on our website?") ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/DiscountSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/DiscountSeeds.scala index 5b3d67f486..f3a5c3c5a6 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/DiscountSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/DiscountSeeds.scala @@ -35,8 +35,7 @@ trait DiscountSeeds { implicit val formats: Formats = JsonFormatters.phoenixFormats - def createDiscounts(search: SharedSearch)(implicit db: DB, - au: AU): DbResultT[Seq[BaseDiscount]] = + def createDiscounts(search: SharedSearch)(implicit db: DB, au: AU): DbResultT[Seq[BaseDiscount]] = for { context ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) results ← * <~ discounts(search).map { @@ -54,43 +53,43 @@ trait DiscountSeeds { shadow ← * <~ ObjectShadow(attributes = payload.shadow.attributes) ins ← * <~ ObjectUtils.insert(form, shadow, schema = None) discount ← * <~ Discounts.create( - Discount(scope = scope, - contextId = context.id, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) + Discount(scope = scope, + contextId = context.id, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) } yield - BaseDiscount(title = title, - discountId = discount.id, - formId = ins.form.id, - shadowId = ins.shadow.id) + BaseDiscount(title = title, discountId = discount.id, formId = ins.form.id, shadowId = ins.shadow.id) def productSearch(search: SharedSearch): Seq[ProductSearch] = Seq(ProductSearch(productSearchId = search.id)) def qualifiers(search: SharedSearch): Seq[Qualifier] = Seq( - OrderAnyQualifier, - OrderTotalAmountQualifier(1000), - OrderNumUnitsQualifier(2), - ItemsAnyQualifier(productSearch(search)), - ItemsTotalAmountQualifier(1500, productSearch(search)), - ItemsNumUnitsQualifier(2, productSearch(search)) + OrderAnyQualifier, + OrderTotalAmountQualifier(1000), + OrderNumUnitsQualifier(2), + ItemsAnyQualifier(productSearch(search)), + ItemsTotalAmountQualifier(1500, productSearch(search)), + ItemsNumUnitsQualifier(2, productSearch(search)) ) def offers(search: SharedSearch): Seq[Offer] = Seq( - OrderAmountOffer(3000), - OrderPercentOffer(30), - ItemAmountOffer(1000, productSearch(search)), - ItemPercentOffer(50, productSearch(search)), - ItemsAmountOffer(3000, productSearch(search)), - ItemsPercentOffer(30, productSearch(search)), - FreeShippingOffer, - DiscountedShippingOffer(500), - SetPriceOffer(2500, 2, productSearch(search)) + OrderAmountOffer(3000), + OrderPercentOffer(30), + ItemAmountOffer(1000, productSearch(search)), + ItemPercentOffer(50, productSearch(search)), + ItemsAmountOffer(3000, productSearch(search)), + ItemsPercentOffer(30, productSearch(search)), + FreeShippingOffer, + DiscountedShippingOffer(500), + SetPriceOffer(2500, 2, productSearch(search)) ) def discounts(search: SharedSearch): Seq[(String, CreateDiscount)] = - for (q ← qualifiers(search); o ← offers(search)) yield createDiscount(q, o) + for { + q ← qualifiers(search) + o ← offers(search) + } yield createDiscount(q, o) def createDiscount(qualifier: Qualifier, offer: Offer): (String, CreateDiscount) = { val discountTitle = DiscountTitles.getDiscountTitle(qualifier, offer) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/Factories.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/Factories.scala index 63003e2598..0dbc2524a7 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/Factories.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/Factories.scala @@ -56,37 +56,31 @@ object Factories def reasons: Seq[Reason] = Seq( - // Gift card creation reasons - Reason(body = "Gift to loyal customer", - reasonType = GiftCardCreation, - parentId = None, - storeAdminId = 0), - Reason(body = "New year GC giveaway", - reasonType = GiftCardCreation, - parentId = None, - storeAdminId = 0), - // Store credit creation reasons - Reason(body = "Gift to loyal customer", - reasonType = StoreCreditCreation, - parentId = None, - storeAdminId = 0), - Reason(body = "New year SC giveaway", - reasonType = StoreCreditCreation, - parentId = None, - storeAdminId = 0), - // Cancellation reasons - Reason(body = "Cancelled by customer request", - reasonType = Cancellation, - parentId = None, - storeAdminId = 0), - Reason(body = "Cancelled because duplication", - reasonType = Cancellation, - parentId = None, - storeAdminId = 0), - Reason(body = "Other cancellation reason", - reasonType = Cancellation, - parentId = None, - storeAdminId = 0) + // Gift card creation reasons + Reason(body = "Gift to loyal customer", + reasonType = GiftCardCreation, + parentId = None, + storeAdminId = 0), + Reason(body = "New year GC giveaway", reasonType = GiftCardCreation, parentId = None, storeAdminId = 0), + // Store credit creation reasons + Reason(body = "Gift to loyal customer", + reasonType = StoreCreditCreation, + parentId = None, + storeAdminId = 0), + Reason(body = "New year SC giveaway", + reasonType = StoreCreditCreation, + parentId = None, + storeAdminId = 0), + // Cancellation reasons + Reason(body = "Cancelled by customer request", + reasonType = Cancellation, + parentId = None, + storeAdminId = 0), + Reason(body = "Cancelled because duplication", + reasonType = Cancellation, + parentId = None, + storeAdminId = 0), + Reason(body = "Other cancellation reason", reasonType = Cancellation, parentId = None, storeAdminId = 0) ) def createSingleMerchantSystem(implicit ec: EC) = diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/GiftCardSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/GiftCardSeeds.scala index e067ea413a..ae5c7ebc28 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/GiftCardSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/GiftCardSeeds.scala @@ -29,14 +29,14 @@ trait GiftCardSeeds { origin ← * <~ GiftCardManuals.create(GiftCardManual(adminId = 1, reasonId = 1)) gc1 ← * <~ GiftCards.create(giftCard.copy(originId = origin.id)) _ ← * <~ GiftCards.create( - build(payload(balance = 10000, reasonId = 1), originId = origin.id, scope = scope)) + build(payload(balance = 10000, reasonId = 1), originId = origin.id, scope = scope)) _ ← * <~ Notes.createAll(giftCardNotes.map(_.copy(referenceId = gc1.id))) } yield {} def giftCardSubTypes: Seq[GiftCardSubtype] = Seq( - GiftCardSubtype(title = "Appeasement Subtype A", originType = GiftCard.CsrAppeasement), - GiftCardSubtype(title = "Appeasement Subtype B", originType = GiftCard.CsrAppeasement), - GiftCardSubtype(title = "Appeasement Subtype C", originType = GiftCard.CsrAppeasement) + GiftCardSubtype(title = "Appeasement Subtype A", originType = GiftCard.CsrAppeasement), + GiftCardSubtype(title = "Appeasement Subtype B", originType = GiftCard.CsrAppeasement), + GiftCardSubtype(title = "Appeasement Subtype C", originType = GiftCard.CsrAppeasement) ) def giftCardNotes(implicit au: AU): Seq[Note] = { @@ -47,10 +47,10 @@ trait GiftCardSeeds { body = body, scope = Scope.current) Seq( - newNote("This customer is a donkey."), - newNote("No, seriously."), - newNote("Like, an actual donkey."), - newNote("How did a donkey even place an order on our website?") + newNote("This customer is a donkey."), + newNote("No, seriously."), + newNote("Like, an actual donkey."), + newNote("How did a donkey even place an order on our website?") ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/GroupTemplatesSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/GroupTemplatesSeeds.scala index d9bd6b7234..a09e85be3d 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/GroupTemplatesSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/GroupTemplatesSeeds.scala @@ -14,8 +14,9 @@ trait GroupTemplatesSeeds { } yield DbResultT.unit private def abandonedCartsTemplate() = - CustomerGroupTemplate(name = "Abandoned Carts", - elasticRequest = parse("""{ + CustomerGroupTemplate( + name = "Abandoned Carts", + elasticRequest = parse("""{ | "query": { | "bool": { | "filter": [ @@ -43,7 +44,8 @@ trait GroupTemplatesSeeds { | } | } |}""".stripMargin), - clientState = fakeQuery) + clientState = fakeQuery + ) type GroupTemplates = (CustomerGroupTemplate#Id, CustomerGroupTemplate#Id) @@ -59,13 +61,9 @@ trait GroupTemplatesSeeds { } private def template_1() = - CustomerGroupTemplate(name = "Donkies Group", - elasticRequest = fakeQuery, - clientState = fakeQuery) + CustomerGroupTemplate(name = "Donkies Group", elasticRequest = fakeQuery, clientState = fakeQuery) private def template_2() = - CustomerGroupTemplate(name = "Foxes Group", - elasticRequest = fakeQuery, - clientState = fakeQuery) + CustomerGroupTemplate(name = "Foxes Group", elasticRequest = fakeQuery, clientState = fakeQuery) def templates: Seq[CustomerGroupTemplate] = Seq(template_1, template_2) def template: CustomerGroupTemplate = template_1 diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/ObjectSchemaSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/ObjectSchemaSeeds.scala index e1b0d563f0..55f91cd53a 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/ObjectSchemaSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/ObjectSchemaSeeds.scala @@ -11,16 +11,8 @@ import scala.concurrent.ExecutionContext.Implicits.global trait ObjectSchemaSeeds { - private val allButPromoSchemaNames = Seq("empty", - "album", - "image", - "price", - "sku", - "coupon", - "discount", - "product", - "taxonomy", - "taxon") + private val allButPromoSchemaNames = + Seq("empty", "album", "image", "price", "sku", "coupon", "discount", "product", "taxonomy", "taxon") private val allSchemaNames = allButPromoSchemaNames :+ "promotion" private lazy val allButPromoSchemas = allButPromoSchemaNames.map(getSchema) @@ -46,8 +38,7 @@ trait ObjectSchemaSeeds { Console.err.println(s"Found schema ${current.name}, updating...") ObjectSchemas .update(current, - current.copy(schema = newSchema.schema, - dependencies = newSchema.dependencies)) + current.copy(schema = newSchema.schema, dependencies = newSchema.dependencies)) .meh case _ ⇒ Console.err.println(s"Schema ${newSchema.name} not found, creating...") diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/OrderSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/OrderSeeds.scala index dffccffd68..bcbe5ab1ca 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/OrderSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/OrderSeeds.scala @@ -10,27 +10,19 @@ import phoenix.utils.aliases._ trait OrderSeeds { def order(scope: LTree): Order = - Order(accountId = 1, - referenceNumber = "ABCD1234-11", - scope = scope, - state = ManualHold, - contextId = 1) + Order(accountId = 1, referenceNumber = "ABCD1234-11", scope = scope, state = ManualHold, contextId = 1) def cart(scope: LTree): Cart = Cart(accountId = 1, referenceNumber = "ABCD1234-11", scope = scope) def orderNotes(implicit au: AU): Seq[Note] = { def newNote(body: String) = - Note(referenceId = 1, - referenceType = Note.Order, - storeAdminId = 1, - body = body, - scope = Scope.current) + Note(referenceId = 1, referenceType = Note.Order, storeAdminId = 1, body = body, scope = Scope.current) Seq( - newNote("This customer is a donkey."), - newNote("No, seriously."), - newNote("Like, an actual donkey."), - newNote("How did a donkey even place an order on our website?") + newNote("This customer is a donkey."), + newNote("No, seriously."), + newNote("Like, an actual donkey."), + newNote("How did a donkey even place an order on our website?") ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/ProductSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/ProductSeeds.scala index 821c5792bf..36a38bd42c 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/ProductSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/ProductSeeds.scala @@ -27,75 +27,74 @@ trait ProductSeeds extends { def products: Seq[SimpleProductData] = Seq( - SimpleProductData( - code = "SKU-YAX", - title = "Donkey", - description = "A styled fit for the donkey life.", - price = - 3300, - image = - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Granger_Three_Quarter.jpg", - active = true, - tags = - Seq("eyeglasses", "readers")), - SimpleProductData(code = "SKU-BRO", - title = - "Shark", - description = - "Sharks come with balanced framing.", - price = 15300, - image = - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Three_Quarter.jpg", - active = true, - tags = Seq("sunglasses", "readers")), - SimpleProductData(code = - "SKU-ABC", - title = "Sharkling", - description = - "Designed for the beach.", - price = 4500, - image = - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Three_Quarter.jpg", - active = true, - tags = Seq("sunglasses")), - SimpleProductData( - code = - "SKU-SHH", - title = - "Duck", - description = "The yellow trim accentuates deep pond style.", - price = 1500, - image = "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Top_Front.jpg", - active = - true, - tags = Seq("sunglasses")), - SimpleProductData( - code = "SKU-ZYA", - title = "Duckling", - description = - "A fit for a smaller face.", - price = 8800, - image = - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Top_Front.jpg", - active = true, - tags = Seq("sunglasses", "readers")), - SimpleProductData(code = "SKU-MRP", - title = "Chicken", - description = "Cross the road in these with confidence.", - price = 7700, - image = - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Top_Front.jpg", - active = true, - tags = Seq("eyeglasses")), - SimpleProductData( - code = "SKU-TRL", - title = "Fox", - description = "Stylish fit, stylish finish.", - price = 10000, - image = - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Side.jpg", - active = true, - tags = Seq("sunglasses"))) + SimpleProductData( + code = "SKU-YAX", + title = "Donkey", + description = "A styled fit for the donkey life.", + price = 3300, + image = + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Granger_Three_Quarter.jpg", + active = true, + tags = Seq("eyeglasses", "readers") + ), + SimpleProductData( + code = "SKU-BRO", + title = "Shark", + description = "Sharks come with balanced framing.", + price = 15300, + image = + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Three_Quarter.jpg", + active = true, + tags = Seq("sunglasses", "readers") + ), + SimpleProductData( + code = "SKU-ABC", + title = "Sharkling", + description = "Designed for the beach.", + price = 4500, + image = + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Three_Quarter.jpg", + active = true, + tags = Seq("sunglasses") + ), + SimpleProductData( + code = "SKU-SHH", + title = "Duck", + description = "The yellow trim accentuates deep pond style.", + price = 1500, + image = "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Top_Front.jpg", + active = true, + tags = Seq("sunglasses") + ), + SimpleProductData( + code = "SKU-ZYA", + title = "Duckling", + description = "A fit for a smaller face.", + price = 8800, + image = "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Top_Front.jpg", + active = true, + tags = Seq("sunglasses", "readers") + ), + SimpleProductData( + code = "SKU-MRP", + title = "Chicken", + description = "Cross the road in these with confidence.", + price = 7700, + image = + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Top_Front.jpg", + active = true, + tags = Seq("eyeglasses") + ), + SimpleProductData( + code = "SKU-TRL", + title = "Fox", + description = "Stylish fit, stylish finish.", + price = 10000, + image = "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Side.jpg", + active = true, + tags = Seq("sunglasses") + ) + ) def createRuProducts(products: SeedProducts)(implicit db: DB, au: AU): DbResultT[SeedProducts] = { val p1 = products._1.copy(title = "осел", diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/PromotionSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/PromotionSeeds.scala index a26cc27949..741b1cc67d 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/PromotionSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/PromotionSeeds.scala @@ -39,9 +39,8 @@ trait PromotionSeeds { import PromotionSeeds._ - def createCouponPromotions(discounts: Seq[BaseDiscount])(implicit db: DB, - ac: AC, - au: AU): DbResultT[Seq[BasePromotion]] = + def createCouponPromotions( + discounts: Seq[BaseDiscount])(implicit db: DB, ac: AC, au: AU): DbResultT[Seq[BasePromotion]] = for { context ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) results ← * <~ discounts.map { discount ⇒ @@ -50,34 +49,33 @@ trait PromotionSeeds { } } yield results - def insertPromotion(payload: CreatePromotion, discount: BaseDiscount, context: ObjectContext)( - implicit db: DB, - ac: AC, - au: AU): DbResultT[BasePromotion] = + def insertPromotion(payload: CreatePromotion, + discount: BaseDiscount, + context: ObjectContext)(implicit db: DB, ac: AC, au: AU): DbResultT[BasePromotion] = for { scope ← * <~ Scope.resolveOverride(payload.scope) form ← * <~ ObjectForm(kind = Promotion.kind, attributes = payload.form.attributes) shadow ← * <~ ObjectShadow(attributes = payload.shadow.attributes) ins ← * <~ ObjectUtils.insert(form, shadow, None) promotion ← * <~ Promotions.create( - Promotion(scope = scope, - contextId = context.id, - applyType = payload.applyType, - formId = ins.form.id, - shadowId = ins.shadow.id, - commitId = ins.commit.id)) + Promotion(scope = scope, + contextId = context.id, + applyType = payload.applyType, + formId = ins.form.id, + shadowId = ins.shadow.id, + commitId = ins.commit.id)) link ← * <~ PromotionDiscountLinks.create( - PromotionDiscountLink(leftId = promotion.id, rightId = discount.discountId)) - } yield - BasePromotion(promotion.id, ins.form.id, ins.shadow.id, payload.applyType, discount.title) + PromotionDiscountLink(leftId = promotion.id, rightId = discount.discountId)) + } yield BasePromotion(promotion.id, ins.form.id, ins.shadow.id, payload.applyType, discount.title) def createPromotion(name: String, applyType: Promotion.ApplyType): CreatePromotion = { val promotionForm = BasePromotionForm(name, applyType) val promotionShadow = BasePromotionShadow(promotionForm) CreatePromotion( - applyType = applyType, - form = CreatePromotionForm(attributes = promotionForm.form, discounts = Seq.empty), - shadow = CreatePromotionShadow(attributes = promotionShadow.shadow, discounts = Seq.empty)) + applyType = applyType, + form = CreatePromotionForm(attributes = promotionForm.form, discounts = Seq.empty), + shadow = CreatePromotionShadow(attributes = promotionShadow.shadow, discounts = Seq.empty) + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/ReturnSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/ReturnSeeds.scala index e4477151b9..676494621c 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/ReturnSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/ReturnSeeds.scala @@ -10,102 +10,82 @@ import scala.concurrent.ExecutionContext.Implicits.global trait ReturnSeeds { - def createReturns(implicit au:AU): DbResultT[Unit] = + def createReturns(implicit au: AU): DbResultT[Unit] = for { - ids ← * <~ ReturnLineItems.createAllReturningIds(returnLineItems) - _ ← * <~ ReturnLineItemSkus.createAll(returnLineItemSkus.zip(ids).map { case (sku, id) => sku.copy(id = id) }) - _ ← * <~ Notes.createAll(returnNotes) + ids ← * <~ ReturnLineItems.createAllReturningIds(returnLineItems) + _ ← * <~ ReturnLineItemSkus.createAll(returnLineItemSkus.zip(ids).map { + case (sku, id) => sku.copy(id = id) + }) + _ ← * <~ Notes.createAll(returnNotes) } yield {} def createReturnReasons(implicit ec: EC): DbResultT[Option[Int]] = ReturnReasons.createAll(returnReasons) def rma = - Return(orderId = 1, - orderRef = "", - returnType = Return.Standard, - state = Return.Pending, - accountId = 1) + Return(orderId = 1, orderRef = "", returnType = Return.Standard, state = Return.Pending, accountId = 1) def returnLineItemSkus = Seq( - ReturnLineItemSku(id = 0, returnId = 1, quantity = 1, skuId = 1, skuShadowId = 1), - ReturnLineItemSku(id = 0, returnId = 1, quantity = 2, skuId = 2, skuShadowId = 2) + ReturnLineItemSku(id = 0, returnId = 1, quantity = 1, skuId = 1, skuShadowId = 1), + ReturnLineItemSku(id = 0, returnId = 1, quantity = 2, skuId = 2, skuShadowId = 2) ) def returnLineItems = Seq( - ReturnLineItem(id = 0, - returnId = 1, - reasonId = 12, - originType = ReturnLineItem.SkuItem), - ReturnLineItem(id = 0, - returnId = 1, - reasonId = 12, - originType = ReturnLineItem.SkuItem) + ReturnLineItem(id = 0, returnId = 1, reasonId = 12, originType = ReturnLineItem.SkuItem), + ReturnLineItem(id = 0, returnId = 1, reasonId = 12, originType = ReturnLineItem.SkuItem) ) - def returnNotes(implicit au:AU): Seq[Note] = { + def returnNotes(implicit au: AU): Seq[Note] = { def newNote(body: String) = Note(referenceId = 1, referenceType = Note.Return, storeAdminId = 1, body = body, scope = Scope.current) Seq( - newNote("This customer is a donkey."), - newNote("No, seriously."), - newNote("Like, an actual donkey."), - newNote("How did a donkey even place an order on our website?") + newNote("This customer is a donkey."), + newNote("No, seriously."), + newNote("Like, an actual donkey."), + newNote("How did a donkey even place an order on our website?") ) } def returnReasons = Seq( - // Return reasons - ReturnReason(name = "Product Return", - reasonType = ReturnReason.BaseReason, - rmaType = Return.Standard), - ReturnReason(name = "Damaged Product", - reasonType = ReturnReason.BaseReason, - rmaType = Return.Standard), - ReturnReason(name = "Return to Sender", - reasonType = ReturnReason.BaseReason, - rmaType = Return.Standard), - ReturnReason(name = "Not Delivered", - reasonType = ReturnReason.BaseReason, - rmaType = Return.CreditOnly), - ReturnReason(name = "Foreign Freight Error", - reasonType = ReturnReason.BaseReason, - rmaType = Return.CreditOnly), - ReturnReason(name = "Late Delivery", - reasonType = ReturnReason.BaseReason, - rmaType = Return.CreditOnly), - ReturnReason(name = "Sales Tax Error", - reasonType = ReturnReason.BaseReason, - rmaType = Return.CreditOnly), - ReturnReason(name = "Shipping Charges Error", - reasonType = ReturnReason.BaseReason, - rmaType = Return.CreditOnly), - ReturnReason(name = "Wrong Product", - reasonType = ReturnReason.BaseReason, - rmaType = Return.CreditOnly), - ReturnReason(name = "Mis-shipment", - reasonType = ReturnReason.BaseReason, - rmaType = Return.CreditOnly), - ReturnReason(name = "Failed Capture", - reasonType = ReturnReason.BaseReason, - rmaType = Return.RestockOnly), - // Product return codes - ReturnReason(name = "Doesn't fit", - reasonType = ReturnReason.ProductReturnCode, - rmaType = Return.Standard), - ReturnReason(name = "Don't like", - reasonType = ReturnReason.ProductReturnCode, - rmaType = Return.Standard), - ReturnReason(name = "Doesn't look like picture", - reasonType = ReturnReason.ProductReturnCode, - rmaType = Return.Standard), - ReturnReason(name = "Wrong color", - reasonType = ReturnReason.ProductReturnCode, - rmaType = Return.Standard), - ReturnReason(name = "Not specified", - reasonType = ReturnReason.ProductReturnCode, - rmaType = Return.Standard) + // Return reasons + ReturnReason(name = "Product Return", reasonType = ReturnReason.BaseReason, rmaType = Return.Standard), + ReturnReason(name = "Damaged Product", reasonType = ReturnReason.BaseReason, rmaType = Return.Standard), + ReturnReason(name = "Return to Sender", + reasonType = ReturnReason.BaseReason, + rmaType = Return.Standard), + ReturnReason(name = "Not Delivered", reasonType = ReturnReason.BaseReason, rmaType = Return.CreditOnly), + ReturnReason(name = "Foreign Freight Error", + reasonType = ReturnReason.BaseReason, + rmaType = Return.CreditOnly), + ReturnReason(name = "Late Delivery", reasonType = ReturnReason.BaseReason, rmaType = Return.CreditOnly), + ReturnReason(name = "Sales Tax Error", + reasonType = ReturnReason.BaseReason, + rmaType = Return.CreditOnly), + ReturnReason(name = "Shipping Charges Error", + reasonType = ReturnReason.BaseReason, + rmaType = Return.CreditOnly), + ReturnReason(name = "Wrong Product", reasonType = ReturnReason.BaseReason, rmaType = Return.CreditOnly), + ReturnReason(name = "Mis-shipment", reasonType = ReturnReason.BaseReason, rmaType = Return.CreditOnly), + ReturnReason(name = "Failed Capture", + reasonType = ReturnReason.BaseReason, + rmaType = Return.RestockOnly), + // Product return codes + ReturnReason(name = "Doesn't fit", + reasonType = ReturnReason.ProductReturnCode, + rmaType = Return.Standard), + ReturnReason(name = "Don't like", + reasonType = ReturnReason.ProductReturnCode, + rmaType = Return.Standard), + ReturnReason(name = "Doesn't look like picture", + reasonType = ReturnReason.ProductReturnCode, + rmaType = Return.Standard), + ReturnReason(name = "Wrong color", + reasonType = ReturnReason.ProductReturnCode, + rmaType = Return.Standard), + ReturnReason(name = "Not specified", + reasonType = ReturnReason.ProductReturnCode, + rmaType = Return.Standard) ) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/SharedSearchSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/SharedSearchSeeds.scala index 04e995e8a6..2d24285b65 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/SharedSearchSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/SharedSearchSeeds.scala @@ -20,13 +20,11 @@ trait SharedSearchSeeds { storeAdmins ← * <~ AdminsData.sortBy(_.accountId).result _ ← * <~ storeAdmins.map { admin ⇒ SharedSearchAssociations.create( - new SharedSearchAssociation(sharedSearchId = productSearch.id, - storeAdminId = admin.accountId)) + new SharedSearchAssociation(sharedSearchId = productSearch.id, storeAdminId = admin.accountId)) } _ ← * <~ storeAdmins.map { admin ⇒ SharedSearchAssociations.create( - new SharedSearchAssociation(sharedSearchId = skusSearch.id, - storeAdminId = admin.accountId)) + new SharedSearchAssociation(sharedSearchId = skusSearch.id, storeAdminId = admin.accountId)) } } yield search @@ -39,8 +37,9 @@ trait SharedSearchSeeds { accessScope = Scope.current) def archivedProductsSearch(adminId: Int)(implicit au: AU) = - SharedSearch(title = "Archived", - query = parse("""[ + SharedSearch( + title = "Archived", + query = parse("""[ | { | "display": "Product : Is Archived : Yes", | "term": "archivedAt", @@ -50,7 +49,7 @@ trait SharedSearchSeeds { | } | } | ]""".stripMargin), - rawQuery = parse("""{ + rawQuery = parse("""{ | "query": { | "bool": { | "filter": [ @@ -63,14 +62,16 @@ trait SharedSearchSeeds { | } | } | }""".stripMargin), - storeAdminId = adminId, - scope = SharedSearch.ProductsScope, - accessScope = Scope.current, - isSystem = true) + storeAdminId = adminId, + scope = SharedSearch.ProductsScope, + accessScope = Scope.current, + isSystem = true + ) def archivedSkusSearch(adminId: Int)(implicit au: AU) = - SharedSearch(title = "Archived", - query = parse("""[ + SharedSearch( + title = "Archived", + query = parse("""[ | { | "display": "Product : Is Archived : Yes", | "term": "archivedAt", @@ -80,7 +81,7 @@ trait SharedSearchSeeds { | } | } | ]""".stripMargin), - rawQuery = parse("""{ + rawQuery = parse("""{ | "query": { | "bool": { | "filter": [ @@ -93,8 +94,9 @@ trait SharedSearchSeeds { | } | } | }""".stripMargin), - storeAdminId = adminId, - scope = SharedSearch.SkusScope, - accessScope = Scope.current, - isSystem = true) + storeAdminId = adminId, + scope = SharedSearch.SkusScope, + accessScope = Scope.current, + isSystem = true + ) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/ShipmentSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/ShipmentSeeds.scala index 50217ba2a3..40df2df916 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/ShipmentSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/ShipmentSeeds.scala @@ -39,35 +39,42 @@ trait ShipmentSeeds { def shippingMethods = Seq( - ShippingMethod(adminDisplayName = standardShippingNameForAdmin, - storefrontDisplayName = standardShippingName, - code = standardShippingCode, - price = 300, - isActive = true, - conditions = Some(under50Bucks)), - ShippingMethod(adminDisplayName = standardShippingNameForAdmin, - storefrontDisplayName = standardShippingName, - code = standardShippingFreeCode, - price = 0, - isActive = true, - conditions = Some(over50Bucks)), - ShippingMethod(adminDisplayName = expressShippingNameForAdmin, - storefrontDisplayName = expressShippingName, - code = expressShippingCode, - price = 1500, - isActive = true, - conditions = Some(usOnly)), - ShippingMethod(adminDisplayName = overnightShippingNameForAdmin, - storefrontDisplayName = overnightShippingName, - code = overnightShippingCode, - price = 3000, - isActive = true, - conditions = Some(usOnly)) + ShippingMethod( + adminDisplayName = standardShippingNameForAdmin, + storefrontDisplayName = standardShippingName, + code = standardShippingCode, + price = 300, + isActive = true, + conditions = Some(under50Bucks) + ), + ShippingMethod( + adminDisplayName = standardShippingNameForAdmin, + storefrontDisplayName = standardShippingName, + code = standardShippingFreeCode, + price = 0, + isActive = true, + conditions = Some(over50Bucks) + ), + ShippingMethod( + adminDisplayName = expressShippingNameForAdmin, + storefrontDisplayName = expressShippingName, + code = expressShippingCode, + price = 1500, + isActive = true, + conditions = Some(usOnly) + ), + ShippingMethod( + adminDisplayName = overnightShippingNameForAdmin, + storefrontDisplayName = overnightShippingName, + code = overnightShippingCode, + price = 3000, + isActive = true, + conditions = Some(usOnly) + ) ) def lowConditions: QueryStatement = - parse( - """ + parse(""" | { | "comparison": "and", | "conditions": [{ @@ -122,8 +129,5 @@ trait ShipmentSeeds { def shipment = Shipment(1, "boo", Some(1), Some(1)) def condition = - Condition(rootObject = "Order", - field = "subtotal", - operator = Condition.Equals, - valInt = Some(50)) + Condition(rootObject = "Order", field = "subtotal", operator = Condition.Equals, valInt = Some(50)) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/StoreAdminSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/StoreAdminSeeds.scala index fcaaacc00b..cc14a4acc4 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/StoreAdminSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/StoreAdminSeeds.scala @@ -37,8 +37,8 @@ trait StoreAdminSeeds { } def createStoreAdmins(implicit ec: EC, db: DB, ac: AC): DbResultT[Int] = { - val reader = CSVReader.open( - Source.fromInputStream(getClass.getResourceAsStream("/data/store_admins.csv"))) + val reader = + CSVReader.open(Source.fromInputStream(getClass.getResourceAsStream("/data/store_admins.csv"))) val admins = reader.all.drop(1).collect { case name :: email :: password :: org :: role :: Nil ⇒ { val user = User(accountId = 0, name = name.some, email = email.some) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/StoreCreditSeeds.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/StoreCreditSeeds.scala index 341329bc7a..5e198ec821 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/StoreCreditSeeds.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/StoreCreditSeeds.scala @@ -30,8 +30,8 @@ trait StoreCreditSeeds { currency = Currency.USD) def storeCreditSubTypes: Seq[StoreCreditSubtype] = Seq( - StoreCreditSubtype(title = "Appeasement Subtype A", originType = StoreCredit.CsrAppeasement), - StoreCreditSubtype(title = "Appeasement Subtype B", originType = StoreCredit.CsrAppeasement), - StoreCreditSubtype(title = "Appeasement Subtype C", originType = StoreCredit.CsrAppeasement) + StoreCreditSubtype(title = "Appeasement Subtype A", originType = StoreCredit.CsrAppeasement), + StoreCreditSubtype(title = "Appeasement Subtype B", originType = StoreCredit.CsrAppeasement), + StoreCreditSubtype(title = "Appeasement Subtype C", originType = StoreCredit.CsrAppeasement) ) } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/AddressGenerator.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/AddressGenerator.scala index 4c39f1dfbd..0af3063c70 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/AddressGenerator.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/AddressGenerator.scala @@ -33,14 +33,16 @@ trait AddressGenerator { val hasPhone = Random.nextBoolean() val phoneNumber = if (hasPhone) Some(Name.numerify("##########")) else None - Address(accountId = customer.accountId, - regionId = 4177, - name = customer.name.getOrElse(Name.name), - address1 = streetName, - address2 = address2, - city = city, - zip = zip, - isDefaultShipping = isDefault, - phoneNumber = phoneNumber) + Address( + accountId = customer.accountId, + regionId = 4177, + name = customer.name.getOrElse(Name.name), + address1 = streetName, + address2 = address2, + city = city, + zip = zip, + isDefaultShipping = isDefault, + phoneNumber = phoneNumber + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/CouponGenerator.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/CouponGenerator.scala index e69ec2174f..f74ab2bab5 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/CouponGenerator.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/CouponGenerator.scala @@ -41,7 +41,7 @@ case class SimpleCouponForm(percentOff: Percent, totalAmount: Int) { case class SimpleCouponShadow(f: SimpleCouponForm) { val shadow = ObjectUtils.newShadow( - parse(""" + parse(""" { "name" : {"type": "string", "ref": "name"}, "storefrontName" : {"type": "richText", "ref": "storefrontName"}, @@ -51,29 +51,27 @@ case class SimpleCouponShadow(f: SimpleCouponForm) { "activeTo" : {"type": "date", "ref": "activeTo"}, "tags" : {"type": "tags", "ref": "tags"} }"""), - f.keyMap) + f.keyMap + ) } trait CouponGenerator { - def generateCoupon(promotion: SimplePromotion): SimpleCoupon = { + def generateCoupon(promotion: SimplePromotion): SimpleCoupon = SimpleCoupon(percentOff = promotion.percentOff, totalAmount = promotion.totalAmount, promotionId = promotion.promotionId) - } - def generateCoupons(sourceData: Seq[SimpleCoupon])(implicit db: DB, - ac: AC, - au: AU): DbResultT[Seq[SimpleCoupon]] = + def generateCoupons( + sourceData: Seq[SimpleCoupon])(implicit db: DB, ac: AC, au: AU): DbResultT[Seq[SimpleCoupon]] = for { context ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) coupons ← * <~ sourceData.map(source ⇒ { val couponForm = SimpleCouponForm(source.percentOff, source.totalAmount) val couponShadow = SimpleCouponShadow(couponForm) - def couponFS: FormAndShadow = { + def couponFS: FormAndShadow = (ObjectForm(kind = Coupon.kind, attributes = couponForm.form), ObjectShadow(attributes = couponShadow.shadow)) - } val payload = CreateCoupon(attributes = couponFS.toPayload, promotion = source.promotionId) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/CreditCardGenerator.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/CreditCardGenerator.scala index 27e81d6de3..5779da563f 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/CreditCardGenerator.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/CreditCardGenerator.scala @@ -10,29 +10,31 @@ import phoenix.models.payment.creditcard.{BillingAddress, CreditCard}; trait CreditCardGenerator extends AddressGenerator { - val gatewayCustomerIds = Seq("cus_8BV45FaedrbyMI", - "cus_8BCn3Ed2Yy1cd3", - "cus_8BACO27aB3l9Sc", - "cus_8AlvEEj9TKTG9j", - "cus_8AkS76A3bahhVg", - "cus_8AkOXndcxvvE0g", - "cus_8AjhoAuAqC6FWa", - "cus_8AjaWtPNbWQvqj", - "cus_8Aif0ZvXxMO7fd", - "cus_8Ai76BTTFay94J", - "cus_8AganQYh9ACK7C", - "cus_8Afrqouoyj7aDF", - "cus_887JE4o0xdvCuy", - "cus_83RUoL0ym7d4Mr", - "cus_83MgKmTYukiQQz", - "cus_83MZpoQsbtY0kK", - "cus_83LaOiTle6avEe", - "cus_83LWLy4ahFgRC9", - "cus_7zwyNO5QHlyqQd", - "cus_7ynmhqyqvd3HZc", - "cus_7yTU1j2Nvo1ifH", - "cus_7yTU0ENGfk0pxN", - "cus_7yTUzhYqMEwy1X") + val gatewayCustomerIds = Seq( + "cus_8BV45FaedrbyMI", + "cus_8BCn3Ed2Yy1cd3", + "cus_8BACO27aB3l9Sc", + "cus_8AlvEEj9TKTG9j", + "cus_8AkS76A3bahhVg", + "cus_8AkOXndcxvvE0g", + "cus_8AjhoAuAqC6FWa", + "cus_8AjaWtPNbWQvqj", + "cus_8Aif0ZvXxMO7fd", + "cus_8Ai76BTTFay94J", + "cus_8AganQYh9ACK7C", + "cus_8Afrqouoyj7aDF", + "cus_887JE4o0xdvCuy", + "cus_83RUoL0ym7d4Mr", + "cus_83MgKmTYukiQQz", + "cus_83MZpoQsbtY0kK", + "cus_83LaOiTle6avEe", + "cus_83LWLy4ahFgRC9", + "cus_7zwyNO5QHlyqQd", + "cus_7ynmhqyqvd3HZc", + "cus_7yTU1j2Nvo1ifH", + "cus_7yTU0ENGfk0pxN", + "cus_7yTUzhYqMEwy1X" + ) def randomCustomerGatewayId = gatewayCustomerIds(Random.nextInt(gatewayCustomerIds.length)) @@ -43,21 +45,23 @@ trait CreditCardGenerator extends AddressGenerator { val address = generateAddress(customer, false) val gatewayCustomerId = randomCustomerGatewayId val gatewayCardId = "" - CreditCard(accountId = customer.accountId, - gatewayCustomerId = gatewayCustomerId, - gatewayCardId = gatewayCardId, - holderName = customer.name.getOrElse(Name.name), - lastFour = base.numerify("####"), - expMonth = today.getMonthValue, - expYear = today.getYear + 2, - isDefault = true, - address = BillingAddress(regionId = 4129, - name = customer.name.getOrElse(Name.name), - address1 = address.address1, - address2 = address.address2, - city = address.city, - zip = address.zip), - brand = "Visa") + CreditCard( + accountId = customer.accountId, + gatewayCustomerId = gatewayCustomerId, + gatewayCardId = gatewayCardId, + holderName = customer.name.getOrElse(Name.name), + lastFour = base.numerify("####"), + expMonth = today.getMonthValue, + expYear = today.getYear + 2, + isDefault = true, + address = BillingAddress(regionId = 4129, + name = customer.name.getOrElse(Name.name), + address1 = address.address1, + address2 = address.address2, + city = address.city, + zip = address.zip), + brand = "Visa" + ) } def generateCreditCards(customers: Seq[User]): Seq[CreditCard] = diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/DiscountGenerator.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/DiscountGenerator.scala index 5764c2881a..e4c19a28b0 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/DiscountGenerator.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/DiscountGenerator.scala @@ -50,7 +50,7 @@ case class SimpleDiscountForm(percentOff: Percent, totalAmount: Int) { case class SimpleDiscountShadow(f: SimpleDiscountForm) { val shadow = ObjectUtils.newShadow( - parse(""" + parse(""" { "title" : {"type": "string", "ref": "title"}, "description" : {"type": "richText", "ref": "description"}, @@ -58,7 +58,8 @@ case class SimpleDiscountShadow(f: SimpleDiscountForm) { "qualifier" : {"type": "qualifier", "ref": "qualifier"}, "offer" : {"type": "offer", "ref": "offer"} }"""), - f.keyMap) + f.keyMap + ) } trait DiscountGenerator { @@ -69,18 +70,16 @@ trait DiscountGenerator { SimpleDiscount(percentOff = percent, totalAmount = totalAmount) } - def generateDiscounts(sourceData: Seq[SimpleDiscount])( - implicit db: DB, - au: AU): DbResultT[Seq[DiscountResponse.Root]] = + def generateDiscounts(sourceData: Seq[SimpleDiscount])(implicit db: DB, + au: AU): DbResultT[Seq[DiscountResponse.Root]] = for { context ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) discounts ← * <~ sourceData.map(source ⇒ { val discountForm = SimpleDiscountForm(source.percentOff, source.totalAmount) val discountShadow = SimpleDiscountShadow(discountForm) - def discountFS: FormAndShadow = { + def discountFS: FormAndShadow = (ObjectForm(kind = Discount.kind, attributes = discountForm.form), ObjectShadow(attributes = discountShadow.shadow)) - } val payload = CreateDiscount(attributes = discountFS.toPayload) DiscountManager.create(payload, context.name) }) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/GiftCardGenerator.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/GiftCardGenerator.scala index 833421faff..297cb9cdd5 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/GiftCardGenerator.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/GiftCardGenerator.scala @@ -26,20 +26,19 @@ trait GiftCardGenerator { origin ← * <~ GiftCardManuals.create(GiftCardManual(adminId = 1, reasonId = 1)) scope ← * <~ Scope.resolveOverride() gc ← * <~ GiftCards.create( - GiftCard.buildAppeasement(GiftCardCreateByCsr(balance = nextGcBalance, reasonId = 1), - originId = origin.id, - scope = scope)) + GiftCard.buildAppeasement(GiftCardCreateByCsr(balance = nextGcBalance, reasonId = 1), + originId = origin.id, + scope = scope)) } yield gc - def generateGiftCardPurchase(accountId: Int, context: ObjectContext)( - implicit db: DB, - au: AU): DbResultT[GiftCard] = + def generateGiftCardPurchase(accountId: Int, context: ObjectContext)(implicit db: DB, + au: AU): DbResultT[GiftCard] = for { cart ← * <~ Carts.create(Cart(accountId = accountId, scope = Scope.current)) order ← * <~ Orders.createFromCart(cart, context.id, None) order ← * <~ Orders.update(order, order.copy(state = Order.ManualHold)) orig ← * <~ GiftCardOrders.create(GiftCardOrder(cordRef = order.refNum)) gc ← * <~ GiftCards.create( - GiftCard.build(balance = nextGcBalance, originId = orig.id, currency = Currency.USD)) + GiftCard.build(balance = nextGcBalance, originId = orig.id, currency = Currency.USD)) } yield gc } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/OrderGenerator.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/OrderGenerator.scala index d8ca4cb4ef..434c099621 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/OrderGenerator.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/OrderGenerator.scala @@ -76,26 +76,24 @@ trait OrderGenerator extends ShipmentSeeds { private val yesterday: Instant = utils.time.yesterday.toInstant - def manualHoldOrder(accountId: Int, - context: ObjectContext, - skuIds: Seq[Int], - giftCard: GiftCard)(implicit db: DB, au: AU): DbResultT[Order] = + def manualHoldOrder(accountId: Int, context: ObjectContext, skuIds: Seq[Int], giftCard: GiftCard)( + implicit db: DB, + au: AU): DbResultT[Order] = for { - cart ← * <~ Carts.create(Cart(accountId = accountId, scope = Scope.current)) - order ← * <~ Orders.createFromCart(cart, context.id, None) - order ← * <~ Orders.update(order, order.copy(state = ManualHold, placedAt = yesterday)) - _ ← * <~ addProductsToOrder(skuIds, cart.refNum, OrderLineItem.Pending) - origin ← * <~ StoreCreditManuals.create(StoreCreditManual(adminId = 1, reasonId = 1)) - cc ← * <~ getCc(accountId) - op ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) + cart ← * <~ Carts.create(Cart(accountId = accountId, scope = Scope.current)) + order ← * <~ Orders.createFromCart(cart, context.id, None) + order ← * <~ Orders.update(order, order.copy(state = ManualHold, placedAt = yesterday)) + _ ← * <~ addProductsToOrder(skuIds, cart.refNum, OrderLineItem.Pending) + origin ← * <~ StoreCreditManuals.create(StoreCreditManual(adminId = 1, reasonId = 1)) + cc ← * <~ getCc(accountId) + op ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) addr ← * <~ getDefaultAddress(accountId) shipMethodIds ← * <~ ShippingMethods.map(_.id).result shipMethod ← * <~ getShipMethod(1 + Random.nextInt(shipMethodIds.length)) shipM ← * <~ OrderShippingMethods.create( - OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) + OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) _ ← * <~ OrderShippingAddresses.create( - OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) + OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) _ ← * <~ OrderTotaler.saveTotals(cart, order) } yield order @@ -111,21 +109,20 @@ trait OrderGenerator extends ShipmentSeeds { origin ← * <~ StoreCreditManuals.create(StoreCreditManual(adminId = 1, reasonId = 1)) totals ← * <~ total(skuIds) sc ← * <~ StoreCredits.create( - StoreCredit(scope = Scope.current, - originId = origin.id, - accountId = accountId, - originalBalance = totals)) - op ← * <~ OrderPayments.create( - OrderPayment.build(sc).copy(cordRef = cart.refNum, amount = totals.some)) + StoreCredit(scope = Scope.current, + originId = origin.id, + accountId = accountId, + originalBalance = totals)) + op ← * <~ OrderPayments.create(OrderPayment.build(sc).copy(cordRef = cart.refNum, amount = totals.some)) _ ← * <~ StoreCredits.auth(sc, op.id, totals) _ ← * <~ StoreCredits.capture(sc, op.id, totals) addr ← * <~ getDefaultAddress(accountId) shipMethodIds ← * <~ ShippingMethods.map(_.id).result shipMethod ← * <~ getShipMethod(1 + Random.nextInt(shipMethodIds.length)) shipM ← * <~ OrderShippingMethods.create( - OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) + OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) _ ← * <~ OrderShippingAddresses.create( - OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) + OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) _ ← * <~ OrderTotaler.saveTotals(cart, order) } yield order @@ -133,20 +130,19 @@ trait OrderGenerator extends ShipmentSeeds { implicit db: DB, au: AU): DbResultT[Order] = for { - cart ← * <~ Carts.create(Cart(accountId = accountId, scope = Scope.current)) - order ← * <~ Orders.createFromCart(cart, context.id, None) - order ← * <~ Orders.update(order, order.copy(state = FraudHold, placedAt = yesterday)) - _ ← * <~ addProductsToOrder(skuIds, cart.refNum, OrderLineItem.Pending) - cc ← * <~ getCc(accountId) - op ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) + cart ← * <~ Carts.create(Cart(accountId = accountId, scope = Scope.current)) + order ← * <~ Orders.createFromCart(cart, context.id, None) + order ← * <~ Orders.update(order, order.copy(state = FraudHold, placedAt = yesterday)) + _ ← * <~ addProductsToOrder(skuIds, cart.refNum, OrderLineItem.Pending) + cc ← * <~ getCc(accountId) + op ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) addr ← * <~ getDefaultAddress(accountId) shipMethodIds ← * <~ ShippingMethods.map(_.id).result shipMethod ← * <~ getShipMethod(1 + Random.nextInt(shipMethodIds.length)) shipM ← * <~ OrderShippingMethods.create( - OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) + OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) _ ← * <~ OrderShippingAddresses.create( - OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) + OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) _ ← * <~ OrderTotaler.saveTotals(cart, order) } yield order @@ -163,25 +159,22 @@ trait OrderGenerator extends ShipmentSeeds { remorsePeriodEnd = Instant.now.plusSeconds(randomSeconds.toLong).some, placedAt = yesterday)) - _ ← * <~ addProductsToOrder(skuIds, cart.refNum, OrderLineItem.Pending) - cc ← * <~ getCc(accountId) - op ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) + _ ← * <~ addProductsToOrder(skuIds, cart.refNum, OrderLineItem.Pending) + cc ← * <~ getCc(accountId) + op ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) addr ← * <~ getDefaultAddress(accountId) shipMethodIds ← * <~ ShippingMethods.map(_.id).result shipMethod ← * <~ getShipMethod(1 + Random.nextInt(shipMethodIds.length)) shipM ← * <~ OrderShippingMethods.create( - OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) + OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) _ ← * <~ OrderShippingAddresses.create( - OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) + OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) _ ← * <~ OrderTotaler.saveTotals(cart, order) } yield order - def cartOrderUsingGiftCard(accountId: Int, - context: ObjectContext, - skuIds: Seq[Int], - giftCard: GiftCard)(implicit db: DB, au: AU): DbResultT[Cart] = { - + def cartOrderUsingGiftCard(accountId: Int, context: ObjectContext, skuIds: Seq[Int], giftCard: GiftCard)( + implicit db: DB, + au: AU): DbResultT[Cart] = for { cart ← * <~ Carts.create(Cart(accountId = accountId, scope = Scope.current)) _ ← * <~ addProductsToCart(skuIds, cart.refNum) @@ -193,32 +186,28 @@ trait OrderGenerator extends ShipmentSeeds { // Authorize SC payments addr ← * <~ getDefaultAddress(accountId) _ ← * <~ OrderShippingAddresses.create( - OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) + OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) _ ← * <~ CartTotaler.saveTotals(cart) } yield cart - } - def cartOrderUsingCreditCard(accountId: Int, - context: ObjectContext, - skuIds: Seq[Int], - giftCard: GiftCard)(implicit db: DB, au: AU): DbResultT[Cart] = + def cartOrderUsingCreditCard(accountId: Int, context: ObjectContext, skuIds: Seq[Int], giftCard: GiftCard)( + implicit db: DB, + au: AU): DbResultT[Cart] = for { cart ← * <~ Carts.create(Cart(accountId = accountId, scope = Scope.current)) _ ← * <~ addProductsToCart(skuIds, cart.refNum) cc ← * <~ getCc(accountId) - _ ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) + _ ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) addr ← * <~ getDefaultAddress(accountId) _ ← * <~ OrderShippingAddresses.create( - OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) + OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) _ ← * <~ CartTotaler.saveTotals(cart) } yield cart - def shippedOrderUsingCreditCard( - accountId: Int, - context: ObjectContext, - skuIds: Seq[Int], - giftCard: GiftCard)(implicit db: DB, au: AU): DbResultT[Order] = { + def shippedOrderUsingCreditCard(accountId: Int, + context: ObjectContext, + skuIds: Seq[Int], + giftCard: GiftCard)(implicit db: DB, au: AU): DbResultT[Order] = for { shipMethodIds ← * <~ ShippingMethods.map(_.id).result shipMethod ← * <~ getShipMethod(1 + Random.nextInt(shipMethodIds.length)) @@ -228,31 +217,28 @@ trait OrderGenerator extends ShipmentSeeds { order ← * <~ Orders.update(order, order.copy(state = Shipped, placedAt = yesterday)) _ ← * <~ addProductsToOrder(skuIds, cart.refNum, OrderLineItem.Shipped) cc ← * <~ getCc(accountId) // TODO: auth - op ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) + op ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) ccc ← * <~ CreditCardCharges.create( - CreditCardCharge(creditCardId = cc.id, - orderPaymentId = op.id, - stripeChargeId = s"${cc.id}_${op.id}", - state = FullCapture, - amount = op.amount.getOrElse(0))) + CreditCardCharge(creditCardId = cc.id, + orderPaymentId = op.id, + stripeChargeId = s"${cc.id}_${op.id}", + state = FullCapture, + amount = op.amount.getOrElse(0))) addr ← * <~ getDefaultAddress(accountId) shipA ← * <~ OrderShippingAddresses.create( - OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) + OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) shipM ← * <~ OrderShippingMethods.create( - OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) + OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) _ ← * <~ OrderTotaler.saveTotals(cart, order) _ ← * <~ Shipments.create( - Shipment(cordRef = cart.refNum, - orderShippingMethodId = shipM.id.some, - shippingAddressId = shipA.id.some)) + Shipment(cordRef = cart.refNum, + orderShippingMethodId = shipM.id.some, + shippingAddressId = shipA.id.some)) } yield order - } - def shippedOrderUsingGiftCard(accountId: Int, - context: ObjectContext, - skuIds: Seq[Int], - giftCard: GiftCard)(implicit db: DB, au: AU): DbResultT[Order] = { + def shippedOrderUsingGiftCard(accountId: Int, context: ObjectContext, skuIds: Seq[Int], giftCard: GiftCard)( + implicit db: DB, + au: AU): DbResultT[Order] = for { shipMethodIds ← * <~ ShippingMethods.map(_.id).result shipMethod ← * <~ getShipMethod(1 + Random.nextInt(shipMethodIds.length)) @@ -272,32 +258,25 @@ trait OrderGenerator extends ShipmentSeeds { _ ← * <~ generateCharges(Seq((cc, ccPayment)), gcPayment.toList.map(p ⇒ (gc, p))) addr ← * <~ getDefaultAddress(accountId) shipA ← * <~ OrderShippingAddresses.create( - OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) + OrderShippingAddress.buildFromAddress(addr).copy(cordRef = cart.refNum)) shipM ← * <~ OrderShippingMethods.create( - OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) + OrderShippingMethod.build(cordRef = cart.refNum, method = shipMethod)) _ ← * <~ OrderTotaler.saveTotals(cart, order) _ ← * <~ Shipments.create( - Shipment(cordRef = cart.refNum, - orderShippingMethodId = shipM.id.some, - shippingAddressId = shipA.id.some)) + Shipment(cordRef = cart.refNum, + orderShippingMethodId = shipM.id.some, + shippingAddressId = shipA.id.some)) } yield order - } def addProductsToOrder(skuIds: Seq[Int], orderRef: String, state: OrderLineItem.State)( implicit db: DB): DbResultT[Unit] = for { skus ← * <~ Skus.filter(_.id inSet skuIds).result - _ ← * <~ OrderLineItems.createAll( - skus.map( - sku ⇒ - OrderLineItem(cordRef = orderRef, - skuId = sku.id, - skuShadowId = sku.shadowId, - state = state))) + _ ← * <~ OrderLineItems.createAll(skus.map(sku ⇒ + OrderLineItem(cordRef = orderRef, skuId = sku.id, skuShadowId = sku.shadowId, state = state))) } yield {} - def addProductsToCart(skuIds: Seq[Int], cartRef: String)( - implicit db: DB): DbResultT[Seq[CartLineItem]] = { + def addProductsToCart(skuIds: Seq[Int], cartRef: String)(implicit db: DB): DbResultT[Seq[CartLineItem]] = { val itemsToInsert = skuIds.map(skuId ⇒ CartLineItem(cordRef = cartRef, skuId = skuId, attributes = None)) CartLineItems.createAllReturningModels(itemsToInsert) @@ -305,11 +284,7 @@ trait OrderGenerator extends ShipmentSeeds { def orderNotes(implicit au: AU): Seq[Note] = { def newNote(body: String) = - Note(referenceId = 1, - referenceType = Note.Order, - storeAdminId = 1, - body = body, - scope = Scope.current) + Note(referenceId = 1, referenceType = Note.Order, storeAdminId = 1, body = body, scope = Scope.current) (1 to Random.nextInt(4)) map { i ⇒ newNote(Lorem.sentence(Random.nextInt(5))) } @@ -321,67 +296,61 @@ trait OrderGenerator extends ShipmentSeeds { t ← * <~ prices.sum } yield t - def generateCharges(ccs: Seq[(CreditCard, OrderPayment)], gcs: Seq[(GiftCard, OrderPayment)]) - : DbResultT[(Seq[CreditCardCharge], Seq[GiftCardAdjustment])] = + def generateCharges( + ccs: Seq[(CreditCard, OrderPayment)], + gcs: Seq[(GiftCard, OrderPayment)]): DbResultT[(Seq[CreditCardCharge], Seq[GiftCardAdjustment])] = for { ccr ← * <~ ccs.map { case (cc, op) ⇒ CreditCardCharges.create( - CreditCardCharge(creditCardId = cc.id, - orderPaymentId = op.id, - stripeChargeId = s"${cc.id}_${op.id}", - state = FullCapture, - amount = op.amount.getOrElse(0))) + CreditCardCharge(creditCardId = cc.id, + orderPaymentId = op.id, + stripeChargeId = s"${cc.id}_${op.id}", + state = FullCapture, + amount = op.amount.getOrElse(0))) } gcr ← * <~ gcs.map { case (gc, op) ⇒ val amount = op.amount.getOrElse(0L) GiftCardAdjustments.create( - GiftCardAdjustment(giftCardId = gc.id, - orderPaymentId = op.id.some, - credit = amount, - debit = 0, - availableBalance = gc.availableBalance - amount, - state = InStorePaymentStates.Capture)) + GiftCardAdjustment(giftCardId = gc.id, + orderPaymentId = op.id.some, + credit = amount, + debit = 0, + availableBalance = gc.availableBalance - amount, + state = InStorePaymentStates.Capture)) } } yield (ccr, gcr) - private def generateOrderPayments( - cart: Cart, - order: Order, - cc: CreditCard, - gc: GiftCard, - deductFromGc: Long): DbResultT[(Option[OrderPayment], OrderPayment)] = { + private def generateOrderPayments(cart: Cart, + order: Order, + cc: CreditCard, + gc: GiftCard, + deductFromGc: Long): DbResultT[(Option[OrderPayment], OrderPayment)] = if (gc.availableBalance > 0) for { op1 ← * <~ OrderPayments.create( - OrderPayment.build(gc).copy(cordRef = cart.refNum, amount = deductFromGc.some)) - op2 ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) + OrderPayment.build(gc).copy(cordRef = cart.refNum, amount = deductFromGc.some)) + op2 ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) } yield (op1.some, op2) else for { - op ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) + op ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) } yield (None, op) - } private def generateCartPayments(cart: Cart, cc: CreditCard, gc: GiftCard, - deductFromGc: Long): DbResultT[Unit] = { + deductFromGc: Long): DbResultT[Unit] = if (gc.availableBalance > 0) for { op1 ← * <~ OrderPayments.create( - OrderPayment.build(gc).copy(cordRef = cart.refNum, amount = deductFromGc.some)) - op2 ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) + OrderPayment.build(gc).copy(cordRef = cart.refNum, amount = deductFromGc.some)) + op2 ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) } yield {} else for { - op ← * <~ OrderPayments.create( - OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) + op ← * <~ OrderPayments.create(OrderPayment.build(cc).copy(cordRef = cart.refNum, amount = none)) } yield {} - } private def getCc(accountId: Int)(implicit db: DB) = CreditCards.findDefaultByAccountId(accountId).mustFindOneOr(CustomerHasNoCreditCard(accountId)) @@ -397,8 +366,7 @@ trait OrderGenerator extends ShipmentSeeds { .findActiveById(shipMethodId) .mustFindOneOr(NotFoundFailure400(ShippingMethod, shipMethodId)) - private def authGiftCard( - results: Seq[(OrderPayment, GiftCard)]): DbResultT[List[GiftCardAdjustment]] = + private def authGiftCard(results: Seq[(OrderPayment, GiftCard)]): DbResultT[List[GiftCardAdjustment]] = DbResultT.seqCollectFailures(results.map { case (pmt, m) ⇒ GiftCards.authOrderPayment(m, pmt) }.toList) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/ProductGenerator.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/ProductGenerator.scala index 68d90ea6cf..aace001761 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/ProductGenerator.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/ProductGenerator.scala @@ -14,57 +14,58 @@ import scala.util.Random object ProductGenerator { val sampleImages = Seq( - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Detail.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Side.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Top_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Detail.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Side.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Top_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Three_Quarter_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Three_Quarter_Top.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Granger_Three_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Granger_Three_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Granger_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/index.html", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Detail.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Side.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Top_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Detail.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Side.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Top_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Detail.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Side.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Top_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Flex_Metal_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Flex_Metal_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Flex_Metal_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Flex_Metal_Three_Quarter_Top.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Off_World_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Off_World_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Off_World_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Off_World_Three_Quarter_Top.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Three_Quarter_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Three_Quarter_Top.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Technotronics_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Technotronics_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Technotronics_Three_Quarters.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Technotronics_Three_Quarters_Top.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Front.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Three_Quarter_Back.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Three_Quarter.jpg", - "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Three_Quarter_Top.jpg") + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Detail.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Side.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Emma_Top_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Detail.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Side.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Festival_Top_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Three_Quarter_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Gold_Blue_Three_Quarter_Top.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Granger_Three_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Granger_Three_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Granger_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/index.html", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Detail.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Side.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Marley_Top_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Detail.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Side.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Quay_Top_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Detail.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Side.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Round_Readers_Top_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Flex_Metal_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Flex_Metal_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Flex_Metal_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Flex_Metal_Three_Quarter_Top.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Off_World_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Off_World_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Off_World_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Off_World_Three_Quarter_Top.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Three_Quarter_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Post_Punk_Three_Quarter_Top.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Technotronics_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Technotronics_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Technotronics_Three_Quarters.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Spitfire_Technotronics_Three_Quarters_Top.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Front.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Three_Quarter_Back.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Three_Quarter.jpg", + "https://s3-us-west-2.amazonaws.com/fc-firebird-public/images/product/Vivien_Three_Quarter_Top.jpg" + ) def randomImage = sampleImages(Random.nextInt(sampleImages.length)) } @@ -78,13 +79,13 @@ trait ProductGenerator { .getLines .map(_.grouped(2)) //group characters in line into sets of 2 .foldLeft(new MarkovChain[String](start, stop))((acc, wordChunks) ⇒ - acc.insert(wordChunks.map(_.toLowerCase).toList)) + acc.insert(wordChunks.map(_.toLowerCase).toList)) def generateProduct: SimpleProductData = { val base = new Base {} val code = base.letterify("???-???") val title = nameGenerator.generate(Math.max(5, Random.nextInt(20))).mkString("") - Console.err.println(s"product: ${code} ${title}") + Console.err.println(s"product: $code $title") SimpleProductData(code = code, title = title, description = title, diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/PromotionGenerator.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/PromotionGenerator.scala index 062329b66c..e0c5dd0435 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/PromotionGenerator.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/PromotionGenerator.scala @@ -48,7 +48,7 @@ case class SimplePromotionForm(percentOff: Percent, totalAmount: Int) { case class SimplePromotionShadow(f: SimplePromotionForm) { val shadow = ObjectUtils.newShadow( - parse(""" + parse(""" { "name" : {"type": "string", "ref": "name"}, "storefrontName" : {"type": "richText", "ref": "storefrontName"}, @@ -58,7 +58,8 @@ case class SimplePromotionShadow(f: SimplePromotionForm) { "activeTo" : {"type": "date", "ref": "activeTo"}, "tags" : {"type": "tags", "ref": "tags"} }"""), - f.keyMap) + f.keyMap + ) } trait PromotionGenerator { @@ -72,10 +73,8 @@ trait PromotionGenerator { SimplePromotion(applyType = applyType, percentOff = percent, totalAmount = totalAmount) } - def generatePromotions(sourceData: Seq[SimplePromotion])( - implicit db: DB, - ac: AC, - au: AU): DbResultT[Seq[SimplePromotion]] = + def generatePromotions( + sourceData: Seq[SimplePromotion])(implicit db: DB, ac: AC, au: AU): DbResultT[Seq[SimplePromotion]] = for { context ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) promotions ← * <~ sourceData.map(source ⇒ { @@ -84,10 +83,9 @@ trait PromotionGenerator { val discountForm = SimpleDiscountForm(source.percentOff, source.totalAmount) val discountShadow = SimpleDiscountShadow(discountForm) - def discountFS: FormAndShadow = { + def discountFS: FormAndShadow = (ObjectForm(kind = Promotion.kind, attributes = discountForm.form), ObjectShadow(attributes = discountShadow.shadow)) - } val promotionFS: FormAndShadow = { (ObjectForm(kind = Promotion.kind, attributes = promotionForm.form), ObjectShadow(attributes = promotionShadow.shadow)) @@ -96,8 +94,7 @@ trait PromotionGenerator { val payload = CreatePromotion(applyType = source.applyType, attributes = promotionFS.toPayload, - discounts = - Seq(CreateDiscount(attributes = discountFS.toPayload))) + discounts = Seq(CreateDiscount(attributes = discountFS.toPayload))) PromotionManager.create(payload, context.name, None).map { newPromo ⇒ source.copy(promotionId = newPromo.id) diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/SeedsGenerator.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/SeedsGenerator.scala index a9b35800e0..52ee4e5de3 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/SeedsGenerator.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/generators/SeedsGenerator.scala @@ -27,14 +27,13 @@ object SeedsGenerator with PromotionGenerator with CouponGenerator { - def generateAddresses(customers: Seq[User]): Seq[Address] = { + def generateAddresses(customers: Seq[User]): Seq[Address] = customers.flatMap { c ⇒ generateAddress(customer = c, isDefault = true) +: - ((0 to Random.nextInt(2)) map { i ⇒ - generateAddress(customer = c, isDefault = false) - }) + ((0 to Random.nextInt(2)) map { i ⇒ + generateAddress(customer = c, isDefault = false) + }) } - } def makePromotions(promotionCount: Int) = (1 to promotionCount).par.map { i ⇒ diff --git a/phoenix-scala/phoenix/app/phoenix/utils/seeds/package.scala b/phoenix-scala/phoenix/app/phoenix/utils/seeds/package.scala index 5702d6776e..8f80fd8836 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/seeds/package.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/seeds/package.scala @@ -36,7 +36,7 @@ package object seeds { case class BaseDiscountShadow(f: BaseDiscountForm) { val shadow = ObjectUtils.newShadow( - parse(""" + parse(""" { "title" : {"type": "string", "ref": "title"}, "description" : {"type": "richText", "ref": "description"}, @@ -44,7 +44,8 @@ package object seeds { "qualifier" : {"type": "qualifier", "ref": "qualifier"}, "offer" : {"type": "offer", "ref": "offer"} }"""), - f.keyMap) + f.keyMap + ) } case class BasePromotion(promotionId: Int = 0, @@ -71,7 +72,7 @@ package object seeds { case class BasePromotionShadow(f: BasePromotionForm) { val shadow = ObjectUtils.newShadow( - parse(""" + parse(""" { "name" : {"type": "string", "ref": "name"}, "storefrontName" : {"type": "richText", "ref": "storefrontName"}, @@ -81,7 +82,8 @@ package object seeds { "activeTo" : {"type": "date", "ref": "activeTo"}, "tags" : {"type": "tags", "ref": "tags"} }"""), - f.keyMap) + f.keyMap + ) } case class BaseCoupon(formId: Int = 0, shadowId: Int = 0, promotionId: Int) @@ -107,7 +109,7 @@ package object seeds { case class BaseCouponShadow(f: BaseCouponForm) { val shadow = ObjectUtils.newShadow( - parse(""" + parse(""" { "name" : {"type": "string", "ref": "name"}, "storefrontName" : {"type": "richText", "ref": "storefrontName"}, @@ -118,6 +120,7 @@ package object seeds { "tags" : {"type": "tags", "ref": "tags"}, "usageRules" : {"type": "usageRules", "ref": "usageRules"} }"""), - f.keyMap) + f.keyMap + ) } } diff --git a/phoenix-scala/phoenix/app/phoenix/utils/time/JavaTimeJson4sSerializer.scala b/phoenix-scala/phoenix/app/phoenix/utils/time/JavaTimeJson4sSerializer.scala index 19d24fa921..30e9e16d6d 100644 --- a/phoenix-scala/phoenix/app/phoenix/utils/time/JavaTimeJson4sSerializer.scala +++ b/phoenix-scala/phoenix/app/phoenix/utils/time/JavaTimeJson4sSerializer.scala @@ -12,7 +12,7 @@ object JavaTimeJson4sSerializer { object jsonFormat extends CustomSerializer[Instant](format ⇒ - ({ + ({ case JString(s) ⇒ Instant.from(formatter.parse(s)) case JNull ⇒ null }, { diff --git a/phoenix-scala/phoenix/test/integration/AddressesIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/AddressesIntegrationTest.scala index d5774d8eba..788b2b777d 100644 --- a/phoenix-scala/phoenix/test/integration/AddressesIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/AddressesIntegrationTest.scala @@ -10,7 +10,7 @@ import phoenix.responses.PublicResponses.CountryWithRegions import testutils._ import testutils.apis.{PhoenixAdminApi, PhoenixPublicApi} import testutils.fixtures.BakedFixtures -import testutils.fixtures.api.{ApiFixtureHelpers, randomAddress} +import testutils.fixtures.api.{randomAddress, ApiFixtureHelpers} class AddressesIntegrationTest extends IntegrationTestBase diff --git a/phoenix-scala/phoenix/test/integration/AllOrdersIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/AllOrdersIntegrationTest.scala index 34ab92cc40..e9a292a271 100644 --- a/phoenix-scala/phoenix/test/integration/AllOrdersIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/AllOrdersIntegrationTest.scala @@ -27,8 +27,8 @@ class AllOrdersIntegrationTest val allOrders = all.result.map(o ⇒ (o.referenceNumber, o.orderState)) allOrders must contain allOf ( - ("foo", FulfillmentStarted), - ("bar", FulfillmentStarted) + ("foo", FulfillmentStarted), + ("bar", FulfillmentStarted) ) all.errors.value must contain only NotFoundFailure404(Order, "nonExistent").description } @@ -42,7 +42,7 @@ class AllOrdersIntegrationTest allOrders must === (Seq((order.refNum, order.state))) all.errors.value.head must === ( - StateTransitionNotAllowed(order.state, Shipped, order.refNum).description) + StateTransitionNotAllowed(order.state, Shipped, order.refNum).description) } } @@ -50,8 +50,7 @@ class AllOrdersIntegrationTest (for { acc ← * <~ Accounts.create(Account()) cust ← * <~ Users.create(Factories.customer.copy(accountId = acc.id)) - _ ← * <~ CustomersData.create( - CustomerData(userId = cust.id, accountId = acc.id, scope = Scope.current)) + _ ← * <~ CustomersData.create(CustomerData(userId = cust.id, accountId = acc.id, scope = Scope.current)) c = Factories.cart(Scope.current).copy(accountId = acc.id) cart ← * <~ Carts.create(c.copy(referenceNumber = "foo")) order ← * <~ Orders.createFromCart(cart, subScope = None) diff --git a/phoenix-scala/phoenix/test/integration/AmazonOrderIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/AmazonOrderIntegrationTest.scala index 87e95111fd..de9095cda2 100644 --- a/phoenix-scala/phoenix/test/integration/AmazonOrderIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/AmazonOrderIntegrationTest.scala @@ -41,15 +41,17 @@ class AmazonOrderIntegrationTest trait Fixture { val customer = api_newCustomer - val amazonOrderPayload = CreateAmazonOrderPayload(amazonOrderId = "111-5296499-9653859", - orderTotal = 4500, - paymentMethodDetail = "CreditCard", - orderType = "StandardOrder", - currency = Currency.USD, - orderStatus = "Shipped", - purchaseDate = Instant.now, - scope = LTree("1"), - customerEmail = customer.email.value) + val amazonOrderPayload = CreateAmazonOrderPayload( + amazonOrderId = "111-5296499-9653859", + orderTotal = 4500, + paymentMethodDetail = "CreditCard", + orderType = "StandardOrder", + currency = Currency.USD, + orderStatus = "Shipped", + purchaseDate = Instant.now, + scope = LTree("1"), + customerEmail = customer.email.value + ) val amazonOrderResponse = amazonOrdersApi.create(amazonOrderPayload).as[AmazonOrderResponse] } diff --git a/phoenix-scala/phoenix/test/integration/ApplePayIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/ApplePayIntegrationTest.scala index c3d14b5b69..af71c4e44f 100644 --- a/phoenix-scala/phoenix/test/integration/ApplePayIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/ApplePayIntegrationTest.scala @@ -52,7 +52,7 @@ class ApplePayIntegrationTest withCustomerAuth(customerLoginData, customer.id) { implicit auth ⇒ storefrontCartsApi.applePayCheckout(payment).as[OrderResponse].referenceNumber must === ( - cart.referenceNumber) + cart.referenceNumber) } } @@ -66,8 +66,7 @@ class ApplePayIntegrationTest } "Capture of Apple Pay payments" - { - "Should capture cc payments if cc payment was authorized" in new ApplePayFixture - with CreditCardsFixture { + "Should capture cc payments if cc payment was authorized" in new ApplePayFixture with CreditCardsFixture { withCustomerAuth(customerLoginData, customer.id) { implicit auth ⇒ val cc = storefrontPaymentsApi.creditCards.create(ccPayload).as[CreditCardsResponse.Root] cartsApi(refNum).payments.creditCard.add(CreditCardPayment(cc.id)).mustBeOk() @@ -122,9 +121,9 @@ class ApplePayIntegrationTest val customerLoginData = TestLoginData(email = "test@bar.com", password = "pwd") val customer = customersApi .create( - CreateCustomerPayload(email = customerLoginData.email, - name = "Test customer".some, - password = customerLoginData.password.some)) + CreateCustomerPayload(email = customerLoginData.email, + name = "Test customer".some, + password = customerLoginData.password.some)) .as[CustomerResponse.Root] val cart = cartsApi.create(CreateCart(customerId = customer.id.some)).as[CartResponse] @@ -134,9 +133,8 @@ class ApplePayIntegrationTest // we don't have shipping method API creation as of PR #910 val shippingMethod: ShippingMethod = ShippingMethods .create( - Factories.shippingMethods.head.copy(conditions = lowConditions.some, - adminDisplayName = - ShippingMethod.expressShippingNameForAdmin)) + Factories.shippingMethods.head.copy(conditions = lowConditions.some, + adminDisplayName = ShippingMethod.expressShippingNameForAdmin)) .gimme val randomAddress = CreateAddressPayload(regionId = Region.californiaId, diff --git a/phoenix-scala/phoenix/test/integration/AssignmentsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/AssignmentsIntegrationTest.scala index 97750daa1d..a69be3ba20 100644 --- a/phoenix-scala/phoenix/test/integration/AssignmentsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/AssignmentsIntegrationTest.scala @@ -84,18 +84,17 @@ class AssignmentsIntegrationTest "can be assigned to multiple orders with graceful error handling" in new BulkAssignmentFixture { private val response = ordersApi - .assign(BulkAssignmentPayload(entityIds = Seq(order1.refNum, order2.refNum, "NOPE"), - storeAdminId = storeAdmin.accountId)) + .assign( + BulkAssignmentPayload(entityIds = Seq(order1.refNum, order2.refNum, "NOPE"), + storeAdminId = storeAdmin.accountId)) .as[TheResponse[Seq[AllOrders.Root]]] response.result.size mustBe 2 private val assertFailures = - Map[String, String]("NOPE" → NotFoundFailure404(Order, "NOPE").description, - order1.refNum → AlreadyAssignedFailure( - Order, - order1.refNum, - storeAdmin.accountId).description) + Map[String, String]( + "NOPE" → NotFoundFailure404(Order, "NOPE").description, + order1.refNum → AlreadyAssignedFailure(Order, order1.refNum, storeAdmin.accountId).description) response.errors.value must contain theSameElementsAs assertFailures.values @@ -108,17 +107,17 @@ class AssignmentsIntegrationTest "can be unassigned from multiple orders with graceful error handling" in new BulkAssignmentFixture { private val response = ordersApi - .unassign(BulkAssignmentPayload(entityIds = Seq(order1.refNum, order2.refNum, "NOPE"), - storeAdminId = storeAdmin.accountId)) + .unassign( + BulkAssignmentPayload(entityIds = Seq(order1.refNum, order2.refNum, "NOPE"), + storeAdminId = storeAdmin.accountId)) .as[TheResponse[Seq[AllOrders.Root]]] response.result must have size 2 private val assertFailures = - Map[String, String]("NOPE" → NotFoundFailure404(Order, "NOPE").description, - order2.refNum → NotAssignedFailure(Order, - order2.refNum, - storeAdmin.accountId).description) + Map[String, String]( + "NOPE" → NotFoundFailure404(Order, "NOPE").description, + order2.refNum → NotAssignedFailure(Order, order2.refNum, storeAdmin.accountId).description) response.errors.value must contain theSameElementsAs assertFailures.values @@ -130,38 +129,36 @@ class AssignmentsIntegrationTest trait AssignmentFixture extends Order_Baked { val (assignee, secondAdmin) = (for { assignee ← * <~ Assignments.create( - Assignment(referenceType = Assignment.Order, - referenceId = order.id, - storeAdminId = storeAdmin.accountId, - assignmentType = Assignment.Assignee)) + Assignment(referenceType = Assignment.Order, + referenceId = order.id, + storeAdminId = storeAdmin.accountId, + assignmentType = Assignment.Assignee)) account ← * <~ Accounts.create(Account()) secondAdmin ← * <~ Users.create( - Factories.storeAdmin - .copy(accountId = account.id, email = "a@b.c".some, name = "Admin2".some)) + Factories.storeAdmin + .copy(accountId = account.id, email = "a@b.c".some, name = "Admin2".some)) custData ← * <~ AdminsData.create( - AdminData(userId = secondAdmin.id, - accountId = account.id, - scope = Scope.current)) + AdminData(userId = secondAdmin.id, accountId = account.id, scope = Scope.current)) } yield (assignee, secondAdmin)).gimme } trait BulkAssignmentFixture extends Customer_Seed with StoreAdmin_Seed { val (order1, order2) = (for { cart ← * <~ Carts.create( - Factories - .cart(Scope.current) - .copy(accountId = customer.accountId, referenceNumber = "foo")) + Factories + .cart(Scope.current) + .copy(accountId = customer.accountId, referenceNumber = "foo")) order1 ← * <~ Orders.createFromCart(cart, None) cart ← * <~ Carts.create( - Factories - .cart(Scope.current) - .copy(accountId = customer.accountId, referenceNumber = "bar")) + Factories + .cart(Scope.current) + .copy(accountId = customer.accountId, referenceNumber = "bar")) order2 ← * <~ Orders.createFromCart(cart, None) _ ← * <~ Assignments.create( - Assignment(referenceType = Assignment.Order, - referenceId = order1.id, - storeAdminId = storeAdmin.accountId, - assignmentType = Assignment.Assignee)) + Assignment(referenceType = Assignment.Order, + referenceId = order1.id, + storeAdminId = storeAdmin.accountId, + assignmentType = Assignment.Assignee)) } yield (order1, order2)).gimme val orderRef1 = order1.referenceNumber diff --git a/phoenix-scala/phoenix/test/integration/AutoPromotionsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/AutoPromotionsIntegrationTest.scala index 9a251845bd..b677d1f615 100644 --- a/phoenix-scala/phoenix/test/integration/AutoPromotionsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/AutoPromotionsIntegrationTest.scala @@ -49,10 +49,8 @@ class AutoPromotionsIntegrationTest val promos = percentOffs.map { percentOff ⇒ promotionsApi - .create( - PromotionPayloadBuilder.build(Promotion.Auto, - PromoOfferBuilder.CartPercentOff(percentOff), - PromoQualifierBuilder.CartAny)) + .create(PromotionPayloadBuilder + .build(Promotion.Auto, PromoOfferBuilder.CartPercentOff(percentOff), PromoQualifierBuilder.CartAny)) .as[PromotionResponse.Root] } @@ -85,27 +83,25 @@ class AutoPromotionsIntegrationTest val promo = promotionsApi .create( - PromotionPayloadBuilder.build(Promotion.Auto, - PromoOfferBuilder.CartPercentOff(percentOffInitial), - PromoQualifierBuilder.CartAny)) + PromotionPayloadBuilder.build(Promotion.Auto, + PromoOfferBuilder.CartPercentOff(percentOffInitial), + PromoQualifierBuilder.CartAny)) .as[PromotionResponse.Root] val customerA, customerB = api_newCustomer() // FIXME: use API val shippingMethod = UpdateShippingMethod( - ShippingMethods - .create( - ShippingMethod( - adminDisplayName = "a", - storefrontDisplayName = "b", - code = "c", - price = 1000, - conditions = Some( - parse("""{"comparison": "and", "conditions": []}""").extract[QueryStatement]) - )) - .gimme - .id) + ShippingMethods + .create(ShippingMethod( + adminDisplayName = "a", + storefrontDisplayName = "b", + code = "c", + price = 1000, + conditions = Some(parse("""{"comparison": "and", "conditions": []}""").extract[QueryStatement]) + )) + .gimme + .id) // FIXME: use API val reason = Reasons.create(Factories.reason(storeAdmin.accountId)).gimme @@ -118,20 +114,20 @@ class AutoPromotionsIntegrationTest .asTheResult[CartResponse] cartsApi(refNum).shippingAddress .create( - CreateAddressPayload(name = "Home Office", - regionId = 1, - address1 = "3000 Coolio Dr", - city = "Seattle", - zip = "55555")) + CreateAddressPayload(name = "Home Office", + regionId = 1, + address1 = "3000 Coolio Dr", + city = "Seattle", + zip = "55555")) .asTheResult[CartResponse] val c = cartsApi(refNum).shippingMethod.update(shippingMethod).asTheResult[CartResponse] import c.totals.total customersApi(customer.id).payments.storeCredit .create( - CreateManualStoreCredit( - amount = total, - reasonId = reason.id - )) + CreateManualStoreCredit( + amount = total, + reasonId = reason.id + )) .as[StoreCreditResponse.Root] cartsApi(refNum).payments.storeCredit .add(StoreCreditPayment(total)) @@ -144,17 +140,19 @@ class AutoPromotionsIntegrationTest // Now, let’s update the promotion and see if orderA’s one stays intact, while cartB’s is updated. - val promoUpdated = promotionsApi(promo.id).update { - val payload = - PromotionPayloadBuilder.build(Promotion.Auto, - PromoOfferBuilder.CartPercentOff(percentOffUpdated), - PromoQualifierBuilder.CartAny) - UpdatePromotion( + val promoUpdated = promotionsApi(promo.id) + .update { + val payload = + PromotionPayloadBuilder.build(Promotion.Auto, + PromoOfferBuilder.CartPercentOff(percentOffUpdated), + PromoQualifierBuilder.CartAny) + UpdatePromotion( applyType = payload.applyType, attributes = payload.attributes, - discounts = - Seq(UpdatePromoDiscount(promo.discounts.head.id, payload.discounts.head.attributes))) - }.as[PromotionResponse.Root] + discounts = Seq(UpdatePromoDiscount(promo.discounts.head.id, payload.discounts.head.attributes)) + ) + } + .as[PromotionResponse.Root] val orderA2 = ordersApi(orderA.referenceNumber).get().asTheResult[OrderResponse] val cartB2 = cartsApi(cartB.referenceNumber).get().asTheResult[CartResponse] @@ -177,9 +175,8 @@ class AutoPromotionsIntegrationTest val promo = promotionsApi .create( - PromotionPayloadBuilder.build(Promotion.Auto, - PromoOfferBuilder.CartPercentOff(37), - PromoQualifierBuilder.CartAny)) + PromotionPayloadBuilder + .build(Promotion.Auto, PromoOfferBuilder.CartPercentOff(37), PromoQualifierBuilder.CartAny)) .as[PromotionResponse.Root] cartsApi(refNum).get.asTheResult[CartResponse].promotion mustBe 'defined @@ -188,9 +185,8 @@ class AutoPromotionsIntegrationTest "after emptying a cart, no auto-promos are left" in new ProductSku_ApiFixture { val promo = promotionsApi .create( - PromotionPayloadBuilder.build(Promotion.Auto, - PromoOfferBuilder.CartPercentOff(37), - PromoQualifierBuilder.CartAny)) + PromotionPayloadBuilder + .build(Promotion.Auto, PromoOfferBuilder.CartPercentOff(37), PromoQualifierBuilder.CartAny)) .as[PromotionResponse.Root] val customer = api_newCustomer() @@ -212,9 +208,8 @@ class AutoPromotionsIntegrationTest "archived auto-apply promos are not applied" in new ProductSku_ApiFixture { val promo = promotionsApi .create( - PromotionPayloadBuilder.build(Promotion.Auto, - PromoOfferBuilder.CartPercentOff(37), - PromoQualifierBuilder.CartAny)) + PromotionPayloadBuilder + .build(Promotion.Auto, PromoOfferBuilder.CartPercentOff(37), PromoQualifierBuilder.CartAny)) .as[PromotionResponse.Root] promotionsApi(promo.id).delete().mustBeOk() @@ -233,26 +228,25 @@ class AutoPromotionsIntegrationTest "promotions narrowed down to certain customer groups are applied only for them in" - { val DefaultPercentOff = 37 - def groupAndPromo( - tpe: GroupType): (GroupResponses.GroupResponse.Root, PromotionResponse.Root) = { + def groupAndPromo(tpe: GroupType): (GroupResponses.GroupResponse.Root, PromotionResponse.Root) = { val group = customerGroupsApi .create( - CustomerGroupPayload(name = faker.Lorem.sentence(), - clientState = JNull, - elasticRequest = JNull, - groupType = tpe)) + CustomerGroupPayload(name = faker.Lorem.sentence(), + clientState = JNull, + elasticRequest = JNull, + groupType = tpe)) .as[GroupResponses.GroupResponse.Root] val promo = promotionsApi .create( - PromotionPayloadBuilder.build( - Promotion.Auto, - PromoOfferBuilder.CartPercentOff(DefaultPercentOff), - PromoQualifierBuilder.CartAny, - extraAttrs = Map( - "customerGroupIds" → tv(List(group.id), - "tock673sjgmqbi5zlfx43o4px6jnxi7absotzjvxwir7jo2v") - ))) + PromotionPayloadBuilder.build( + Promotion.Auto, + PromoOfferBuilder.CartPercentOff(DefaultPercentOff), + PromoQualifierBuilder.CartAny, + extraAttrs = Map( + "customerGroupIds" → tv(List(group.id), "tock673sjgmqbi5zlfx43o4px6jnxi7absotzjvxwir7jo2v") + ) + )) .as[PromotionResponse.Root] (group, promo) @@ -308,9 +302,9 @@ class AutoPromotionsIntegrationTest promotionsApi .create( - PromotionPayloadBuilder.build(Promotion.Auto, - PromoOfferBuilder.CartPercentOff(otherPercentOff), - PromoQualifierBuilder.CartAny)) + PromotionPayloadBuilder.build(Promotion.Auto, + PromoOfferBuilder.CartPercentOff(otherPercentOff), + PromoQualifierBuilder.CartAny)) .as[PromotionResponse.Root] val customer = api_newCustomer() @@ -321,8 +315,7 @@ class AutoPromotionsIntegrationTest .add(Seq(UpdateLineItemsPayload(skuCode, 1))) .asTheResult[CartResponse] - percentOff(finalCart.promotion.value) must === ( - math.max(DefaultPercentOff, otherPercentOff)) + percentOff(finalCart.promotion.value) must === (math.max(DefaultPercentOff, otherPercentOff)) } } diff --git a/phoenix-scala/phoenix/test/integration/CartCreditCardPaymentsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CartCreditCardPaymentsIntegrationTest.scala index d214c41caa..b6e9b2ac49 100644 --- a/phoenix-scala/phoenix/test/integration/CartCreditCardPaymentsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CartCreditCardPaymentsIntegrationTest.scala @@ -98,12 +98,10 @@ class CartCreditCardPaymentsIntegrationTest extends CartPaymentsIntegrationTestB cc ← * <~ CreditCards.create(Factories.creditCard.copy(accountId = customer.accountId)) otherAccount ← * <~ Accounts.create(Account()) otherCustomer ← * <~ Users.create( - Factories.customer.copy(accountId = otherAccount.id, - email = Some("other.customer@email.com"))) + Factories.customer.copy(accountId = otherAccount.id, + email = Some("other.customer@email.com"))) _ ← * <~ CustomersData.create( - CustomerData(userId = otherCustomer.id, - accountId = otherAccount.id, - scope = Scope.current)) + CustomerData(userId = otherCustomer.id, accountId = otherAccount.id, scope = Scope.current)) otherCC ← * <~ CreditCards.create(Factories.creditCard.copy(accountId = otherAccount.id)) } yield (cc, otherCC)).gimme } diff --git a/phoenix-scala/phoenix/test/integration/CartGiftCardPaymentsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CartGiftCardPaymentsIntegrationTest.scala index 38f73f72eb..b7d24d667a 100644 --- a/phoenix-scala/phoenix/test/integration/CartGiftCardPaymentsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CartGiftCardPaymentsIntegrationTest.scala @@ -155,9 +155,8 @@ class CartGiftCardPaymentsIntegrationTest extends CartPaymentsIntegrationTestBas val giftCard = (for { reason ← * <~ Reasons.create(Factories.reason(storeAdmin.accountId)) origin ← * <~ GiftCardManuals.create( - GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) - giftCard ← * <~ GiftCards.create( - Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) + GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + giftCard ← * <~ GiftCards.create(Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) } yield giftCard).gimme } diff --git a/phoenix-scala/phoenix/test/integration/CartIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CartIntegrationTest.scala index f9e2201d94..c7d9491d26 100644 --- a/phoenix-scala/phoenix/test/integration/CartIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CartIntegrationTest.scala @@ -87,8 +87,8 @@ class CartIntegrationTest fullCart.paymentMethods.size must === (0) } - "calculates customer’s expenses considering in-store payments" in new StoreAdmin_Seed - with Customer_Seed with ProductSku_ApiFixture with Reason_Baked { + "calculates customer’s expenses considering in-store payments" in new StoreAdmin_Seed with Customer_Seed + with ProductSku_ApiFixture with Reason_Baked { val refNum = cartsApi .create(CreateCart(customerId = customer.accountId.some)) .as[CartResponse] @@ -115,8 +115,7 @@ class CartIntegrationTest val fullCart = cartsApi(refNum).get().asTheResult[CartResponse] - fullCart.totals.customersExpenses must === ( - fullCart.totals.total - giftCardAmount - storeCreditAmount) + fullCart.totals.customersExpenses must === (fullCart.totals.total - giftCardAmount - storeCreditAmount) } } @@ -135,8 +134,8 @@ class CartIntegrationTest sku.quantity must === (2) } - "adding a SKU with no product should return an error" in new OrderShippingMethodFixture - with Sku_Raw with EmptyCartWithShipAddress_Baked with PaymentStateFixture { + "adding a SKU with no product should return an error" in new OrderShippingMethodFixture with Sku_Raw + with EmptyCartWithShipAddress_Baked with PaymentStateFixture { val payload = Seq(UpdateLineItemsPayload(simpleSku.code, 1)) cartsApi(cart.refNum).lineItems .add(Seq(UpdateLineItemsPayload(simpleSku.code, 1))) @@ -164,24 +163,24 @@ class CartIntegrationTest val addPayload = Seq(UpdateLineItemsPayload("SKU-YAX", 2)) val attributes = LineItemAttributes( - GiftCardLineItemAttributes(senderName = "senderName", - recipientName = "recipientName", - recipientEmail = "example@example.com", - message = "message".some).some).some + GiftCardLineItemAttributes(senderName = "senderName", + recipientName = "recipientName", + recipientEmail = "example@example.com", + message = "message".some).some).some val attributes2 = LineItemAttributes( - GiftCardLineItemAttributes(senderName = "senderName2", - recipientName = "recipientName2", - recipientEmail = "example2@example.com", - message = "message2".some).some).some + GiftCardLineItemAttributes(senderName = "senderName2", + recipientName = "recipientName2", + recipientEmail = "example2@example.com", + message = "message2".some).some).some def addGiftCardPayload(sku: String) = Seq(UpdateLineItemsPayload(sku, 2, attributes), UpdateLineItemsPayload(sku, 1, attributes2)) def removeGiftCardPayload(sku: String) = Seq(UpdateLineItemsPayload(sku, -2, attributes)) - "should successfully add line items" in new OrderShippingMethodFixture - with EmptyCartWithShipAddress_Baked with PaymentStateFixture { + "should successfully add line items" in new OrderShippingMethodFixture with EmptyCartWithShipAddress_Baked + with PaymentStateFixture { val sku = cartsApi(cart.refNum).lineItems .update(addPayload) .asTheResult[CartResponse] @@ -201,8 +200,7 @@ class CartIntegrationTest updatedSku.quantity must === (6) } - "should successfully add a gift card line item" in new Customer_Seed - with ProductSku_ApiFixture { + "should successfully add a gift card line item" in new Customer_Seed with ProductSku_ApiFixture { val refNum = cartsApi.create(CreateCart(email = customer.email)).as[CartResponse].referenceNumber @@ -212,12 +210,12 @@ class CartIntegrationTest .lineItems .skus .map(sku ⇒ (sku.sku, sku.quantity, sku.attributes)) must contain theSameElementsAs Seq( - (skuCode, 1, attributes2), - (skuCode, 2, attributes)) + (skuCode, 1, attributes2), + (skuCode, 2, attributes)) } - "adding a SKU with no product should return an error" in new OrderShippingMethodFixture - with Sku_Raw with EmptyCartWithShipAddress_Baked with PaymentStateFixture { + "adding a SKU with no product should return an error" in new OrderShippingMethodFixture with Sku_Raw + with EmptyCartWithShipAddress_Baked with PaymentStateFixture { cartsApi(cart.refNum).lineItems .update(Seq(UpdateLineItemsPayload(simpleSku.code, 1))) .mustFailWith400(SkuWithNoProductAdded(cart.refNum, simpleSku.code)) @@ -236,20 +234,18 @@ class CartIntegrationTest sku.quantity must === (1) } - "should successfully remove gift card line item" in new Customer_Seed - with ProductSku_ApiFixture { + "should successfully remove gift card line item" in new Customer_Seed with ProductSku_ApiFixture { val refNum = cartsApi.create(CreateCart(email = customer.email)).as[CartResponse].referenceNumber val regSkus = cartsApi(refNum).lineItems.update(addGiftCardPayload(skuCode)).mustBeOk() val skus = cartsApi(refNum).lineItems - .update(removeGiftCardPayload(skuCode)) - .asTheResult[CartResponse] - .lineItems - .skus - .map(sku ⇒ (sku.sku, sku.quantity, sku.attributes)) must === ( - Seq((skuCode, 1, attributes2))) + .update(removeGiftCardPayload(skuCode)) + .asTheResult[CartResponse] + .lineItems + .skus + .map(sku ⇒ (sku.sku, sku.quantity, sku.attributes)) must === (Seq((skuCode, 1, attributes2))) } "removing too many of an item should remove all of that item" in new OrderShippingMethodFixture @@ -284,8 +280,7 @@ class CartIntegrationTest "copying a shipping address from a customer's book" - { - "succeeds if the address exists in their book" in new EmptyCustomerCart_Baked - with CustomerAddress_Raw { + "succeeds if the address exists in their book" in new EmptyCustomerCart_Baked with CustomerAddress_Raw { cartsApi(cart.refNum).shippingAddress.updateFromAddress(address.id).mustBeOk() val shippingAddressUpd = OrderShippingAddresses.findByOrderRef(cart.refNum).one.gimme.value @@ -316,12 +311,12 @@ class CartIntegrationTest "succeeds when the address exists" in new EmptyCartWithShipAddress_Baked { val newAddress = Addresses .create( - Factories.address.copy(accountId = customer.accountId, - isDefaultShipping = false, - name = "Paul P", - address1 = "29918 Kenloch Dr", - city = "Farmington Hills", - regionId = 4177)) + Factories.address.copy(accountId = customer.accountId, + isDefaultShipping = false, + name = "Paul P", + address1 = "29918 Kenloch Dr", + city = "Farmington Hills", + regionId = 4177)) .gimme cartsApi(cart.refNum).shippingAddress.updateFromAddress(newAddress.id).mustBeOk() @@ -341,8 +336,7 @@ class CartIntegrationTest .updateFromAddress(101) .mustFailWith404(NotFoundFailure404(Address, 101)) - OrderShippingAddresses.findByOrderRef(cart.refNum).one.gimme.value.cordRef must === ( - cart.refNum) + OrderShippingAddresses.findByOrderRef(cart.refNum).one.gimme.value.cordRef must === (cart.refNum) } } } @@ -464,7 +458,7 @@ class CartIntegrationTest trait ShippingMethodFixture extends EmptyCartWithShipAddress_Baked { val lowConditions: QueryStatement = parse( - """ + """ | { | "comparison": "and", | "conditions": [{ @@ -474,7 +468,7 @@ class CartIntegrationTest """.stripMargin).extract[QueryStatement] val highConditions: QueryStatement = parse( - """ + """ | { | "comparison": "and", | "conditions": [{ @@ -496,7 +490,7 @@ class CartIntegrationTest lowShippingMethod ← * <~ ShippingMethods.create(lowSm) inactiveShippingMethod ← * <~ ShippingMethods.create( - lowShippingMethod.copy(isActive = false, code = "INACTIVE")) + lowShippingMethod.copy(isActive = false, code = "INACTIVE")) highShippingMethod ← * <~ ShippingMethods.create(highSm) _ ← * <~ CartTotaler.saveTotals(cart) @@ -507,11 +501,9 @@ class CartIntegrationTest trait OrderShippingMethodFixture extends ShippingMethodFixture { val shipment = (for { orderShipMethod ← * <~ OrderShippingMethods.create( - OrderShippingMethod.build(cordRef = cart.refNum, - method = highShippingMethod)) + OrderShippingMethod.build(cordRef = cart.refNum, method = highShippingMethod)) shipment ← * <~ Shipments.create( - Shipment(cordRef = cart.refNum, - orderShippingMethodId = Some(orderShipMethod.id))) + Shipment(cordRef = cart.refNum, orderShippingMethodId = Some(orderShipMethod.id))) } yield shipment).gimme } @@ -520,9 +512,9 @@ class CartIntegrationTest val (cc, op, ccc) = (for { cc ← * <~ CreditCards.create(Factories.creditCard.copy(accountId = customer.accountId)) op ← * <~ OrderPayments.create( - Factories.orderPayment.copy(cordRef = cart.refNum, paymentMethodId = cc.id)) + Factories.orderPayment.copy(cordRef = cart.refNum, paymentMethodId = cc.id)) ccc ← * <~ CreditCardCharges.create( - Factories.creditCardCharge.copy(creditCardId = cc.id, orderPaymentId = op.id)) + Factories.creditCardCharge.copy(creditCardId = cc.id, orderPaymentId = op.id)) } yield (cc, op, ccc)).gimme } diff --git a/phoenix-scala/phoenix/test/integration/CartPaymentsIntegrationTestBase.scala b/phoenix-scala/phoenix/test/integration/CartPaymentsIntegrationTestBase.scala index 64327523ca..78e071900b 100644 --- a/phoenix-scala/phoenix/test/integration/CartPaymentsIntegrationTestBase.scala +++ b/phoenix-scala/phoenix/test/integration/CartPaymentsIntegrationTestBase.scala @@ -13,9 +13,8 @@ trait CartPaymentsIntegrationTestBase with TestActivityContext.AdminAC with BakedFixtures { - def paymentsFor(cart: Cart, pmt: PaymentMethod.Type): Seq[OrderPayment] = { + def paymentsFor(cart: Cart, pmt: PaymentMethod.Type): Seq[OrderPayment] = OrderPayments.filter(_.cordRef === cart.refNum).byType(pmt).gimme - } def creditCardPayments(cart: Cart): Seq[OrderPayment] = paymentsFor(cart, PaymentMethod.CreditCard) diff --git a/phoenix-scala/phoenix/test/integration/CartStoreCreditPaymentsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CartStoreCreditPaymentsIntegrationTest.scala index 4c9ac8ed1e..f93fcf8679 100644 --- a/phoenix-scala/phoenix/test/integration/CartStoreCreditPaymentsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CartStoreCreditPaymentsIntegrationTest.scala @@ -59,8 +59,8 @@ class CartStoreCreditPaymentsIntegrationTest extends CartPaymentsIntegrationTest val payments = storeCreditPayments(cart) payments.map(_.paymentMethodId) must contain noneOf ( - storeCredits(1 - 1).id, - storeCredits(2 - 1).id + storeCredits(1 - 1).id, + storeCredits(2 - 1).id ) payments must have size 2 } diff --git a/phoenix-scala/phoenix/test/integration/CartValidatorIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CartValidatorIntegrationTest.scala index 6a8fcfb243..bee3a6181f 100644 --- a/phoenix-scala/phoenix/test/integration/CartValidatorIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CartValidatorIntegrationTest.scala @@ -55,8 +55,7 @@ class CartValidatorIntegrationTest "/v1/carts/:refNum/shipping-address" in new ShippingAddressFixture { val api = cartsApi(refNum).shippingAddress - checkResponse(api.create(CreateAddressPayload("a", 1, "b", None, "c", "11111")), - expectedWarnings) + checkResponse(api.create(CreateAddressPayload("a", 1, "b", None, "c", "11111")), expectedWarnings) checkResponse(api.update(UpdateAddressPayload(name = "z".some)), expectedWarnings) @@ -147,8 +146,7 @@ class CartValidatorIntegrationTest trait ShippingMethodFixture extends EmptyCustomerCart_Baked { val (shipMethod) = (for { - address ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, regionId = 4129)) + address ← * <~ Addresses.create(Factories.address.copy(accountId = customer.accountId, regionId = 4129)) _ ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) shipMethod ← * <~ ShippingMethods.create(Factories.shippingMethods.head) } yield shipMethod).gimme @@ -160,30 +158,22 @@ class CartValidatorIntegrationTest val expectedWarnings = Seq(EmptyCart(refNum), NoShipMethod(refNum)) } - trait GiftCardFixture - extends ExpectedWarningsForPayment - with EmptyCustomerCart_Baked - with Reason_Baked { + trait GiftCardFixture extends ExpectedWarningsForPayment with EmptyCustomerCart_Baked with Reason_Baked { val giftCard = (for { origin ← * <~ GiftCardManuals.create( - GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) - giftCard ← * <~ GiftCards.create( - Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) + GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + giftCard ← * <~ GiftCards.create(Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) } yield giftCard).gimme val refNum = cart.refNum } - trait StoreCreditFixture - extends ExpectedWarningsForPayment - with EmptyCustomerCart_Baked - with Reason_Baked { + trait StoreCreditFixture extends ExpectedWarningsForPayment with EmptyCustomerCart_Baked with Reason_Baked { (for { manual ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) _ ← * <~ StoreCredits.create( - Factories.storeCredit.copy(state = StoreCredit.Active, - accountId = customer.accountId, - originId = manual.id)) + Factories.storeCredit + .copy(state = StoreCredit.Active, accountId = customer.accountId, originId = manual.id)) } yield {}).gimme val refNum = cart.refNum } @@ -206,15 +196,13 @@ class CartValidatorIntegrationTest product ← * <~ Mvp.insertProduct(productCtx.id, Factories.products.head) sku ← * <~ Skus.mustFindById404(product.skuId) manual ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) _ ← * <~ StoreCredits.create( - Factories.storeCredit.copy(state = StoreCredit.Active, - accountId = customer.accountId, - originId = manual.id)) + Factories.storeCredit + .copy(state = StoreCredit.Active, accountId = customer.accountId, originId = manual.id)) origin ← * <~ GiftCardManuals.create( - GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) - giftCard ← * <~ GiftCards.create( - Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) + GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + giftCard ← * <~ GiftCards.create(Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) } yield (cart.refNum, sku, cc, giftCard)).gimme } diff --git a/phoenix-scala/phoenix/test/integration/CategoryIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CategoryIntegrationTest.scala index 3e9f839a6f..693a90d858 100644 --- a/phoenix-scala/phoenix/test/integration/CategoryIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CategoryIntegrationTest.scala @@ -34,8 +34,7 @@ class CategoryIntegrationTest val updatedShadow: JObject = (newAttribute → ("type" → "string")) val content = categoriesApi(category.form.id) - .update(UpdateFullCategory(UpdateCategoryForm(updatedForm), - UpdateCategoryShadow(updatedShadow))) + .update(UpdateFullCategory(UpdateCategoryForm(updatedForm), UpdateCategoryShadow(updatedShadow))) .as[FullCategoryResponse.Root] val formValues: List[Json] = content.form.attributes.asInstanceOf[JObject].children @@ -55,8 +54,7 @@ class CategoryIntegrationTest val updatedShadow: JObject = (newAttribute → ("type" → "string")) val content = categoriesApi - .create(CreateFullCategory(CreateCategoryForm(updatedForm), - CreateCategoryShadow(updatedShadow))) + .create(CreateFullCategory(CreateCategoryForm(updatedForm), CreateCategoryShadow(updatedShadow))) .as[FullCategoryResponse.Root] val formValues: List[Json] = content.form.attributes.asInstanceOf[JObject].children @@ -110,10 +108,10 @@ class CategoryIntegrationTest val testShadowAttributes: JObject = ("attr1" → ("type" → "string")) val category = CategoryManager - .createCategory(storeAdmin, - CreateFullCategory(CreateCategoryForm(testAttributes), - CreateCategoryShadow(testShadowAttributes)), - ctx.name) + .createCategory( + storeAdmin, + CreateFullCategory(CreateCategoryForm(testAttributes), CreateCategoryShadow(testShadowAttributes)), + ctx.name) .gimme } } diff --git a/phoenix-scala/phoenix/test/integration/CheckoutIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CheckoutIntegrationTest.scala index 1f405ac342..4828afae41 100644 --- a/phoenix-scala/phoenix/test/integration/CheckoutIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CheckoutIntegrationTest.scala @@ -54,9 +54,10 @@ class CheckoutIntegrationTest val lineItemToUpdate = order.lineItems.skus.head val updatedOrder = cartsApi(order.referenceNumber) .updateCartLineItem( - Seq(UpdateOrderLineItemsPayload(lineItemToUpdate.state, - attributes, - lineItemToUpdate.referenceNumbers.head))) + Seq( + UpdateOrderLineItemsPayload(lineItemToUpdate.state, + attributes, + lineItemToUpdate.referenceNumbers.head))) .as[OrderResponse] updatedOrder.lineItems.skus @@ -81,12 +82,12 @@ class CheckoutIntegrationTest .checkout(CheckoutCart(items = List(UpdateLineItemsPayload(skuCode, 1)))) .as[OrderResponse] order.lineItems.skus.onlyElement must have( - 'sku (skuCode), - 'quantity (1) + 'sku (skuCode), + 'quantity (1) ) order.billingCreditCardInfo.value must have( - 'id (creditCard.id), - 'type (PaymentMethod.CreditCard) + 'id (creditCard.id), + 'type (PaymentMethod.CreditCard) ) // FIXME: Add Address#id to OrderShippingAddress? @michalrus @@ -94,13 +95,12 @@ class CheckoutIntegrationTest val orderShippingAddress = OrderShippingAddresses.findOneById(order.shippingAddress.id).gimme.value val expectedAddressResponse = AddressResponse.buildFromOrder( - orderShippingAddress, - order.shippingAddress.region + orderShippingAddress, + order.shippingAddress.region ) // Compare all significant fields. - expectedAddressResponse must === ( - address.copy(id = expectedAddressResponse.id, isDefault = None)) + expectedAddressResponse must === (address.copy(id = expectedAddressResponse.id, isDefault = None)) order.shippingAddress must === (expectedAddressResponse) order.shippingMethod.id must === (shipMethod.id) } @@ -122,8 +122,8 @@ class CheckoutIntegrationTest .lineItems .skus .onlyElement must have( - 'sku (otherSkuCode), - 'quantity (2) + 'sku (otherSkuCode), + 'quantity (2) ) storefrontCartsApi @@ -132,13 +132,13 @@ class CheckoutIntegrationTest .lineItems .skus .onlyElement must have( - 'sku (skuCode), - 'quantity (1) + 'sku (skuCode), + 'quantity (1) ) storefrontCartsApi.get().as[CartResponse].lineItems.skus.onlyElement must have( - 'sku (otherSkuCode), - 'quantity (2) + 'sku (otherSkuCode), + 'quantity (2) ) } } @@ -238,26 +238,28 @@ class CheckoutIntegrationTest trait OneClickCheckoutFixture extends Fixture { val creditCard = { val cc = Factories.creditCard - api_newCreditCard(customer.id, - CreateCreditCardFromTokenPayload( - token = "whatever", - lastFour = cc.lastFour, - expYear = cc.expYear, - expMonth = cc.expMonth, - brand = cc.brand, - holderName = cc.holderName, - billingAddress = CreateAddressPayload( - name = cc.address.name, - regionId = cc.address.regionId, - address1 = cc.address.address1, - address2 = cc.address.address2, - city = cc.address.city, - zip = cc.address.zip, - isDefault = false, - phoneNumber = cc.address.phoneNumber - ), - addressIsNew = true - )) + api_newCreditCard( + customer.id, + CreateCreditCardFromTokenPayload( + token = "whatever", + lastFour = cc.lastFour, + expYear = cc.expYear, + expMonth = cc.expMonth, + brand = cc.brand, + holderName = cc.holderName, + billingAddress = CreateAddressPayload( + name = cc.address.name, + regionId = cc.address.regionId, + address1 = cc.address.address1, + address2 = cc.address.address2, + city = cc.address.city, + zip = cc.address.zip, + isDefault = false, + phoneNumber = cc.address.phoneNumber + ), + addressIsNew = true + ) + ) } } diff --git a/phoenix-scala/phoenix/test/integration/CouponsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CouponsIntegrationTest.scala index 794e3a4e70..c527bc5a18 100644 --- a/phoenix-scala/phoenix/test/integration/CouponsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CouponsIntegrationTest.scala @@ -38,8 +38,7 @@ class CouponsIntegrationTest coupon } - "created coupon should always be active" in new StoreAdmin_Seed - with Coupon_TotalQualifier_PercentOff { + "created coupon should always be active" in new StoreAdmin_Seed with Coupon_TotalQualifier_PercentOff { override def couponActiveFrom = Instant.now.plus(10, DAYS) override def couponActiveTo = Some(Instant.now.plus(20, DAYS)) @@ -149,7 +148,7 @@ class CouponsIntegrationTest .add(Seq(UpdateLineItemsPayload(skuCode, 2, randomGiftCardLineItemAttributes))) val message = s"qualifier orderAnyQualifier rejected order with refNum=$cartRef, " + - "reason: Items in cart are not eligible for discount" + "reason: Items in cart are not eligible for discount" cartsApi(cartRef).coupon.add(couponCode).mustFailWithMessage(message) } @@ -158,7 +157,7 @@ class CouponsIntegrationTest override def qualifiedSubtotal: Long = 4000 val message = s"qualifier orderTotalAmountQualifier rejected order with refNum=$cartRef, " + - s"reason: Order subtotal is less than $qualifiedSubtotal" + s"reason: Order subtotal is less than $qualifiedSubtotal" cartsApi(cartRef).coupon.add(couponCode).mustFailWithMessage(message) } @@ -167,7 +166,7 @@ class CouponsIntegrationTest override def qualifiedNumItems: Int = 2 val message = s"qualifier orderNumUnitsQualifier rejected order with refNum=$cartRef, " + - s"reason: Order unit count is less than $qualifiedNumItems" + s"reason: Order unit count is less than $qualifiedNumItems" cartsApi(cartRef).coupon.add(couponCode).mustFailWithMessage(message) } } diff --git a/phoenix-scala/phoenix/test/integration/CreditCardsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CreditCardsIntegrationTest.scala index b0533afea0..d9e2d3ba2f 100644 --- a/phoenix-scala/phoenix/test/integration/CreditCardsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CreditCardsIntegrationTest.scala @@ -35,9 +35,8 @@ class CreditCardsIntegrationTest with BeforeAndAfterEach with CreditCardsFixture { - override def beforeEach(): Unit = { + override def beforeEach(): Unit = initStripeApiMock(stripeWrapperMock) - } "POST /v1/customers/:id/payment-methods/credit-cards (admin auth)" - { "creates a new credit card" in { @@ -48,22 +47,24 @@ class CreditCardsIntegrationTest val cc = CreditCards.result.gimme.onlyElement - val expected = CreditCard(id = 0, - gatewayCustomerId = stripeCustomer.getId, - gatewayCardId = stripeCard.getId, - accountId = customer.id, - address = BillingAddress(name = theAddress.name, - address1 = theAddress.address1, - address2 = theAddress.address2, - city = theAddress.city, - zip = theAddress.zip, - regionId = theAddress.regionId), - brand = "Mona Visa", - holderName = "Leo", - lastFour = "1234", - expMonth = 1, - expYear = expYear, - createdAt = cc.createdAt) + val expected = CreditCard( + id = 0, + gatewayCustomerId = stripeCustomer.getId, + gatewayCardId = stripeCard.getId, + accountId = customer.id, + address = BillingAddress(name = theAddress.name, + address1 = theAddress.address1, + address2 = theAddress.address2, + city = theAddress.city, + zip = theAddress.zip, + regionId = theAddress.regionId), + brand = "Mona Visa", + holderName = "Leo", + lastFour = "1234", + expMonth = 1, + expYear = expYear, + createdAt = cc.createdAt + ) cc.copy(id = expected.id) must === (expected) @@ -111,7 +112,7 @@ class CreditCardsIntegrationTest .create(ccPayload.copy(addressIsNew = true)) .mustBeOk() Addresses.result.headOption.gimme.value.copy(id = theAddress.id) must === ( - theAddress.copy(accountId = accountId)) + theAddress.copy(accountId = accountId)) } "errors 404 if wrong customer.accountId" in { @@ -187,8 +188,8 @@ class CreditCardsIntegrationTest "GET /v1/my/payment-methods/credit-cards" - { "returns valid phone number" in withRandomCustomerAuth { implicit auth ⇒ val testPhoneNumber = "1234567890" - val payloadWithPhoneNumber = ccPayload.copy( - billingAddress = ccPayload.billingAddress.copy(phoneNumber = testPhoneNumber.some)) + val payloadWithPhoneNumber = + ccPayload.copy(billingAddress = ccPayload.billingAddress.copy(phoneNumber = testPhoneNumber.some)) storefrontPaymentsApi.creditCards.create(payloadWithPhoneNumber).mustBeOk() storefrontPaymentsApi.creditCards @@ -208,22 +209,24 @@ class CreditCardsIntegrationTest val cc: CreditCard = CreditCards.result.gimme.onlyElement - val expected = CreditCard(id = 0, - gatewayCustomerId = stripeCustomer.getId, - accountId = auth.customerId, - address = BillingAddress(name = theAddress.name, - address1 = theAddress.address1, - address2 = theAddress.address2, - city = theAddress.city, - zip = theAddress.zip, - regionId = theAddress.regionId), - holderName = "Leo", - brand = "Mona Visa", - lastFour = "1234", - expMonth = 1, - expYear = expYear, - gatewayCardId = stripeCard.getId, - createdAt = cc.createdAt) + val expected = CreditCard( + id = 0, + gatewayCustomerId = stripeCustomer.getId, + accountId = auth.customerId, + address = BillingAddress(name = theAddress.name, + address1 = theAddress.address1, + address2 = theAddress.address2, + city = theAddress.city, + zip = theAddress.zip, + regionId = theAddress.regionId), + holderName = "Leo", + brand = "Mona Visa", + lastFour = "1234", + expMonth = 1, + expYear = expYear, + gatewayCardId = stripeCard.getId, + createdAt = cc.createdAt + ) cc.copy(id = expected.id) must === (expected) @@ -262,7 +265,7 @@ class CreditCardsIntegrationTest "creates address if it's new" in withRandomCustomerAuth { implicit auth ⇒ storefrontPaymentsApi.creditCards.create(ccPayload.copy(addressIsNew = true)).mustBeOk() Addresses.result.headOption.gimme.value.copy(id = theAddress.id) must === ( - theAddress.copy(accountId = auth.customerId)) + theAddress.copy(accountId = auth.customerId)) } "errors 400 if wrong credit card token" in withRandomCustomerAuth { implicit auth ⇒ diff --git a/phoenix-scala/phoenix/test/integration/CustomerGroupIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CustomerGroupIntegrationTest.scala index 72b64f5f8d..15b8f2e4da 100644 --- a/phoenix-scala/phoenix/test/integration/CustomerGroupIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CustomerGroupIntegrationTest.scala @@ -6,7 +6,7 @@ import org.scalatest.mockito.MockitoSugar import phoenix.models.customer.CustomerGroup._ import phoenix.models.customer._ import phoenix.payloads.CustomerGroupPayloads.CustomerGroupPayload -import phoenix.responses.GroupResponses.GroupResponse.{Root, build} +import phoenix.responses.GroupResponses.GroupResponse.{build, Root} import phoenix.utils.seeds.Factories import testutils._ import testutils.apis.PhoenixAdminApi @@ -38,13 +38,15 @@ class CustomerGroupIntegrationTest "successfully creates customer group and link to template" in new Fixture { val scopeN = "1" - val payload = CustomerGroupPayload(name = "Group number one", - clientState = JObject(), - elasticRequest = JObject(), - customersCount = 1, - templateId = groupTemplate.id.some, - scope = scopeN.some, - groupType = Dynamic) + val payload = CustomerGroupPayload( + name = "Group number one", + clientState = JObject(), + elasticRequest = JObject(), + customersCount = 1, + templateId = groupTemplate.id.some, + scope = scopeN.some, + groupType = Dynamic + ) val root = customerGroupsApi.create(payload).as[Root] val created = CustomerGroups.mustFindById400(root.id).gimme @@ -70,7 +72,7 @@ class CustomerGroupIntegrationTest val root = customerGroupsApi.create(payload).as[Root] root.elasticRequest must !==(JObject()) ((((root.elasticRequest \ "query" \ "bool" \ "filter")(0) \ "bool" \ "must")(0) \ "term" \ "groups")) must === ( - JInt(root.id)) + JInt(root.id)) } "fail to create customer group with nonexistnet tempalte id" in new Fixture { diff --git a/phoenix-scala/phoenix/test/integration/CustomerGroupMembersIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CustomerGroupMembersIntegrationTest.scala index 8c911e0383..17a632165a 100644 --- a/phoenix-scala/phoenix/test/integration/CustomerGroupMembersIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CustomerGroupMembersIntegrationTest.scala @@ -85,8 +85,7 @@ class CustomerGroupMembersIntegrationTest (updatedMemberships.contains(group3.id)) must === (true) } - withClue( - s"Group ${groupDynamic.id} is dynamic and must not be deleted from group member list: ") { + withClue(s"Group ${groupDynamic.id} is dynamic and must not be deleted from group member list: ") { (updatedMemberships.contains(groupDynamic.id)) must === (true) } } @@ -139,9 +138,10 @@ class CustomerGroupMembersIntegrationTest "400 if payload contains same ids for addition and deletion" in new FixtureForCustomerGroups { customerGroupsMembersApi(group1.id) .syncCustomers(CustomerGroupMemberSyncPayload(Seq(account2.id), Seq(account2.id))) - .mustFailWith400(CustomerGroupMemberPayloadContainsSameIdsInBothSections(group1.id, - Set(account2.id), - Set(account2.id))) + .mustFailWith400( + CustomerGroupMemberPayloadContainsSameIdsInBothSections(group1.id, + Set(account2.id), + Set(account2.id))) } } @@ -155,25 +155,24 @@ class CustomerGroupMembersIntegrationTest account1 ← * <~ Accounts.create(Account()) user1 ← * <~ Users.create(Factories.customer.copy(accountId = account1.id)) custData1 ← * <~ CustomersData.create( - CustomerData(userId = user1.id, accountId = account1.id, scope = scope)) + CustomerData(userId = user1.id, accountId = account1.id, scope = scope)) account2 ← * <~ Accounts.create(Account()) user2 ← * <~ Users.create(Factories.customer.copy(accountId = account2.id)) custData2 ← * <~ CustomersData.create( - CustomerData(userId = user2.id, accountId = account2.id, scope = scope)) + CustomerData(userId = user2.id, accountId = account2.id, scope = scope)) account3 ← * <~ Accounts.create(Account()) user3 ← * <~ Users.create(Factories.customer.copy(accountId = account3.id)) custData3 ← * <~ CustomersData.create( - CustomerData(userId = user3.id, accountId = account3.id, scope = scope)) + CustomerData(userId = user3.id, accountId = account3.id, scope = scope)) _ ← * <~ CustomerGroupMembers.create( - CustomerGroupMember(groupId = group.id, customerDataId = custData1.id)) + CustomerGroupMember(groupId = group.id, customerDataId = custData1.id)) _ ← * <~ CustomerGroupMembers.create( - CustomerGroupMember(groupId = group.id, customerDataId = custData2.id)) + CustomerGroupMember(groupId = group.id, customerDataId = custData2.id)) - } yield - (group, account1, custData1, account2, custData2, account3, custData3, manualGroup)).gimmeTxn + } yield (group, account1, custData1, account2, custData2, account3, custData3, manualGroup)).gimmeTxn } trait FixtureForCustomerGroups extends StoreAdmin_Seed { @@ -197,24 +196,24 @@ class CustomerGroupMembersIntegrationTest account ← * <~ Accounts.create(Account()) user ← * <~ Users.create(Factories.customer.copy(accountId = account.id)) custData ← * <~ CustomersData.create( - CustomerData(userId = user.id, accountId = account.id, scope = scope)) + CustomerData(userId = user.id, accountId = account.id, scope = scope)) account2 ← * <~ Accounts.create(Account()) user2 ← * <~ Users.create(Factories.customer.copy(accountId = account2.id)) custData2 ← * <~ CustomersData.create( - CustomerData(userId = user2.id, accountId = account2.id, scope = scope)) + CustomerData(userId = user2.id, accountId = account2.id, scope = scope)) account3 ← * <~ Accounts.create(Account()) user3 ← * <~ Users.create(Factories.customer.copy(accountId = account3.id)) custData3 ← * <~ CustomersData.create( - CustomerData(userId = user3.id, accountId = account3.id, scope = scope)) + CustomerData(userId = user3.id, accountId = account3.id, scope = scope)) _ ← * <~ CustomerGroupMembers.create( - CustomerGroupMember(groupId = group1.id, customerDataId = custData.id)) + CustomerGroupMember(groupId = group1.id, customerDataId = custData.id)) _ ← * <~ CustomerGroupMembers.create( - CustomerGroupMember(groupId = group2.id, customerDataId = custData.id)) + CustomerGroupMember(groupId = group2.id, customerDataId = custData.id)) _ ← * <~ CustomerGroupMembers.create( - CustomerGroupMember(groupId = groupDynamic.id, customerDataId = custData.id)) + CustomerGroupMember(groupId = groupDynamic.id, customerDataId = custData.id)) } yield (group1, group2, diff --git a/phoenix-scala/phoenix/test/integration/CustomerGroupTemplateIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CustomerGroupTemplateIntegrationTest.scala index a8e8208334..cddc00e63c 100644 --- a/phoenix-scala/phoenix/test/integration/CustomerGroupTemplateIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CustomerGroupTemplateIntegrationTest.scala @@ -24,13 +24,15 @@ class CustomerGroupTemplateIntegrationTest "sends unused templates only when templates are not used" in new Fixture { val scopeN = "1" - val payload = CustomerGroupPayload(name = "Group number one", - clientState = JObject(), - elasticRequest = JObject(), - customersCount = 1, - templateId = groupTemplates.head.id.some, - scope = scopeN.some, - groupType = Template) + val payload = CustomerGroupPayload( + name = "Group number one", + clientState = JObject(), + elasticRequest = JObject(), + customersCount = 1, + templateId = groupTemplates.head.id.some, + scope = scopeN.some, + groupType = Template + ) val root = customerGroupsApi.create(payload).as[Root] diff --git a/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala index 1af862b448..6c8aa954f9 100644 --- a/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala @@ -105,7 +105,7 @@ class CustomerIntegrationTest Addresses.filter(_.id === address.id).map(_.isDefaultShipping).update(false).gimme customersApi(customer.accountId).get().as[Root] must === ( - CustomerResponse.build(customer, customerData)) + CustomerResponse.build(customer, customerData)) } "customer info shows valid billingRegion" in new CreditCardFixture { @@ -129,17 +129,14 @@ class CustomerIntegrationTest val defaultPhoneNumber: String = "1111111111" val (customer, customerData, region) = (for { - account ← * <~ Accounts.create(Account()) - customer ← * <~ Users.create( - Factories.customer.copy(accountId = account.id, phoneNumber = None)) + account ← * <~ Accounts.create(Account()) + customer ← * <~ Users.create(Factories.customer.copy(accountId = account.id, phoneNumber = None)) customerData ← * <~ CustomersData.create( - CustomerData(accountId = account.id, - userId = customer.id, - scope = Scope.current)) + CustomerData(accountId = account.id, userId = customer.id, scope = Scope.current)) address ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, - isDefaultShipping = true, - phoneNumber = defaultPhoneNumber.some)) + Factories.address.copy(accountId = customer.accountId, + isDefaultShipping = true, + phoneNumber = defaultPhoneNumber.some)) region ← * <~ Regions.findOneById(address.regionId) } yield (customer, customerData, region)).gimme @@ -164,39 +161,32 @@ class CustomerIntegrationTest } val (customer, region, shipments) = (for { - account ← * <~ Accounts.create(Account()) - customer ← * <~ Users.create( - Factories.customer.copy(accountId = account.id, phoneNumber = None)) + account ← * <~ Accounts.create(Account()) + customer ← * <~ Users.create(Factories.customer.copy(accountId = account.id, phoneNumber = None)) custData ← * <~ CustomersData.create( - CustomerData(userId = customer.id, - accountId = account.id, - scope = Scope.current)) + CustomerData(userId = customer.id, accountId = account.id, scope = Scope.current)) address ← * <~ Addresses.create(defaultAddress.copy(accountId = customer.accountId)) region ← * <~ Regions.findOneById(address.regionId) cart1 ← * <~ Carts.create( - Cart(referenceNumber = "ABC-1", - scope = Scope.current, - accountId = customer.accountId)) + Cart(referenceNumber = "ABC-1", scope = Scope.current, accountId = customer.accountId)) order1 ← * <~ Orders.createFromCart(cart1, None) order1 ← * <~ Orders.update(order1, order1.copy(state = Order.FulfillmentStarted)) order1 ← * <~ Orders.update(order1, order1.copy(state = Order.Shipped)) cart2 ← * <~ Carts.create( - Cart(referenceNumber = "ABC-2", - scope = Scope.current, - accountId = customer.accountId)) + Cart(referenceNumber = "ABC-2", scope = Scope.current, accountId = customer.accountId)) order2 ← * <~ Orders.createFromCart(cart2, None) order2 ← Orders.update(order2, order2.copy(state = Order.FulfillmentStarted)) order2 ← Orders.update(order2, order2.copy(state = Order.Shipped)) orders = Seq(order1, order2) addresses ← * <~ shippingAddresses(orders.zip(phoneNumbers)).map(a ⇒ - OrderShippingAddresses.create(a)) + OrderShippingAddresses.create(a)) shipments ← * <~ addresses.map( - address ⇒ - Shipments.create( - Factories.shipment.copy(cordRef = address.cordRef, - shippingAddressId = address.id.some, - orderShippingMethodId = None, - state = Shipped))) + address ⇒ + Shipments.create( + Factories.shipment.copy(cordRef = address.cordRef, + shippingAddressId = address.id.some, + orderShippingMethodId = None, + state = Shipped))) } yield (customer, region, shipments)).gimme def updateShipmentTime(s: Shipment, newTime: Instant ⇒ Instant): Unit = @@ -272,11 +262,11 @@ class CustomerIntegrationTest email = "newemail@example.org".some, phoneNumber = "555 555 55".some) (payload.name, payload.email, payload.phoneNumber) must !==( - (customer.name, customer.email, customer.phoneNumber)) + (customer.name, customer.email, customer.phoneNumber)) val updated: Root = customersApi(customer.accountId).update(payload).as[Root] (updated.name, updated.email, updated.phoneNumber) must === ( - (payload.name, payload.email, payload.phoneNumber)) + (payload.name, payload.email, payload.phoneNumber)) } "fails if email is already in use" in new Fixture { @@ -506,8 +496,7 @@ class CustomerIntegrationTest val numAddresses = Addresses.length.result.gimme numAddresses must === (1) - (newVersion.address.zip, newVersion.address.regionId) must === ( - (address.zip, address.regionId)) + (newVersion.address.zip, newVersion.address.regionId) must === ((address.zip, address.regionId)) } "creates a new address book entry if a full address was given" in new CreditCardFixture { @@ -528,10 +517,8 @@ class CustomerIntegrationTest val newAddress = addresses.last addresses must have size 2 - (newVersion.address.zip, newVersion.address.regionId) must === ( - ("54321", address.regionId + 1)) - (newVersion.address.zip, newVersion.address.regionId) must === ( - (newAddress.zip, newAddress.regionId)) + (newVersion.address.zip, newVersion.address.regionId) must === (("54321", address.regionId + 1)) + (newVersion.address.zip, newVersion.address.regionId) must === ((newAddress.zip, newAddress.regionId)) } } @@ -641,43 +628,36 @@ class CustomerIntegrationTest val (order, orderPayment, customer2, charge1, charge2) = (for { account ← * <~ Accounts.create(Account()) customer2 ← * <~ Users.create( - Factories.customer.copy(accountId = account.id, - email = "second@example.org".some, - name = "second".some)) + Factories.customer + .copy(accountId = account.id, email = "second@example.org".some, name = "second".some)) custData2 ← * <~ CustomersData.create( - CustomerData(userId = customer2.id, - accountId = account.id, - scope = Scope.current)) + CustomerData(userId = customer2.id, accountId = account.id, scope = Scope.current)) cart2 ← * <~ Carts.create( - Cart(accountId = customer2.accountId, - scope = Scope.current, - referenceNumber = "ABC-456")) + Cart(accountId = customer2.accountId, scope = Scope.current, referenceNumber = "ABC-456")) order ← * <~ Orders.createFromCart(cart, None) order2 ← * <~ Orders.createFromCart(cart2, None) orderPayment ← * <~ OrderPayments.create( - Factories.orderPayment.copy(cordRef = order.refNum, - paymentMethodId = creditCard.id, - amount = None)) + Factories.orderPayment + .copy(cordRef = order.refNum, paymentMethodId = creditCard.id, amount = None)) creditCardCharge1 ← * <~ CreditCardCharges.create( - CreditCardCharge( - creditCardId = creditCard.id, - orderPaymentId = orderPayment.id, - stripeChargeId = "asd1", - state = ExternalCharge.FullCapture, - amount = 100 - )) + CreditCardCharge( + creditCardId = creditCard.id, + orderPaymentId = orderPayment.id, + stripeChargeId = "asd1", + state = ExternalCharge.FullCapture, + amount = 100 + )) orderPayment2 ← * <~ OrderPayments.create( - Factories.orderPayment.copy(cordRef = order2.refNum, - paymentMethodId = creditCard.id, - amount = None)) + Factories.orderPayment + .copy(cordRef = order2.refNum, paymentMethodId = creditCard.id, amount = None)) creditCardCharge2 ← * <~ CreditCardCharges.create( - CreditCardCharge( - creditCardId = creditCard.id, - orderPaymentId = orderPayment2.id, - stripeChargeId = "asd2", - state = ExternalCharge.FullCapture, - amount = 1000000 - )) + CreditCardCharge( + creditCardId = creditCard.id, + orderPaymentId = orderPayment2.id, + stripeChargeId = "asd2", + state = ExternalCharge.FullCapture, + amount = 1000000 + )) order ← * <~ Orders.update(order, order.copy(state = Order.FulfillmentStarted)) order ← * <~ Orders.update(order, order.copy(state = Order.Shipped)) order2 ← * <~ Orders.update(order2, order2.copy(state = Order.FulfillmentStarted)) diff --git a/phoenix-scala/phoenix/test/integration/DbResultSequenceIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/DbResultSequenceIntegrationTest.scala index 42f64f2158..6e0e0ea5f1 100644 --- a/phoenix-scala/phoenix/test/integration/DbResultSequenceIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/DbResultSequenceIntegrationTest.scala @@ -42,10 +42,9 @@ class DbResultSequenceIntegrationTest extends IntegrationTestBase { val failures = cool.gimmeFailures val expectedFailure = DatabaseFailure( - "ERROR: duplicate key value violates unique constraint \"users_account_idx\"\n" + - s" Detail: Key (account_id)=(${account.id}) already exists.") - failures must === ( - NonEmptyList.fromList(List.fill[Failure](numTries - 1)(expectedFailure)).value) + "ERROR: duplicate key value violates unique constraint \"users_account_idx\"\n" + + s" Detail: Key (account_id)=(${account.id}) already exists.") + failures must === (NonEmptyList.fromList(List.fill[Failure](numTries - 1)(expectedFailure)).value) Users.gimme.onlyElement.accountId must === (account.id) } diff --git a/phoenix-scala/phoenix/test/integration/GenericTreeIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/GenericTreeIntegrationTest.scala index 33e143ec09..2e35d58fe4 100644 --- a/phoenix-scala/phoenix/test/integration/GenericTreeIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/GenericTreeIntegrationTest.scala @@ -11,10 +11,7 @@ import testutils._ import testutils.apis.PhoenixAdminApi import core.db._ -class GenericTreeIntegrationTest - extends IntegrationTestBase - with PhoenixAdminApi - with DefaultJwtAdminAuth { +class GenericTreeIntegrationTest extends IntegrationTestBase with PhoenixAdminApi with DefaultJwtAdminAuth { "GenericTreeIntegrationTest" - { "GET /v1/tree/default/test" - { @@ -115,8 +112,7 @@ class GenericTreeIntegrationTest val context = ObjectContexts.filter(_.name === "default").one.run.futureValue.get val testObjects = ObjectForms - .createAllReturningModels( - 0 to 2 map (index ⇒ ObjectForm(0, "testKind", s"key$index" → s"val$index"))) + .createAllReturningModels(0 to 2 map (index ⇒ ObjectForm(0, "testKind", s"key$index" → s"val$index"))) .gimme } @@ -128,12 +124,12 @@ class GenericTreeIntegrationTest (for { tree ← * <~ GenericTrees.create(GenericTree(0, "testTree", context.id)) testData = Seq( - GenericTreeNode(0, tree.id, 1, LTree("1"), testKind, testObjectId), - GenericTreeNode(0, tree.id, 2, LTree(List("1.2")), testKind, testObjectId), - GenericTreeNode(0, tree.id, 3, LTree(List("1.3")), testKind, testObjectId), - GenericTreeNode(0, tree.id, 4, LTree(List("1.3.4")), testKind, testObjectId), - GenericTreeNode(0, tree.id, 5, LTree(List("1.3.5")), testKind, testObjectId), - GenericTreeNode(0, tree.id, 6, LTree(List("1.3.6")), testKind, testObjectId) + GenericTreeNode(0, tree.id, 1, LTree("1"), testKind, testObjectId), + GenericTreeNode(0, tree.id, 2, LTree(List("1.2")), testKind, testObjectId), + GenericTreeNode(0, tree.id, 3, LTree(List("1.3")), testKind, testObjectId), + GenericTreeNode(0, tree.id, 4, LTree(List("1.3.4")), testKind, testObjectId), + GenericTreeNode(0, tree.id, 5, LTree(List("1.3.5")), testKind, testObjectId), + GenericTreeNode(0, tree.id, 6, LTree(List("1.3.6")), testKind, testObjectId) ) treeNodes ← * <~ GenericTreeNodes.createAllReturningModels(testData) } yield (tree, treeNodes)).gimme diff --git a/phoenix-scala/phoenix/test/integration/GiftCardIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/GiftCardIntegrationTest.scala index 1766b8cca3..07a9755dc0 100644 --- a/phoenix-scala/phoenix/test/integration/GiftCardIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/GiftCardIntegrationTest.scala @@ -9,7 +9,7 @@ import phoenix.models.account._ import phoenix.models.payment.giftcard.GiftCard._ import phoenix.models.payment.giftcard._ import phoenix.models.payment.storecredit.StoreCredit -import phoenix.models.payment.{InStorePaymentStates, storecredit} +import phoenix.models.payment.{storecredit, InStorePaymentStates} import phoenix.payloads.GiftCardPayloads._ import phoenix.responses.GiftCardAdjustmentsResponse.{Root ⇒ GcAdjRoot} import phoenix.responses.GiftCardResponse.{Root ⇒ GcRoot} @@ -56,9 +56,8 @@ class GiftCardIntegrationTest } "succeeds with valid subTypeId" in new Reason_Baked with GiftCardSubtype_Seed { - private val payload = GiftCardCreateByCsr(balance = 25, - reasonId = reason.id, - subTypeId = giftCardSubtype.id.some) + private val payload = + GiftCardCreateByCsr(balance = 25, reasonId = reason.id, subTypeId = giftCardSubtype.id.some) giftCardsApi.create(payload).as[GcRoot].subTypeId.value must === (giftCardSubtype.id) } @@ -117,13 +116,14 @@ class GiftCardIntegrationTest val cordInsert = api_newCustomerCart(customer.accountId) val root = giftCardsApi - .createFromCustomer( - GiftCardCreatedByCustomer(balance = 555, - senderName = "senderName", - recipientName = "recipienName", - recipientEmail = "recipientEmail@mail.com", - message = "test message".some, - cordRef = cordInsert.referenceNumber)) + .createFromCustomer(GiftCardCreatedByCustomer( + balance = 555, + senderName = "senderName", + recipientName = "recipienName", + recipientEmail = "recipientEmail@mail.com", + message = "test message".some, + cordRef = cordInsert.referenceNumber + )) .as[GiftCardResponse.Root] root.currency must === (Currency.USD) root.availableBalance must === (555) @@ -136,19 +136,24 @@ class GiftCardIntegrationTest val cordInsert = api_newCustomerCart(customer.accountId) val root = giftCardsApi - .createMultipleFromCustomer( - Seq(GiftCardCreatedByCustomer(balance = 555, - senderName = "senderName", - recipientName = "recipienName", - recipientEmail = "recipientEmail@mail.com", - message = "test message".some, - cordRef = cordInsert.referenceNumber), - GiftCardCreatedByCustomer(balance = 100, - senderName = "senderName2", - recipientName = "recipienName2", - recipientEmail = "recipientEmail@mail.com2", - message = "test message2".some, - cordRef = cordInsert.referenceNumber))) + .createMultipleFromCustomer(Seq( + GiftCardCreatedByCustomer( + balance = 555, + senderName = "senderName", + recipientName = "recipienName", + recipientEmail = "recipientEmail@mail.com", + message = "test message".some, + cordRef = cordInsert.referenceNumber + ), + GiftCardCreatedByCustomer( + balance = 100, + senderName = "senderName2", + recipientName = "recipienName2", + recipientEmail = "recipientEmail@mail.com2", + message = "test message2".some, + cordRef = cordInsert.referenceNumber + ) + )) .as[Seq[GiftCardResponse.Root]] root.size must === (2) @@ -166,19 +171,24 @@ class GiftCardIntegrationTest val cordInsert = api_newCustomerCart(customer.accountId) val root = giftCardsApi - .createMultipleFromCustomer( - Seq(GiftCardCreatedByCustomer(balance = 555, - senderName = "senderName", - recipientName = "recipienName", - recipientEmail = "recipientEmail@mail.com", - message = None, - cordRef = cordInsert.referenceNumber), - GiftCardCreatedByCustomer(balance = 100, - senderName = "senderName2", - recipientName = "recipienName2", - recipientEmail = "recipientEmail@mail.com2", - message = "".some, - cordRef = cordInsert.referenceNumber))) + .createMultipleFromCustomer(Seq( + GiftCardCreatedByCustomer( + balance = 555, + senderName = "senderName", + recipientName = "recipienName", + recipientEmail = "recipientEmail@mail.com", + message = None, + cordRef = cordInsert.referenceNumber + ), + GiftCardCreatedByCustomer( + balance = 100, + senderName = "senderName2", + recipientName = "recipienName2", + recipientEmail = "recipientEmail@mail.com2", + message = "".some, + cordRef = cordInsert.referenceNumber + ) + )) .as[Seq[GiftCardResponse.Root]] root.size must === (2) @@ -310,8 +320,8 @@ class GiftCardIntegrationTest private val bothCodes = Seq(giftCard1.code, giftCard2.code) private val payload = GiftCardBulkUpdateStateByCsr( - codes = bothCodes, - state = GiftCard.OnHold + codes = bothCodes, + state = GiftCard.OnHold ) giftCardsApi.updateBulk(payload).mustBeOk() @@ -324,8 +334,8 @@ class GiftCardIntegrationTest "returns multiple errors if no cancellation reason provided" in new Fixture { val payload = GiftCardBulkUpdateStateByCsr( - codes = Seq(giftCard1.code, giftCard2.code), - state = GiftCard.Canceled + codes = Seq(giftCard1.code, giftCard2.code), + state = GiftCard.Canceled ) giftCardsApi.updateBulk(payload).mustFailWith400(EmptyCancellationReasonFailure) diff --git a/phoenix-scala/phoenix/test/integration/GiftCardNotesIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/GiftCardNotesIntegrationTest.scala index b25f6d0076..7bdaa1dab7 100644 --- a/phoenix-scala/phoenix/test/integration/GiftCardNotesIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/GiftCardNotesIntegrationTest.scala @@ -96,9 +96,8 @@ class GiftCardNotesIntegrationTest trait Fixture extends Reason_Baked { val giftCard = (for { origin ← * <~ GiftCardManuals.create( - GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) - giftCard ← * <~ GiftCards.create( - Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) + GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + giftCard ← * <~ GiftCards.create(Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) } yield giftCard).gimme } } diff --git a/phoenix-scala/phoenix/test/integration/ImageIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/ImageIntegrationTest.scala index a921b05cff..036284f54e 100644 --- a/phoenix-scala/phoenix/test/integration/ImageIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/ImageIntegrationTest.scala @@ -62,8 +62,8 @@ class ImageIntegrationTest val imageSources = Seq("1", "2") albumsApi(album.formId) - .update(AlbumPayload(name = "Name 2.0".some, - images = imageSources.map(u ⇒ ImagePayload(src = u)).some)) + .update( + AlbumPayload(name = "Name 2.0".some, images = imageSources.map(u ⇒ ImagePayload(src = u)).some)) .mustBeOk() albumsApi(album.formId).get().as[AlbumRoot].images.map(_.src) must === (imageSources) @@ -81,8 +81,8 @@ class ImageIntegrationTest "one image" in new Fixture { albumsApi - .create(AlbumPayload(name = Some("Non-empty album"), - images = Seq(ImagePayload(src = "url")).some)) + .create( + AlbumPayload(name = Some("Non-empty album"), images = Seq(ImagePayload(src = "url")).some)) .as[AlbumRoot] .images .onlyElement @@ -91,8 +91,8 @@ class ImageIntegrationTest "multiple images" in new Fixture { val sources = Seq("url", "url2") - val payload = AlbumPayload(name = Some("Non-empty album"), - images = sources.map(s ⇒ ImagePayload(src = s)).some) + val payload = + AlbumPayload(name = Some("Non-empty album"), images = sources.map(s ⇒ ImagePayload(src = s)).some) val ordered = albumsApi.create(payload).as[AlbumRoot] ordered.images.map(_.src) must === (sources) @@ -365,8 +365,7 @@ class ImageIntegrationTest } "fail when uploading to archived album" in new ArchivedAlbumFixture { - uploadImage(archivedAlbum).mustFailWith400( - AddImagesToArchivedAlbumFailure(archivedAlbum.id)) + uploadImage(archivedAlbum).mustFailWith400(AddImagesToArchivedAlbumFailure(archivedAlbum.id)) } def uploadImage(album: Album, count: Int = 1): HttpResponse = { @@ -380,8 +379,7 @@ class ImageIntegrationTest } else { val bodyParts = 1 to count map { _ ⇒ Multipart.FormData.BodyPart.fromPath(name = "upload-file", - contentType = - MediaTypes.`application/octet-stream`, + contentType = MediaTypes.`application/octet-stream`, file = image) } val formData = Multipart.FormData(bodyParts.toList: _*) @@ -413,11 +411,11 @@ class ImageIntegrationTest val (album, albumImages) = (for { ins ← * <~ ObjectUtils.insert(form, shadow) album ← * <~ Albums.create( - Album(scope = Scope.current, - contextId = ctx.id, - shadowId = ins.shadow.id, - formId = ins.form.id, - commitId = ins.commit.id)) + Album(scope = Scope.current, + contextId = ctx.id, + shadowId = ins.shadow.id, + formId = ins.form.id, + commitId = ins.commit.id)) albumImages ← * <~ ImageManager.createImagesForAlbum(album, Seq(testPayload), ctx) } yield (album, albumImages)).gimme } @@ -428,15 +426,14 @@ class ImageIntegrationTest skuForm ← * <~ ObjectForms.create(simpleSku.create) sSkuShadow ← * <~ SimpleSkuShadow(simpleSku) skuShadow ← * <~ ObjectShadows.create(sSkuShadow.create.copy(formId = skuForm.id)) - skuCommit ← * <~ ObjectCommits.create( - ObjectCommit(formId = skuForm.id, shadowId = skuShadow.id)) + skuCommit ← * <~ ObjectCommits.create(ObjectCommit(formId = skuForm.id, shadowId = skuShadow.id)) sku ← * <~ Skus.create( - Sku(scope = Scope.current, - contextId = ctx.id, - formId = skuForm.id, - shadowId = skuShadow.id, - commitId = skuCommit.id, - code = "SKU-TEST")) + Sku(scope = Scope.current, + contextId = ctx.id, + formId = skuForm.id, + shadowId = skuShadow.id, + commitId = skuCommit.id, + code = "SKU-TEST")) _ ← * <~ SkuAlbumLinks.create(SkuAlbumLink(leftId = sku.id, rightId = album.id)) simpleProd ← * <~ SimpleProduct(title = "Test Product", @@ -445,14 +442,13 @@ class ImageIntegrationTest prodForm ← * <~ ObjectForms.create(simpleProd.create) sProdShadow ← * <~ SimpleProductShadow(simpleProd) prodShadow ← * <~ ObjectShadows.create(sProdShadow.create.copy(formId = prodForm.id)) - prodCommit ← * <~ ObjectCommits.create( - ObjectCommit(formId = prodForm.id, shadowId = prodShadow.id)) + prodCommit ← * <~ ObjectCommits.create(ObjectCommit(formId = prodForm.id, shadowId = prodShadow.id)) product ← * <~ Products.create( - Product(scope = Scope.current, - contextId = ctx.id, - formId = prodForm.id, - shadowId = prodShadow.id, - commitId = prodCommit.id)) + Product(scope = Scope.current, + contextId = ctx.id, + formId = prodForm.id, + shadowId = prodShadow.id, + commitId = prodCommit.id)) _ ← * <~ ProductAlbumLinks.create(ProductAlbumLink(leftId = product.id, rightId = album.id)) _ ← * <~ ProductSkuLinks.create(ProductSkuLink(leftId = product.id, rightId = sku.id)) diff --git a/phoenix-scala/phoenix/test/integration/JsonExceptionHandlerIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/JsonExceptionHandlerIntegrationTest.scala index 0b2c27408a..c96055a808 100644 --- a/phoenix-scala/phoenix/test/integration/JsonExceptionHandlerIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/JsonExceptionHandlerIntegrationTest.scala @@ -14,15 +14,14 @@ class JsonExceptionHandlerIntegrationTest val exceptionText = "A test exception" override protected def additionalRoutes = immutable.Seq( - path("testThrowAnExcepton") { - complete(throw new Exception(exceptionText)) - }, - path("testThrowAnIllegalRequestException") { - complete( - throw new IllegalRequestException( - new ErrorInfo(illegalRequestExceptionText), - StatusCodes.custom(400, "test").asInstanceOf[ClientError])) - } + path("testThrowAnExcepton") { + complete(throw new Exception(exceptionText)) + }, + path("testThrowAnIllegalRequestException") { + complete( + throw new IllegalRequestException(new ErrorInfo(illegalRequestExceptionText), + StatusCodes.custom(400, "test").asInstanceOf[ClientError])) + } ) "return a valid JSON exception on an IllegalRequestException" in { diff --git a/phoenix-scala/phoenix/test/integration/JwtAuthTest.scala b/phoenix-scala/phoenix/test/integration/JwtAuthTest.scala index 8618cfb7f6..7e5e336022 100644 --- a/phoenix-scala/phoenix/test/integration/JwtAuthTest.scala +++ b/phoenix-scala/phoenix/test/integration/JwtAuthTest.scala @@ -16,14 +16,13 @@ class JwtAuthTest "Real test auth" - { "must create an admin" in withNewAdminAuth(TestLoginData("admin@admin.com")) { implicit auth ⇒ - storeAdminsApi(auth.adminId).get().as[StoreAdminResponse.Root].email.value must === ( - "admin@admin.com") + storeAdminsApi(auth.adminId).get().as[StoreAdminResponse.Root].email.value must === ("admin@admin.com") } "must create an admin 2" in { withNewAdminAuth(TestLoginData("admin@admin.com")) { implicit auth ⇒ storeAdminsApi(auth.adminId).get().as[StoreAdminResponse.Root].email.value must === ( - "admin@admin.com") + "admin@admin.com") } } @@ -38,9 +37,10 @@ class JwtAuthTest // Let's assume she just got her nails done so she can only hit refresh on the cart page and talk to CSR val (adminId, daisyId, daisyCartRef) = withNewAdminAuth(adminLoginData) { implicit auth ⇒ val customer = customersApi - .create(CreateCustomerPayload(email = daisyLoginData.email, - password = daisyLoginData.password.some, - name = "Daisy Bloom".some)) + .create( + CreateCustomerPayload(email = daisyLoginData.email, + password = daisyLoginData.password.some, + name = "Daisy Bloom".some)) .as[CustomerResponse.Root] val cartRef = api_newCustomerCart(customer.id).referenceNumber diff --git a/phoenix-scala/phoenix/test/integration/NotificationIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/NotificationIntegrationTest.scala index 5b3fe02792..f48ffd652b 100644 --- a/phoenix-scala/phoenix/test/integration/NotificationIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/NotificationIntegrationTest.scala @@ -33,8 +33,9 @@ class NotificationIntegrationTest val notifications = skipHeartbeatsAndAdminCreated(sseSource(s"v1/notifications", defaultAdminAuth.jwtCookie)) val requests = Source(2 to 3).map { activityId ⇒ - val response = notificationsApi.create(newNotificationPayload.copy( - activity = newNotificationPayload.activity.copy(id = activityId.toString))) + val response = notificationsApi.create( + newNotificationPayload.copy( + activity = newNotificationPayload.activity.copy(id = activityId.toString))) s"notification $activityId: ${response.status}" } } @@ -47,7 +48,7 @@ class NotificationIntegrationTest val requests = Source.single(2).map { activityId ⇒ val response = notificationsApi.create(newNotificationPayload.copy( - activity = newNotificationPayload.activity.copy(id = activityId.toString))) + activity = newNotificationPayload.activity.copy(id = activityId.toString))) s"notification $activityId: ${response.status}" } } @@ -81,8 +82,7 @@ class NotificationIntegrationTest data.lastSeenNotificationId must === (notificationId) notificationsApi - .create(newNotificationPayload.copy( - activity = newNotificationPayload.activity.copy(id = "test2"))) + .create(newNotificationPayload.copy(activity = newNotificationPayload.activity.copy(id = "test2"))) .mustBeOk() } } @@ -159,12 +159,11 @@ class NotificationIntegrationTest } val newNotificationActivity = NotificationActivity( - id = "test", - kind = "test", - data = JNothing, - context = - ActivityContext(userId = 1, userType = "x", transactionId = "y", scope = LTree("1")), - createdAt = Instant.now) + id = "test", + kind = "test", + data = JNothing, + context = ActivityContext(userId = 1, userType = "x", transactionId = "y", scope = LTree("1")), + createdAt = Instant.now) val newNotificationPayload = CreateNotification(sourceDimension = Dimension.order, sourceObjectId = randomObjectId, @@ -177,10 +176,7 @@ class NotificationIntegrationTest objectIds: Seq[String] = Seq(randomObjectId), reason: Reason = Watching) = NotificationManager - .subscribe(adminIds = adminIds, - dimension = dimension, - objectIds = objectIds, - reason = reason) + .subscribe(adminIds = adminIds, dimension = dimension, objectIds = objectIds, reason = reason) .gimme def unsubscribeFromNotifications() = diff --git a/phoenix-scala/phoenix/test/integration/PaymentTypesIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/PaymentTypesIntegrationTest.scala index a6dbede468..322c9be56d 100644 --- a/phoenix-scala/phoenix/test/integration/PaymentTypesIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/PaymentTypesIntegrationTest.scala @@ -8,10 +8,7 @@ import testutils.apis.PhoenixPublicApi import testutils.fixtures.BakedFixtures import core.db._ -class PaymentTypesIntegrationTest - extends IntegrationTestBase - with PhoenixPublicApi - with BakedFixtures { +class PaymentTypesIntegrationTest extends IntegrationTestBase with PhoenixPublicApi with BakedFixtures { "GiftCard Types" - { "GET /v1/public/gift-cards/types" - { @@ -20,8 +17,7 @@ class PaymentTypesIntegrationTest root.size must === (GiftCard.OriginType.types.size) root.map(_.originType) must === (GiftCard.OriginType.types.toSeq) - root.filter(_.originType == giftCardSubtype.originType).head.subTypes must === ( - Seq(giftCardSubtype)) + root.filter(_.originType == giftCardSubtype.originType).head.subTypes must === (Seq(giftCardSubtype)) } } } @@ -42,9 +38,8 @@ class PaymentTypesIntegrationTest val (giftCard) = (for { reason ← * <~ Reasons.create(Factories.reason(storeAdmin.accountId)) origin ← * <~ GiftCardManuals.create( - GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) - giftCard ← * <~ GiftCards.create( - Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) + GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + giftCard ← * <~ GiftCards.create(Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) } yield giftCard).gimme } @@ -53,10 +48,9 @@ class PaymentTypesIntegrationTest scReason ← * <~ Reasons.create(Factories.reason(storeAdmin.accountId)) scSubType ← * <~ StoreCreditSubtypes.create(Factories.storeCreditSubTypes.head) scOrigin ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = scReason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = scReason.id)) storeCredit ← * <~ StoreCredits.create( - Factories.storeCredit.copy(originId = scOrigin.id, - accountId = customer.accountId)) + Factories.storeCredit.copy(originId = scOrigin.id, accountId = customer.accountId)) } yield (storeCredit, scSubType)).gimme } } diff --git a/phoenix-scala/phoenix/test/integration/ProductIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/ProductIntegrationTest.scala index 462b06e51b..5c0b751bd4 100644 --- a/phoenix-scala/phoenix/test/integration/ProductIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/ProductIntegrationTest.scala @@ -73,10 +73,7 @@ class ProductIntegrationTest productsApi(product.id) .update( - UpdateProductPayload(productPayload.attributes, - slug = Some(slug), - skus = None, - variants = None)) + UpdateProductPayload(productPayload.attributes, slug = Some(slug), skus = None, variants = None)) .mustBeOk() List(slug, "Simple-Product").foreach { slugToQuery ⇒ @@ -103,19 +100,16 @@ class ProductIntegrationTest productsApi(product.formId) .update( - UpdateProductPayload(productPayload.attributes, - slug = slug.some, - skus = None, - variants = None)) + UpdateProductPayload(productPayload.attributes, slug = slug.some, skus = None, variants = None)) .mustBeOk() deactivate(fix) List( - withRandomCustomerAuth { implicit auth ⇒ - storefrontProductsApi(slug).get() - }, - publicApi.getProducts(slug) + withRandomCustomerAuth { implicit auth ⇒ + storefrontProductsApi(slug).get() + }, + publicApi.getProducts(slug) ).foreach(_.mustFailWith404(NotFoundFailure404(Product, slug))) } @@ -125,10 +119,8 @@ class ProductIntegrationTest "404 for inactive products" in go { f ⇒ productsApi(f.product.formId) - .update(UpdateProductPayload(attributes = f.inactiveAttrMap, - skus = None, - albums = None, - variants = None)) + .update( + UpdateProductPayload(attributes = f.inactiveAttrMap, skus = None, albums = None, variants = None)) .mustBeOk() } @@ -157,9 +149,8 @@ class ProductIntegrationTest } "POST v1/products/:context" - { - def doQuery(productPayload: CreateProductPayload) = { + def doQuery(productPayload: CreateProductPayload) = productsApi.create(productPayload).as[Root] - } "Creates a product with" - { val skuName = "SKU-NEW-TEST" @@ -209,10 +200,10 @@ class ProductIntegrationTest "a new SKU successfully, both active, and that is accessible for customers & publicly" in new Fixture { val pp = productPayload val response = doQuery( - pp.copy( - attributes = pp.attributes ++ activeAttrMap, - skus = pp.skus.map(sku ⇒ sku.copy(attributes = sku.attributes ++ activeAttrMap)) - )) + pp.copy( + attributes = pp.attributes ++ activeAttrMap, + skus = pp.skus.map(sku ⇒ sku.copy(attributes = sku.attributes ++ activeAttrMap)) + )) withRandomCustomerAuth { implicit auth ⇒ storefrontProductsApi(product.formId.toString).get().mustBeOk() } @@ -220,14 +211,11 @@ class ProductIntegrationTest } "a new SKU in variant successfully" in new Fixture { - val valuePayload = Seq( - VariantValuePayload(skuCodes = Seq(skuName), - swatch = None, - image = None, - name = Some("Test"))) + val valuePayload = + Seq(VariantValuePayload(skuCodes = Seq(skuName), swatch = None, image = None, name = Some("Test"))) val variantPayload = Seq( - VariantPayload(attributes = Map("test" → (("t" → "test") ~ ("v" → "Test"))), - values = Some(valuePayload))) + VariantPayload(attributes = Map("test" → (("t" → "test") ~ ("v" → "Test"))), + values = Some(valuePayload))) val productResponse = doQuery(productPayload.copy(variants = Some(variantPayload))) @@ -296,14 +284,10 @@ class ProductIntegrationTest "empty variant successfully" in new Fixture { val redSkuPayload = makeSkuPayload(skuRedSmallCode, skuAttrMap, None) - val values = Seq( - VariantValuePayload(name = Some("value"), - swatch = None, - image = None, - skuCodes = Seq.empty)) - val variantPayload = Seq( - VariantPayload(attributes = Map("t" → (("t" → "typ") ~ ("v" → "val"))), - values = Some(values))) + val values = + Seq(VariantValuePayload(name = Some("value"), swatch = None, image = None, skuCodes = Seq.empty)) + val variantPayload = + Seq(VariantPayload(attributes = Map("t" → (("t" → "typ") ~ ("v" → "val"))), values = Some(values))) val payload = productPayload.copy(skus = Seq(redSkuPayload), variants = Some(variantPayload)) @@ -360,10 +344,10 @@ class ProductIntegrationTest "no SKU exists for variants" in new Fixture { val values = Seq( - VariantValuePayload(name = Some("name"), - swatch = None, - image = None, - skuCodes = Seq("SKU-TEST1", "SKU-TEST2"))) + VariantValuePayload(name = Some("name"), + swatch = None, + image = None, + skuCodes = Seq("SKU-TEST1", "SKU-TEST2"))) val variantPayload = Seq(VariantPayload(attributes = Map("t" → "t"), values = Some(values))) val payload = productPayload.copy(skus = Seq.empty, variants = Some(variantPayload)) @@ -393,7 +377,7 @@ class ProductIntegrationTest productsApi .create(newProductPayload) .mustFailWithMessage( - """Object sku with id=%ANY% doesn't pass validation: $.code: must be at least 1 characters long""") + """Object sku with id=%ANY% doesn't pass validation: $.code: must be at least 1 characters long""") } "trying to create a product with archived SKU" in new ArchivedSkuFixture { @@ -404,7 +388,7 @@ class ProductIntegrationTest "trying to create a product with string price" in new Fixture { val price: Json = ("t" → "price") ~ ("v" → (("currency" - → "USD") ~ ("value" → "1000"))) + → "USD") ~ ("value" → "1000"))) val skuAttributes: Map[String, Json] = skuPayload.attributes + ("salePrice" → price) val productToCreate = productPayload.copy(skus = Seq(skuPayload.copy(attributes = skuAttributes))) @@ -454,9 +438,8 @@ class ProductIntegrationTest } "PATCH v1/products/:context/:id" - { - def doQuery(formId: Int, productPayload: UpdateProductPayload)(implicit sl: SL, sf: SF) = { + def doQuery(formId: Int, productPayload: UpdateProductPayload)(implicit sl: SL, sf: SF) = productsApi(formId).update(productPayload).as[Root] - } "Doesn't complain if you do update w/o any changes" in new Customer_Seed with Fixture { private val cartRef = @@ -466,11 +449,10 @@ class ProductIntegrationTest productsApi(product.formId) .update( - UpdateProductPayload(attributes = attrMap, - skus = - allSkus.map(sku ⇒ makeSkuPayload(sku, skuAttrMap, None)).some, - albums = None, - variants = None)) + UpdateProductPayload(attributes = attrMap, + skus = allSkus.map(sku ⇒ makeSkuPayload(sku, skuAttrMap, None)).some, + albums = None, + variants = None)) .mustBeOk() } @@ -589,10 +571,10 @@ class ProductIntegrationTest "Removes SKUs from product" in new Fixture { productsApi(product.formId) .update( - UpdateProductPayload(attributes = attrMap, - skus = Seq.empty.some, - albums = None, - variants = Seq.empty.some)) + UpdateProductPayload(attributes = attrMap, + skus = Seq.empty.some, + albums = None, + variants = Seq.empty.some)) .as[Root] .skus mustBe empty } @@ -659,10 +641,8 @@ class ProductIntegrationTest "Updates the variants" - { "Remove all variants successfully" in new Fixture { - val payload = UpdateProductPayload(attributes = Map.empty, - skus = None, - variants = Some(Seq()), - albums = None) + val payload = + UpdateProductPayload(attributes = Map.empty, skus = None, variants = Some(Seq()), albums = None) val response = doQuery(product.formId, payload) response.skus.length must === (0) @@ -673,22 +653,17 @@ class ProductIntegrationTest private val newSkuCode: ActivityType = "SKU-NEW-TEST" val newSkuPayload = makeSkuPayload(newSkuCode, skuAttrMap, None) - val goldValuePayload = VariantValuePayload(name = Some("Gold"), - swatch = None, - image = None, - skuCodes = Seq(newSkuCode)) - val silverValuePayload = VariantValuePayload(name = Some("Silver"), - swatch = None, - image = None, - skuCodes = Seq.empty) + val goldValuePayload = + VariantValuePayload(name = Some("Gold"), swatch = None, image = None, skuCodes = Seq(newSkuCode)) + val silverValuePayload = + VariantValuePayload(name = Some("Silver"), swatch = None, image = None, skuCodes = Seq.empty) val metalVariantPayload = makeVariantPayload("Metal", Seq(goldValuePayload, silverValuePayload)) val payload = UpdateProductPayload(attributes = Map.empty, skus = Some(Seq(newSkuPayload)), albums = None, - variants = - Some(colorSizeVariants.+:(metalVariantPayload))) + variants = Some(colorSizeVariants.+:(metalVariantPayload))) val response = doQuery(product.formId, payload) response.skus.length must === (5) @@ -700,15 +675,15 @@ class ProductIntegrationTest "Throws an error" - { "if updating adds too many SKUs" in new VariantFixture { val upPayload = UpdateProductPayload( - attributes = Map.empty, - skus = Some( - Seq(skuPayload, - smallRedSkuPayload, - smallGreenSkuPayload, - largeRedSkuPayload, - largeGreenSkuPayload)), - variants = None, - albums = None + attributes = Map.empty, + skus = Some( + Seq(skuPayload, + smallRedSkuPayload, + smallGreenSkuPayload, + largeRedSkuPayload, + largeGreenSkuPayload)), + variants = None, + albums = None ) productsApi(product.formId) @@ -718,10 +693,11 @@ class ProductIntegrationTest "trying to update a product with archived SKU" in new ArchivedSkuFixture { productsApi(product.formId) - .update(UpdateProductPayload(attributes = archivedSkuProductPayload.attributes, - skus = archivedSkuProductPayload.skus.some, - albums = None, - variants = archivedSkuProductPayload.variants)) + .update( + UpdateProductPayload(attributes = archivedSkuProductPayload.attributes, + skus = archivedSkuProductPayload.skus.some, + albums = None, + variants = archivedSkuProductPayload.variants)) .mustFailWith400(LinkInactiveSkuFailure(Product, product.id, archivedSkuCode)) } @@ -744,10 +720,11 @@ class ProductIntegrationTest val invalidSlugValues = Seq("1", "-1", "+1", "_", "-") for (slug ← invalidSlugValues) { productsApi(createdProduct.id) - .update(UpdateProductPayload(attributes = productPayload.attributes, - slug = Some(slug), - skus = None, - variants = None)) + .update( + UpdateProductPayload(attributes = productPayload.attributes, + slug = Some(slug), + skus = None, + variants = None)) .mustFailWith400(SlugShouldHaveLetters(slug)) .withClue(s" slug = $slug") } @@ -760,10 +737,10 @@ class ProductIntegrationTest val product2 = productsApi.create(productPayload).as[Root] private val updateResponse: HttpResponse = productsApi(product2.id).update( - UpdateProductPayload(attributes = productPayload.attributes, - slug = Some(slug), - skus = None, - variants = None)) + UpdateProductPayload(attributes = productPayload.attributes, + slug = Some(slug), + skus = None, + variants = None)) updateResponse.mustFailWith400(SlugDuplicates(slug)) } @@ -834,9 +811,7 @@ class ProductIntegrationTest SkuPayload(attributes = attrMap, albums = albums) } - def makeSkuPayload(code: String, - attrMap: Map[String, Json], - albums: Option[Seq[AlbumPayload]]) = { + def makeSkuPayload(code: String, attrMap: Map[String, Json], albums: Option[Seq[AlbumPayload]]) = { val codeJson = ("t" → "string") ~ ("v" → code) val titleJson = ("t" → "string") ~ ("v" → ("title_" + code)) val attributes = (attrMap + ("code" → codeJson)) + ("title" → titleJson) @@ -848,16 +823,14 @@ class ProductIntegrationTest val skuAttrMap = Map("price" → priceJson) val skuPayload = makeSkuPayload("SKU-NEW-TEST", skuAttrMap, None) - val nameJson = ("t" → "string") ~ ("v" → "Product name") - val attrMap = Map("name" → nameJson, "title" → nameJson) - val activeFromJson = ("t" → "date") ~ ("v" → (Instant.now.minus(2, ChronoUnit.DAYS)).toString) - val activeToJson = ("t" → "date") ~ ("v" → (Instant.now.minus(1, ChronoUnit.DAYS)).toString) + val nameJson = ("t" → "string") ~ ("v" → "Product name") + val attrMap = Map("name" → nameJson, "title" → nameJson) + val activeFromJson = ("t" → "date") ~ ("v" → (Instant.now.minus(2, ChronoUnit.DAYS)).toString) + val activeToJson = ("t" → "date") ~ ("v" → (Instant.now.minus(1, ChronoUnit.DAYS)).toString) val inactiveAttrMap = attrMap ++ Map("activeFrom" → activeFromJson, "activeTo" → activeToJson) val activeAttrMap = attrMap ++ Map("activeFrom" → activeFromJson) - val productPayload = CreateProductPayload(attributes = attrMap, - skus = Seq(skuPayload), - variants = None, - albums = None) + val productPayload = + CreateProductPayload(attributes = attrMap, skus = Seq(skuPayload), variants = None, albums = None) val simpleProd = SimpleProductData(title = "Test Product", code = "TEST", @@ -874,34 +847,19 @@ class ProductIntegrationTest val allSkus: Seq[String] = Seq(skuRedSmallCode, skuRedLargeCode, skuGreenSmallCode, skuGreenLargeCode) - val simpleSkus = Seq(SimpleSku(skuRedSmallCode, - "A small, red item", - 9999, - currency = Currency.USD, - active = true), - SimpleSku(skuRedLargeCode, - "A large, red item", - 9999, - currency = Currency.USD, - active = true), - SimpleSku(skuGreenSmallCode, - "A small, green item", - 9999, - currency = Currency.USD, - active = true), - SimpleSku(skuGreenLargeCode, - "A large, green item", - 9999, - currency = Currency.USD, - active = true)) + val simpleSkus = Seq( + SimpleSku(skuRedSmallCode, "A small, red item", 9999, currency = Currency.USD, active = true), + SimpleSku(skuRedLargeCode, "A large, red item", 9999, currency = Currency.USD, active = true), + SimpleSku(skuGreenSmallCode, "A small, green item", 9999, currency = Currency.USD, active = true), + SimpleSku(skuGreenLargeCode, "A large, green item", 9999, currency = Currency.USD, active = true) + ) val variantsWithValues = Seq( - SimpleCompleteVariant( - SimpleVariant("Size"), - Seq(SimpleVariantValue("small", ""), SimpleVariantValue("large", ""))), - SimpleCompleteVariant( - SimpleVariant("Color"), - Seq(SimpleVariantValue("red", "ff0000"), SimpleVariantValue("green", "00ff00")))) + SimpleCompleteVariant(SimpleVariant("Size"), + Seq(SimpleVariantValue("small", ""), SimpleVariantValue("large", ""))), + SimpleCompleteVariant(SimpleVariant("Color"), + Seq(SimpleVariantValue("red", "ff0000"), SimpleVariantValue("green", "00ff00"))) + ) val skuValueMapping: Seq[(String, String, String)] = Seq((skuRedSmallCode, "red", "small"), (skuRedLargeCode, "red", "large"), @@ -935,11 +893,9 @@ class ProductIntegrationTest for { colorLink ← * <~ VariantValueSkuLinks.create( - VariantValueSkuLink(leftId = colorValue.valueId, - rightId = selectedSku.id)) + VariantValueSkuLink(leftId = colorValue.valueId, rightId = selectedSku.id)) sizeLink ← * <~ VariantValueSkuLinks.create( - VariantValueSkuLink(leftId = sizeValue.valueId, - rightId = selectedSku.id)) + VariantValueSkuLink(leftId = sizeValue.valueId, rightId = selectedSku.id)) } yield (colorLink, sizeLink) } } yield (product, skus, variantsAndValues) @@ -948,27 +904,22 @@ class ProductIntegrationTest trait VariantFixture extends Fixture { def makeVariantPayload(name: String, values: Seq[VariantValuePayload]) = - VariantPayload(attributes = Map("name" → (("t" → "string") ~ ("v" → name))), - values = Some(values)) + VariantPayload(attributes = Map("name" → (("t" → "string") ~ ("v" → name))), values = Some(values)) val redSkus = Seq(skuRedSmallCode, skuRedLargeCode) val greenSkus = Seq(skuGreenSmallCode, skuGreenLargeCode) val smallSkus = Seq(skuRedSmallCode, skuGreenSmallCode) val largeSkus = Seq(skuRedLargeCode, skuGreenLargeCode) - val redValuePayload = VariantValuePayload(name = Some("Red"), - swatch = Some("ff0000"), - image = None, - skuCodes = Seq.empty) - val greenValuePayload = VariantValuePayload(name = Some("Green"), - swatch = Some("00ff00"), - image = None, - skuCodes = Seq.empty) + val redValuePayload = + VariantValuePayload(name = Some("Red"), swatch = Some("ff0000"), image = None, skuCodes = Seq.empty) + val greenValuePayload = + VariantValuePayload(name = Some("Green"), swatch = Some("00ff00"), image = None, skuCodes = Seq.empty) val justColorVariantPayload = makeVariantPayload( - "Color", - Seq(redValuePayload.copy(skuCodes = Seq(skuRedSmallCode)), - greenValuePayload.copy(skuCodes = Seq(skuGreenSmallCode)))) + "Color", + Seq(redValuePayload.copy(skuCodes = Seq(skuRedSmallCode)), + greenValuePayload.copy(skuCodes = Seq(skuGreenSmallCode)))) val smallValuePayload = VariantValuePayload(name = Some("Small"), swatch = None, image = None, skuCodes = Seq.empty) @@ -977,19 +928,17 @@ class ProductIntegrationTest VariantValuePayload(name = Some("Large"), swatch = None, image = None, skuCodes = Seq.empty) val justSizeVariantPayload = makeVariantPayload( - "Size", - Seq(smallValuePayload.copy(skuCodes = Seq(skuRedSmallCode)), - largeValuePayload.copy(skuCodes = Seq(skuRedLargeCode)))) + "Size", + Seq(smallValuePayload.copy(skuCodes = Seq(skuRedSmallCode)), + largeValuePayload.copy(skuCodes = Seq(skuRedLargeCode)))) private val colorVariantPayload = makeVariantPayload( - "Color", - Seq(redValuePayload.copy(skuCodes = redSkus), - greenValuePayload.copy(skuCodes = greenSkus))) + "Color", + Seq(redValuePayload.copy(skuCodes = redSkus), greenValuePayload.copy(skuCodes = greenSkus))) private val sizeVariantPayload = makeVariantPayload( - "Size", - Seq(smallValuePayload.copy(skuCodes = smallSkus), - largeValuePayload.copy(skuCodes = largeSkus))) + "Size", + Seq(smallValuePayload.copy(skuCodes = smallSkus), largeValuePayload.copy(skuCodes = largeSkus))) val colorSizeVariants = Seq(colorVariantPayload, sizeVariantPayload) @@ -1014,21 +963,21 @@ class ProductIntegrationTest trait RemovingSkusFixture extends VariantFixture { val twoSkuVariantPayload: Seq[VariantPayload] = Seq( - makeVariantPayload("Size", - Seq(redValuePayload.copy(skuCodes = Seq(skuRedLargeCode)), - greenValuePayload.copy(skuCodes = Seq(skuGreenSmallCode)))), - makeVariantPayload("Color", - Seq(smallValuePayload.copy(skuCodes = Seq(skuGreenSmallCode)), - largeValuePayload.copy(skuCodes = Seq(skuRedLargeCode))))) + makeVariantPayload("Size", + Seq(redValuePayload.copy(skuCodes = Seq(skuRedLargeCode)), + greenValuePayload.copy(skuCodes = Seq(skuGreenSmallCode)))), + makeVariantPayload("Color", + Seq(smallValuePayload.copy(skuCodes = Seq(skuGreenSmallCode)), + largeValuePayload.copy(skuCodes = Seq(skuRedLargeCode)))) + ) - val twoSkuPayload: Seq[SkuPayload] = Seq( - makeSkuPayload(skuRedLargeCode, "A large, red item", None), - makeSkuPayload(skuGreenSmallCode, "A small, green item", None)) + val twoSkuPayload: Seq[SkuPayload] = Seq(makeSkuPayload(skuRedLargeCode, "A large, red item", None), + makeSkuPayload(skuGreenSmallCode, "A small, green item", None)) val twoSkuProductPayload: UpdateProductPayload = UpdateProductPayload( - attributes = attrMap, - variants = twoSkuVariantPayload.some, - albums = None, - skus = twoSkuPayload.some) + attributes = attrMap, + variants = twoSkuVariantPayload.some, + albums = None, + skus = twoSkuPayload.some) } } diff --git a/phoenix-scala/phoenix/test/integration/ProductReviewIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/ProductReviewIntegrationTest.scala index 65429f09b6..392907d1f9 100644 --- a/phoenix-scala/phoenix/test/integration/ProductReviewIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/ProductReviewIntegrationTest.scala @@ -28,9 +28,8 @@ class ProductReviewIntegrationTest "POST v1/review/:contextName" - { "creates product review" in new ProductSku_ApiFixture { - val payload = CreateProductReviewByCustomerPayload(attributes = "title" → tv("title"), - sku = skuCode, - scope = None) + val payload = + CreateProductReviewByCustomerPayload(attributes = "title" → tv("title"), sku = skuCode, scope = None) val reviewResp = productReviewApi.create(payload).as[ProductReviewResponse] val getReviewResp = productReviewApi(reviewResp.id).get().as[ProductReviewResponse] getReviewResp must === (reviewResp) @@ -38,9 +37,8 @@ class ProductReviewIntegrationTest } "does not create duplicate reviews" in new ProductSku_ApiFixture { - val payload = CreateProductReviewByCustomerPayload(attributes = "title" → tv("title"), - sku = skuCode, - scope = None) + val payload = + CreateProductReviewByCustomerPayload(attributes = "title" → tv("title"), sku = skuCode, scope = None) val reviewResp1 = productReviewApi.create(payload).as[ProductReviewResponse] val getReviewResp1 = productReviewApi(reviewResp1.id).get().as[ProductReviewResponse] val reviewResp2 = productReviewApi.create(payload).as[ProductReviewResponse] @@ -80,29 +78,29 @@ class ProductReviewIntegrationTest archivedAt: Option[String]) implicit val getProductReviewsSearchViewResult = GetResult( - r ⇒ - ProductReviewsSearchViewItem(r.nextInt(), - r.nextObject().toString, - r.nextString(), - r.nextString(), - r.nextInt(), - r.nextString(), - r.nextString(), - r.nextStringOption(), - r.nextStringOption(), - r.nextStringOption())) + r ⇒ + ProductReviewsSearchViewItem( + r.nextInt(), + r.nextObject().toString, + r.nextString(), + r.nextString(), + r.nextInt(), + r.nextString(), + r.nextString(), + r.nextStringOption(), + r.nextStringOption(), + r.nextStringOption() + )) - def selectById(id: Int) = { - sql"""select * from product_reviews_search_view where id = ${id}""" + def selectById(id: Int) = + sql"""select * from product_reviews_search_view where id = $id""" .as[ProductReviewsSearchViewItem] .gimme - } "inserts new record on review insert" in new ProductSku_ApiFixture { private val title: String = "title" - val payload = CreateProductReviewByCustomerPayload(attributes = "title" → tv(title), - sku = skuCode, - scope = None) + val payload = + CreateProductReviewByCustomerPayload(attributes = "title" → tv(title), sku = skuCode, scope = None) val reviewResp = productReviewApi.create(payload).as[ProductReviewResponse] val values = selectById(reviewResp.id) values.size must === (1) diff --git a/phoenix-scala/phoenix/test/integration/PromotionsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/PromotionsIntegrationTest.scala index 6fae7dcf9f..56d5ea9c61 100644 --- a/phoenix-scala/phoenix/test/integration/PromotionsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/PromotionsIntegrationTest.scala @@ -80,8 +80,7 @@ class PromotionsIntegrationTest val disablePromoPayload = UpdatePromotion(applyType = promotion.applyType, attributes = promoAttributes, - discounts = - Seq(UpdatePromoDiscount(formDiscount.id, attributes = newDiscountAttrs))) + discounts = Seq(UpdatePromoDiscount(formDiscount.id, attributes = newDiscountAttrs))) promotionsApi(promotion.formId).update(disablePromoPayload).as[PromotionResponse.Root] } @@ -102,8 +101,7 @@ class PromotionsIntegrationTest fullPromotion.getAttribute("activeFrom") must === (JNothing) val attributes: List[(String, JValue)] = - IlluminateAlgorithm.projectAttributes(fullPromotion.form.attributes, - fullPromotion.shadow.attributes) match { + IlluminateAlgorithm.projectAttributes(fullPromotion.form.attributes, fullPromotion.shadow.attributes) match { case JObject(f) ⇒ f case _ ⇒ List() } @@ -112,8 +110,7 @@ class PromotionsIntegrationTest .update(promotion.formId, UpdatePromotion(Coupon, attributes.toMap, Seq()), ctx.name, None) .gimme - fullPromotion = - ObjectManager.getFullObject(Promotions.mustFindById400(fullPromotion.model.id)).gimme + fullPromotion = ObjectManager.getFullObject(Promotions.mustFindById400(fullPromotion.model.id)).gimme fullPromotion.getAttribute("activeFrom") must !==(JNothing) } } @@ -133,8 +130,8 @@ class PromotionsIntegrationTest val discountPayload = { val discountAttrs = { val qualifier = JObject(JField("orderAny", JObject(("", JNothing)))) - val offer = JObject( - JField("orderPercentOff", JObject(JField("discount", DefaultDiscountPercent)))) + val offer = + JObject(JField("orderPercentOff", JObject(JField("discount", DefaultDiscountPercent)))) Map("qualifier" → tv(qualifier, "qualifier"), "offer" → tv(offer, "offer")) } @@ -154,17 +151,21 @@ class PromotionsIntegrationTest val coupon = { val couponPayload = { - val usageRules = JObject(JField("isExclusive", false), - JField("isUnlimitedPerCode", false), - JField("usesPerCode", 1), - JField("isUnlimitedPerCustomer", false), - JField("usesPerCustomer", 1)) - - val attrs = Map("usageRules" → tv(usageRules, "usageRules"), - "name" → tv("testyCoupon"), - "storefrontName" → tv("

Testy coupon

", "richText"), - "activeFrom" → tv(Instant.now, "datetime"), - "activeTo" → tv(JNull, "datetime")) + val usageRules = JObject( + JField("isExclusive", false), + JField("isUnlimitedPerCode", false), + JField("usesPerCode", 1), + JField("isUnlimitedPerCustomer", false), + JField("usesPerCustomer", 1) + ) + + val attrs = Map( + "usageRules" → tv(usageRules, "usageRules"), + "name" → tv("testyCoupon"), + "storefrontName" → tv("

Testy coupon

", "richText"), + "activeFrom" → tv(Instant.now, "datetime"), + "activeTo" → tv(JNull, "datetime") + ) CreateCoupon(promotion = promoId, attributes = attrs) } couponsApi.create(couponPayload).as[CouponResponse.Root] @@ -191,10 +192,8 @@ class PromotionsIntegrationTest cartWithCoupon.promotion mustBe 'defined cartWithCoupon.coupon mustBe 'defined - cartWithCoupon.totals.adjustments.toDouble must === ( - cartTotal * (DefaultDiscountPercent / 100.0)) - cartWithCoupon.totals.total.toDouble must === ( - cartTotal * (1.0 - (DefaultDiscountPercent / 100.0))) + cartWithCoupon.totals.adjustments.toDouble must === (cartTotal * (DefaultDiscountPercent / 100.0)) + cartWithCoupon.totals.total.toDouble must === (cartTotal * (1.0 - (DefaultDiscountPercent / 100.0))) } "from storefront UI" in new StoreAdmin_Seed with ProductAndSkus_Baked { @@ -212,15 +211,12 @@ class PromotionsIntegrationTest cartWithCoupon.promotion mustBe 'defined cartWithCoupon.coupon mustBe 'defined - cartWithCoupon.totals.adjustments.toDouble must === ( - cartTotal * (DefaultDiscountPercent / 100.0)) - cartWithCoupon.totals.total.toDouble must === ( - cartTotal * (1.0 - (DefaultDiscountPercent / 100.0))) + cartWithCoupon.totals.adjustments.toDouble must === (cartTotal * (DefaultDiscountPercent / 100.0)) + cartWithCoupon.totals.total.toDouble must === (cartTotal * (1.0 - (DefaultDiscountPercent / 100.0))) } } - "should update coupon discount when cart becomes clean" in new Fixture - with ProductSku_ApiFixture { + "should update coupon discount when cart becomes clean" in new Fixture with ProductSku_ApiFixture { private val (_, couponCode) = setupPromoAndCoupon() withRandomCustomerAuth { implicit auth ⇒ @@ -284,10 +280,8 @@ class PromotionsIntegrationTest val percentOff = 37 val autoPromo = promotionsApi - .create( - PromotionPayloadBuilder.build(Promotion.Auto, - PromoOfferBuilder.CartPercentOff(percentOff), - PromoQualifierBuilder.CartAny)) + .create(PromotionPayloadBuilder + .build(Promotion.Auto, PromoOfferBuilder.CartPercentOff(percentOff), PromoQualifierBuilder.CartAny)) .as[PromotionResponse.Root] val (coupon, couponCode) = setupPromoAndCoupon() diff --git a/phoenix-scala/phoenix/test/integration/ReasonsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/ReasonsIntegrationTest.scala index adccf31be2..005d94555d 100644 --- a/phoenix-scala/phoenix/test/integration/ReasonsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/ReasonsIntegrationTest.scala @@ -34,8 +34,8 @@ class ReasonsIntegrationTest trait Fixture extends StoreAdmin_Seed { val (reason, returnReason) = (for { reason ← * <~ Reasons.create( - Factories.reasons.head.copy(reasonType = Reason.GiftCardCreation, - storeAdminId = storeAdmin.accountId)) + Factories.reasons.head.copy(reasonType = Reason.GiftCardCreation, + storeAdminId = storeAdmin.accountId)) returnReason ← * <~ ReturnReasons.create(Factories.returnReasons.head) } yield (reason, returnReason)).gimme } diff --git a/phoenix-scala/phoenix/test/integration/ReturnIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/ReturnIntegrationTest.scala index 7a40644ca2..31b65cb319 100644 --- a/phoenix-scala/phoenix/test/integration/ReturnIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/ReturnIntegrationTest.scala @@ -72,15 +72,13 @@ class ReturnIntegrationTest "PATCH /v1/returns/:refNum" - { "successfully changes status of Return" in new ReturnDefaults { val payload = ReturnUpdateStatePayload(state = Processing, reasonId = None) - returnsApi(rma.referenceNumber).update(payload).as[ReturnResponse.Root].state must === ( - Processing) + returnsApi(rma.referenceNumber).update(payload).as[ReturnResponse.Root].state must === (Processing) } "successfully cancels Return with valid reason" in new ReturnDefaults { val payload = ReturnUpdateStatePayload(state = Canceled, reasonId = cancellationReason.id.some) - returnsApi(rma.referenceNumber).update(payload).as[ReturnResponse.Root].state must === ( - Canceled) + returnsApi(rma.referenceNumber).update(payload).as[ReturnResponse.Root].state must === (Canceled) } "fails if return reason has wrong type" in new ReturnDefaults { @@ -105,8 +103,7 @@ class ReturnIntegrationTest "Cancel state should be final " in new ReturnDefaults { val canceled = returnsApi(rma.referenceNumber) - .update( - ReturnUpdateStatePayload(state = Canceled, reasonId = cancellationReason.id.some)) + .update(ReturnUpdateStatePayload(state = Canceled, reasonId = cancellationReason.id.some)) .as[Root] canceled.state must === (Canceled) @@ -114,16 +111,14 @@ class ReturnIntegrationTest returnsApi(rma.referenceNumber) .update(ReturnUpdateStatePayload(state = Pending, reasonId = None)) - .mustFailWith400( - StateTransitionNotAllowed(Return, "Canceled", "Pending", rma.referenceNumber)) + .mustFailWith400(StateTransitionNotAllowed(Return, "Canceled", "Pending", rma.referenceNumber)) } "Returns should be fine with state transition " in new ReturnDefaults { returnsApi(rma.referenceNumber).get().as[ReturnResponse.Root].state must === (Pending) - def state(s: State, reasonId: Option[Int] = None) = { + def state(s: State, reasonId: Option[Int] = None) = ReturnUpdateStatePayload(state = s, reasonId = reasonId) - } returnsApi(rma.referenceNumber) .update(state(Processing)) @@ -142,15 +137,14 @@ class ReturnIntegrationTest returnsApi(rma.referenceNumber) .update(state(Pending)) - .mustFailWith400( - StateTransitionNotAllowed(Return, "Complete", "Pending", rma.referenceNumber)) + .mustFailWith400(StateTransitionNotAllowed(Return, "Complete", "Pending", rma.referenceNumber)) } "gift cards and store credits should be activated on complete state" in new ReturnLineItemDefaults with ReturnPaymentFixture { val payments = createReturnPayments(Map( - PaymentMethod.GiftCard → 100, - PaymentMethod.StoreCredit → 150 + PaymentMethod.GiftCard → 100, + PaymentMethod.StoreCredit → 150 ), refNum = rma.referenceNumber).payments val gcApi = giftCardsApi(payments.giftCard.value.code) @@ -167,8 +161,8 @@ class ReturnIntegrationTest "gift cards and store credits should be canceled on canceled state" in new ReturnLineItemDefaults with ReturnPaymentFixture { val payments = createReturnPayments(Map( - PaymentMethod.GiftCard → 100, - PaymentMethod.StoreCredit → 150 + PaymentMethod.GiftCard → 100, + PaymentMethod.StoreCredit → 150 ), refNum = rma.referenceNumber).payments val gcApi = giftCardsApi(payments.giftCard.value.code) @@ -178,8 +172,7 @@ class ReturnIntegrationTest scApi.get().as[StoreCreditResponse.Root].state must === (StoreCredit.OnHold) returnsApi(rma.referenceNumber) - .update( - ReturnUpdateStatePayload(state = Canceled, reasonId = cancellationReason.id.some)) + .update(ReturnUpdateStatePayload(state = Canceled, reasonId = cancellationReason.id.some)) .as[ReturnResponse.Root] .payments must === (payments) gcApi.get().as[GiftCardResponse.Root].state must === (GiftCard.Canceled) @@ -203,8 +196,7 @@ class ReturnIntegrationTest } "GET /v1/returns/customer/:id" - { - "should return list of Returns of existing customer" in new ReturnFixture - with OrderDefaults { + "should return list of Returns of existing customer" in new ReturnFixture with OrderDefaults { val expected = createReturn(order.referenceNumber) val root = returnsApi.getByCustomer(customer.accountId).as[Seq[ReturnResponse.Root]] root.size must === (1) @@ -252,8 +244,8 @@ class ReturnIntegrationTest } "fails if message is too long" in new ReturnDefaults { - val payload = ReturnMessageToCustomerPayload( - message = List.fill(messageToAccountMaxLength)("Yax").mkString) + val payload = + ReturnMessageToCustomerPayload(message = List.fill(messageToAccountMaxLength)("Yax").mkString) returnsApi(rma.referenceNumber) .message(payload) .mustFailWith400(GeneralFailure("Message length got 3000, expected 1000 or less")) @@ -290,17 +282,17 @@ class ReturnIntegrationTest "POST /v1/returns/:refNum/line-items" - { "successfully adds shipping cost line item" in new ReturnDefaults with ReturnReasonDefaults { - val payload = ReturnShippingCostLineItemPayload(amount = order.totals.shipping, - reasonId = returnReason.id) + val payload = + ReturnShippingCostLineItemPayload(amount = order.totals.shipping, reasonId = returnReason.id) returnsApi(rma.referenceNumber).lineItems .add(payload) .as[ReturnResponse.Root] .lineItems .shippingCosts .value must have( - 'name (shippingMethod.adminDisplayName), - 'amount (order.totals.shipping), - 'price (shippingMethod.price) + 'name (shippingMethod.adminDisplayName), + 'amount (order.totals.shipping), + 'price (shippingMethod.price) ) } @@ -314,19 +306,19 @@ class ReturnIntegrationTest .lineItems .skus .onlyElement must have( - 'sku (product.code), - 'title (product.title), - 'imagePath (product.image), - 'quantity (1), - 'price (product.price), - 'currency (product.currency) + 'sku (product.code), + 'title (product.title), + 'imagePath (product.image), + 'quantity (1), + 'price (product.price), + 'currency (product.currency) ) } "overwrites existing shipping cost" in new ReturnLineItemFixture with ReturnDefaults with ReturnReasonDefaults { - val payload = ReturnShippingCostLineItemPayload(amount = order.totals.shipping, - reasonId = returnReason.id) + val payload = + ReturnShippingCostLineItemPayload(amount = order.totals.shipping, reasonId = returnReason.id) val first = createReturnLineItem(payload, rma.referenceNumber) first.lineItems.shippingCosts.value.amount must === (order.totals.shipping) @@ -338,8 +330,8 @@ class ReturnIntegrationTest with ReturnReasonDefaults with OrderDefaults { val secondProduct = Mvp.insertProduct(ctx.id, Factories.products.tail.head).gimme override val order = createDefaultOrder( - items = List(UpdateLineItemsPayload(sku = product.code, quantity = 1), - UpdateLineItemsPayload(sku = secondProduct.code, quantity = 1))) + items = List(UpdateLineItemsPayload(sku = product.code, quantity = 1), + UpdateLineItemsPayload(sku = secondProduct.code, quantity = 1))) val rma = createReturn(orderRef = order.referenceNumber) val api = returnsApi(rma.referenceNumber).lineItems @@ -347,23 +339,20 @@ class ReturnIntegrationTest val payload = ReturnSkuLineItemPayload(sku = product.code, quantity = 1, reasonId = returnReason.id) api.add(payload).as[ReturnResponse.Root].lineItems.skus.onlyElement must have( - 'sku (product.code), - 'quantity (1) + 'sku (product.code), + 'quantity (1) ) - createReturnLineItem(ReturnShippingCostLineItemPayload(amount = 300, - reasonId = returnReason.id), + createReturnLineItem(ReturnShippingCostLineItemPayload(amount = 300, reasonId = returnReason.id), rma.referenceNumber) - val payloads = List( - ReturnSkuLineItemPayload(sku = secondProduct.code, - quantity = 1, - reasonId = returnReason.id)) + val payloads = + List(ReturnSkuLineItemPayload(sku = secondProduct.code, quantity = 1, reasonId = returnReason.id)) val response = api.addOrReplace(payloads).as[ReturnResponse.Root].lineItems response.shippingCosts mustBe 'defined response.skus.onlyElement must have( - 'sku (secondProduct.code), - 'quantity (1) + 'sku (secondProduct.code), + 'quantity (1) ) } @@ -410,13 +399,11 @@ class ReturnIntegrationTest returnsApi(rma.referenceNumber).lineItems .add(payload) - .mustFailWith400(ReturnSkuItemQuantityExceeded(rma.referenceNumber, - quantity = payload.quantity, - maxQuantity = 0)) + .mustFailWith400( + ReturnSkuItemQuantityExceeded(rma.referenceNumber, quantity = payload.quantity, maxQuantity = 0)) } - "fails if amount for shipping cost is less then 0" in new ReturnDefaults - with ReturnReasonDefaults { + "fails if amount for shipping cost is less then 0" in new ReturnDefaults with ReturnReasonDefaults { val payload = ReturnShippingCostLineItemPayload(amount = -666, reasonId = returnReason.id) returnsApi(rma.referenceNumber).lineItems @@ -426,8 +413,8 @@ class ReturnIntegrationTest "fails if amount for shipping cost is more then maximum allowed amount" in new ReturnLineItemFixture with ReturnDefaults with ReturnReasonDefaults { - val payload = ReturnShippingCostLineItemPayload(amount = order.totals.shipping, - reasonId = returnReason.id) + val payload = + ReturnShippingCostLineItemPayload(amount = order.totals.shipping, reasonId = returnReason.id) // create some other return for different order val otherOrderRef = createDefaultOrder().referenceNumber @@ -442,9 +429,10 @@ class ReturnIntegrationTest returnsApi(rma.referenceNumber).lineItems .add(payload) - .mustFailWith400(ReturnShippingCostExceeded(rma.referenceNumber, - amount = payload.amount, - maxAmount = order.totals.shipping - 25)) + .mustFailWith400( + ReturnShippingCostExceeded(rma.referenceNumber, + amount = payload.amount, + maxAmount = order.totals.shipping - 25)) } } @@ -485,9 +473,8 @@ class ReturnIntegrationTest forAll(paymentMethodTable) { paymentMethod ⇒ val order = createDefaultOrder() val rma = createReturn(orderRef = order.referenceNumber) - val shippingCostPayload = ReturnShippingCostLineItemPayload(amount = - order.totals.shipping, - reasonId = returnReason.id) + val shippingCostPayload = + ReturnShippingCostLineItemPayload(amount = order.totals.shipping, reasonId = returnReason.id) createReturnLineItem(shippingCostPayload, rma.referenceNumber) val payload = ReturnPaymentPayload(amount = shippingCostPayload.amount) @@ -513,9 +500,9 @@ class ReturnIntegrationTest "Apple Pay charges should be taken into account" in new ReturnPaymentDefaults { val apRma = createReturn( - createDefaultOrder( - paymentMethods = Map(PaymentMethod.ApplePay → None) - ).referenceNumber) + createDefaultOrder( + paymentMethods = Map(PaymentMethod.ApplePay → None) + ).referenceNumber) createReturnLineItem(shippingCostPayload, apRma.referenceNumber) createReturnLineItem(skuPayload, apRma.referenceNumber) @@ -527,43 +514,41 @@ class ReturnIntegrationTest .as[ReturnResponse.Root] .payments .asMap - .mapValues(_.amount) must === ( - Map[PaymentMethod.Type, Long](PaymentMethod.ApplePay → 50)) + .mapValues(_.amount) must === (Map[PaymentMethod.Type, Long](PaymentMethod.ApplePay → 50)) } "bulk insert should override any existing payments, whilst single addition endpoint should append payment to existing ones" in - new ReturnPaymentDefaults { - val api = returnsApi(rma.referenceNumber).paymentMethods - - api - .add(PaymentMethod.GiftCard, ReturnPaymentPayload(130)) - .as[ReturnResponse.Root] - .payments - .asMap - .mapValues(_.amount) must === ( - Map[PaymentMethod.Type, Long](PaymentMethod.GiftCard → 130)) - - val payload = ReturnPaymentsPayload( - Map(PaymentMethod.CreditCard → 100, PaymentMethod.StoreCredit → 120)) - val response = api.addOrReplace(payload).as[ReturnResponse.Root] - response.payments.asMap.mapValues(_.amount) must === (payload.payments) - mustProduceActivity(ReturnPaymentsDeleted(response, List(PaymentMethod.GiftCard))) + new ReturnPaymentDefaults { + val api = returnsApi(rma.referenceNumber).paymentMethods - api - .add(PaymentMethod.StoreCredit, ReturnPaymentPayload(50)) - .as[ReturnResponse.Root] - .payments - .asMap - .mapValues(_.amount) must === (payload.payments + (PaymentMethod.StoreCredit → 50L)) + api + .add(PaymentMethod.GiftCard, ReturnPaymentPayload(130)) + .as[ReturnResponse.Root] + .payments + .asMap + .mapValues(_.amount) must === (Map[PaymentMethod.Type, Long](PaymentMethod.GiftCard → 130)) + + val payload = + ReturnPaymentsPayload(Map(PaymentMethod.CreditCard → 100, PaymentMethod.StoreCredit → 120)) + val response = api.addOrReplace(payload).as[ReturnResponse.Root] + response.payments.asMap.mapValues(_.amount) must === (payload.payments) + mustProduceActivity(ReturnPaymentsDeleted(response, List(PaymentMethod.GiftCard))) + + api + .add(PaymentMethod.StoreCredit, ReturnPaymentPayload(50)) + .as[ReturnResponse.Root] + .payments + .asMap + .mapValues(_.amount) must === (payload.payments + (PaymentMethod.StoreCredit → 50L)) - api - .add(PaymentMethod.GiftCard, ReturnPaymentPayload(80)) - .as[ReturnResponse.Root] - .payments - .asMap - .mapValues(_.amount) must === ( + api + .add(PaymentMethod.GiftCard, ReturnPaymentPayload(80)) + .as[ReturnResponse.Root] + .payments + .asMap + .mapValues(_.amount) must === ( payload.payments + (PaymentMethod.StoreCredit → 50) + (PaymentMethod.GiftCard → 80)) - } + } "fails if the amount is less than zero" in new ReturnPaymentFixture with OrderDefaults { forAll(paymentMethodTable) { paymentType ⇒ @@ -586,13 +571,12 @@ class ReturnIntegrationTest } "fails if total payment exceeds returns items subtotal" in new ReturnPaymentDefaults { - val payload = ReturnPaymentsPayload( - Map(PaymentMethod.CreditCard → 3000, PaymentMethod.StoreCredit → 1500)) + val payload = + ReturnPaymentsPayload(Map(PaymentMethod.CreditCard → 3000, PaymentMethod.StoreCredit → 1500)) returnsApi(rma.referenceNumber).paymentMethods .addOrReplace(payload) - .mustFailWith400( - ReturnPaymentExceeded(rma.referenceNumber, amount = 4500, maxAmount = 3600)) + .mustFailWith400(ReturnPaymentExceeded(rma.referenceNumber, amount = 4500, maxAmount = 3600)) } "fails if cc payment exceeds order cc payment minus any previously returned cc payments" in new ReturnPaymentFixture @@ -602,8 +586,8 @@ class ReturnIntegrationTest override val storeCredit = api_newStoreCredit(customer.accountId, CreateManualStoreCredit(amount = scAmount, reasonId = reason.id)) - override val order = createDefaultOrder( - Map(PaymentMethod.CreditCard → None, PaymentMethod.StoreCredit → Some(scAmount))) + override val order = + createDefaultOrder(Map(PaymentMethod.CreditCard → None, PaymentMethod.StoreCredit → Some(scAmount))) def createPayload(amount: Long) = ReturnShippingCostLineItemPayload(amount = amount, reasonId = returnReason.id) @@ -628,17 +612,18 @@ class ReturnIntegrationTest returnsApi(rma.referenceNumber).paymentMethods .add(PaymentMethod.CreditCard, ReturnPaymentPayload(maxCCAmount)) - .mustFailWith400(ReturnCcPaymentExceeded(rma.referenceNumber, - amount = payload.amount, - maxAmount = maxCCAmount - 25)) + .mustFailWith400( + ReturnCcPaymentExceeded(rma.referenceNumber, + amount = payload.amount, + maxAmount = maxCCAmount - 25)) } } "DELETE /v1/returns/:ref/payment-methods/credit-cards" - { "successfully delete any supported payment method" in new ReturnPaymentDefaults { val payments = createReturnPayments(Map( - PaymentMethod.GiftCard → 100, - PaymentMethod.StoreCredit → 150 + PaymentMethod.GiftCard → 100, + PaymentMethod.StoreCredit → 150 ), refNum = rma.referenceNumber).payments diff --git a/phoenix-scala/phoenix/test/integration/SharedSearchIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/SharedSearchIntegrationTest.scala index 63d649d64a..975d62e56e 100644 --- a/phoenix-scala/phoenix/test/integration/SharedSearchIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/SharedSearchIntegrationTest.scala @@ -71,8 +71,7 @@ class SharedSearchIntegrationTest "returns associated scopes created by different admins" in new SharedSearchAssociationFixture { SharedSearchAssociations - .create( - SharedSearchAssociation(sharedSearchId = search.id, storeAdminId = defaultAdmin.id)) + .create(SharedSearchAssociation(sharedSearchId = search.id, storeAdminId = defaultAdmin.id)) .gimme getByScope("customersScope") must === (Seq(search)) @@ -217,8 +216,7 @@ class SharedSearchIntegrationTest "GET v1/shared-search/:code/associates" - { "returns associates by code" in new AssociateSecondaryFixture { - sharedSearchApi(search.code).associates().as[Seq[UserRoot]].onlyElement.id must === ( - defaultAdmin.id) + sharedSearchApi(search.code).associates().as[Seq[UserRoot]].onlyElement.id must === (defaultAdmin.id) } "returns multiple associates by code" in new AssociateSecondaryFixture { @@ -339,12 +337,12 @@ class SharedSearchIntegrationTest } val search = (for { search ← * <~ SharedSearches.create( - SharedSearch(title = "Test", - query = dummyJVal, - rawQuery = dummyJVal, - scope = CustomersScope, - storeAdminId = secondAdminId, - accessScope = scope)) + SharedSearch(title = "Test", + query = dummyJVal, + rawQuery = dummyJVal, + scope = CustomersScope, + storeAdminId = secondAdminId, + accessScope = scope)) secondAdmin ← * <~ Users.mustFindByAccountId(secondAdminId) _ ← * <~ SharedSearchAssociations.create(buildAssociation(search, secondAdmin)) } yield search).gimme diff --git a/phoenix-scala/phoenix/test/integration/ShippingMethodsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/ShippingMethodsIntegrationTest.scala index 889b35d130..b9430631d4 100644 --- a/phoenix-scala/phoenix/test/integration/ShippingMethodsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/ShippingMethodsIntegrationTest.scala @@ -35,8 +35,8 @@ class ShippingMethodsIntegrationTest "Evaluates shipping rule: order total is greater than $25" - { "Shipping method is returned when actual order total is greater than $25" in new ShippingMethodsFixture { - val conditions = parse( - """ + val conditions = + parse(""" | { | "comparison": "and", | "conditions": [{ @@ -59,8 +59,8 @@ class ShippingMethodsIntegrationTest "Evaluates shipping rule: order total is greater than $100" - { "No shipping rules found when order total is less than $100" in new ShippingMethodsFixture { - val conditions = parse( - """ + val conditions = + parse(""" | { | "comparison": "and", | "conditions": [{ @@ -173,9 +173,8 @@ class ShippingMethodsIntegrationTest val (address, orderShippingAddress) = (for { productContext ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) address ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, regionId = californiaId)) - shipAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, - cordRef = cart.refNum) + Factories.address.copy(accountId = customer.accountId, regionId = californiaId)) + shipAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) product ← * <~ Mvp.insertProduct(productContext.id, Factories.products.head.copy(title = "Donkey", price = 27)) _ ← * <~ CartLineItems.create(CartLineItem(cordRef = cart.refNum, skuId = product.skuId)) @@ -294,8 +293,8 @@ class ShippingMethodsIntegrationTest val shippingMethod = (for { shippingMethod ← shipping.ShippingMethods.create( - Factories.shippingMethods.head.copy(conditions = Some(conditions), - restrictions = Some(restrictions))) + Factories.shippingMethods.head.copy(conditions = Some(conditions), + restrictions = Some(restrictions))) } yield shippingMethod).gimme } diff --git a/phoenix-scala/phoenix/test/integration/SkuIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/SkuIntegrationTest.scala index f6a3a9f90e..f4e2c8a173 100644 --- a/phoenix-scala/phoenix/test/integration/SkuIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/SkuIntegrationTest.scala @@ -34,14 +34,15 @@ trait SkuOps { self: PhoenixAdminApi with DefaultJwtAdminAuth ⇒ import org.json4s._ val skuResponse = skusApi(skuCode).get().as[SkuResponse.Root] val activeFromJson: Json = ("t" → "date") ~ ("v" → (Instant.now - .minus(2, ChronoUnit.DAYS)) - .toString) + .minus(2, ChronoUnit.DAYS)) + .toString) val activeToJson: Json = ("t" → "date") ~ ("v" → (Instant.now - .minus(1, ChronoUnit.DAYS)) - .toString) + .minus(1, ChronoUnit.DAYS)) + .toString) skusApi(skuCode) - .update(SkuPayload(attributes = skuResponse.attributes.extract[Map[String, Json]] ++ - Map("activeFrom" → activeFromJson, "activeTo" → activeToJson))) + .update( + SkuPayload(attributes = skuResponse.attributes.extract[Map[String, Json]] ++ + Map("activeFrom" → activeFromJson, "activeTo" → activeToJson))) .mustBeOk() } @@ -56,7 +57,7 @@ class SkuIntegrationTest "POST v1/skus/:context" - { "Creates a SKU successfully" in new Fixture { val priceValue = ("currency" → "USD") ~ ("value" → 9999) - val priceJson = ("t" → "price") ~ ("v" → priceValue) + val priceJson = ("t" → "price") ~ ("v" → priceValue) val attrMap = Map("price" → priceJson) skusApi.create(makeSkuPayload("SKU-NEW-TEST", attrMap, None)).mustBeOk() @@ -64,7 +65,7 @@ class SkuIntegrationTest "Tries to create a SKU with no code" in new Fixture { val priceValue = ("currency" → "USD") ~ ("value" → 9999) - val priceJson = ("t" → "price") ~ ("v" → priceValue) + val priceJson = ("t" → "price") ~ ("v" → priceValue) val attrMap = Map("price" → priceJson) skusApi @@ -175,9 +176,7 @@ class SkuIntegrationTest } trait Fixture extends StoreAdmin_Seed { - def makeSkuPayload(code: String, - attrMap: Map[String, Json], - albums: Option[Seq[AlbumPayload]] = None) = { + def makeSkuPayload(code: String, attrMap: Map[String, Json], albums: Option[Seq[AlbumPayload]] = None) = { val codeJson = ("t" → "string") ~ ("v" → code) val attributes = attrMap + ("code" → codeJson) SkuPayload(attributes = attributes, albums = albums) @@ -188,15 +187,14 @@ class SkuIntegrationTest skuForm ← * <~ ObjectForms.create(simpleSku.create) simpleSkuShadow ← * <~ SimpleSkuShadow(simpleSku) skuShadow ← * <~ ObjectShadows.create(simpleSkuShadow.create.copy(formId = skuForm.id)) - skuCommit ← * <~ ObjectCommits.create( - ObjectCommit(formId = skuForm.id, shadowId = skuShadow.id)) + skuCommit ← * <~ ObjectCommits.create(ObjectCommit(formId = skuForm.id, shadowId = skuShadow.id)) sku ← * <~ Skus.create( - Sku(scope = Scope.current, - contextId = ctx.id, - code = simpleSku.code, - formId = skuForm.id, - shadowId = skuShadow.id, - commitId = skuCommit.id)) + Sku(scope = Scope.current, + contextId = ctx.id, + code = simpleSku.code, + formId = skuForm.id, + shadowId = skuShadow.id, + commitId = skuCommit.id)) } yield (sku, skuForm, skuShadow)).gimme } diff --git a/phoenix-scala/phoenix/test/integration/StoreAdminIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/StoreAdminIntegrationTest.scala index 6f1a0e4e93..bc16f42826 100644 --- a/phoenix-scala/phoenix/test/integration/StoreAdminIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/StoreAdminIntegrationTest.scala @@ -106,10 +106,11 @@ class StoreAdminIntegrationTest "respond with 400 when cannot apply new state" in new Fixture { storeAdminsApi(storeAdmin.accountId) .updateState(StateChangeStoreAdminPayload(state = AdminData.Invited)) - .mustFailWith400(StateTransitionNotAllowed(AdminData, - storeAdminUser.state.toString, - AdminData.Invited.toString, - storeAdminUser.id)) + .mustFailWith400( + StateTransitionNotAllowed(AdminData, + storeAdminUser.state.toString, + AdminData.Invited.toString, + storeAdminUser.id)) } "respond with 404 when id does not point to valid admin" in new Fixture { diff --git a/phoenix-scala/phoenix/test/integration/StoreCreditIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/StoreCreditIntegrationTest.scala index 70f27ae6ee..c775d26c97 100644 --- a/phoenix-scala/phoenix/test/integration/StoreCreditIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/StoreCreditIntegrationTest.scala @@ -7,7 +7,7 @@ import phoenix.models.cord.OrderPayments import phoenix.models.payment.giftcard.GiftCard import phoenix.models.payment.storecredit.StoreCredit._ import phoenix.models.payment.storecredit._ -import phoenix.models.payment.{InStorePaymentStates, PaymentMethod, giftcard} +import phoenix.models.payment.{giftcard, InStorePaymentStates, PaymentMethod} import phoenix.payloads.PaymentPayloads.CreateManualStoreCredit import phoenix.payloads.StoreCreditPayloads._ import phoenix.responses.StoreCreditResponse.Root @@ -44,17 +44,14 @@ class StoreCreditIntegrationTest "succeeds with valid subTypeId" in new Fixture { customersApi(customer.accountId).payments.storeCredit - .create(CreateManualStoreCredit(amount = 25, - reasonId = reason.id, - subTypeId = Some(scSubType.id))) + .create(CreateManualStoreCredit(amount = 25, reasonId = reason.id, subTypeId = Some(scSubType.id))) .as[Root] .subTypeId must === (Some(scSubType.id)) } "fails if subtypeId is not found" in new Fixture { customersApi(customer.accountId).payments.storeCredit - .create( - CreateManualStoreCredit(amount = 25, reasonId = reason.id, subTypeId = Some(255))) + .create(CreateManualStoreCredit(amount = 25, reasonId = reason.id, subTypeId = Some(255))) .mustFailWith400(NotFoundFailure404(StoreCreditSubtype, 255)) } @@ -157,8 +154,8 @@ class StoreCreditIntegrationTest "PATCH /v1/store-credits" - { "successfully changes statuses of multiple store credits" in new Fixture { val payload = StoreCreditBulkUpdateStateByCsr( - ids = Seq(storeCredit.id, scSecond.id), - state = StoreCredit.OnHold + ids = Seq(storeCredit.id, scSecond.id), + state = StoreCredit.OnHold ) storeCreditsApi.update(payload).mustBeOk() @@ -172,8 +169,8 @@ class StoreCreditIntegrationTest "returns multiple errors if no cancellation reason provided" in new Fixture { val payload = StoreCreditBulkUpdateStateByCsr( - ids = Seq(storeCredit.id, scSecond.id), - state = StoreCredit.Canceled + ids = Seq(storeCredit.id, scSecond.id), + state = StoreCredit.Canceled ) storeCreditsApi.update(payload).mustFailWith400(EmptyCancellationReasonFailure) @@ -234,18 +231,16 @@ class StoreCreditIntegrationTest val (storeCredit, adjustment, scSecond, payment, scSubType) = (for { scSubType ← * <~ StoreCreditSubtypes.create(Factories.storeCreditSubTypes.head) scOrigin ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) storeCredit ← * <~ StoreCredits.create( - Factories.storeCredit.copy(originId = scOrigin.id, - accountId = customer.accountId)) + Factories.storeCredit.copy(originId = scOrigin.id, accountId = customer.accountId)) scSecond ← * <~ StoreCredits.create( - Factories.storeCredit.copy(originId = scOrigin.id, - accountId = customer.accountId)) + Factories.storeCredit.copy(originId = scOrigin.id, accountId = customer.accountId)) payment ← * <~ OrderPayments.create( - Factories.storeCreditPayment.copy(cordRef = cart.refNum, - paymentMethodId = storeCredit.id, - paymentMethodType = PaymentMethod.StoreCredit, - amount = Some(storeCredit.availableBalance))) + Factories.storeCreditPayment.copy(cordRef = cart.refNum, + paymentMethodId = storeCredit.id, + paymentMethodType = PaymentMethod.StoreCredit, + amount = Some(storeCredit.availableBalance))) adjustment ← * <~ StoreCredits.auth(storeCredit, payment.id, 10) } yield (storeCredit, adjustment, scSecond, payment, scSubType)).gimme } diff --git a/phoenix-scala/phoenix/test/integration/TaxonomyIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/TaxonomyIntegrationTest.scala index 112c9b5d69..ca3bc497b6 100644 --- a/phoenix-scala/phoenix/test/integration/TaxonomyIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/TaxonomyIntegrationTest.scala @@ -29,7 +29,7 @@ class TaxonomyIntegrationTest taxons .find(_.node.id == id) .orElse( - taxons.map(t ⇒ findTaxonsById(t.childrenAsList.toList, id)).find(_.isDefined).flatten + taxons.map(t ⇒ findTaxonsById(t.childrenAsList.toList, id)).find(_.isDefined).flatten ) def queryGetTaxonomy(formId: Int): FullTaxonomyResponse = @@ -49,12 +49,11 @@ class TaxonomyIntegrationTest response.id must === (taxonomy.formId) response.taxons.map(tree ⇒ (tree.node.attributes \ "name" \ "v").extract[String]) must === ( - Seq("taxon1", "taxon2")) - response.taxons.head.childrenAsList.map(tree ⇒ - (tree.node.attributes \ "name" \ "v").extract[String]) must === ( - Seq("taxon3", "taxon4")) + Seq("taxon1", "taxon2")) + response.taxons.head.childrenAsList + .map(tree ⇒ (tree.node.attributes \ "name" \ "v").extract[String]) must === (Seq("taxon3", "taxon4")) response.taxons.head.childrenAsList.head.childrenAsList.map(tree ⇒ - (tree.node.attributes \ "name" \ "v").extract[String]) must === (Seq("taxon7")) + (tree.node.attributes \ "name" \ "v").extract[String]) must === (Seq("taxon7")) } } @@ -125,14 +124,14 @@ class TaxonomyIntegrationTest taxonsResp.size must === (1) taxonsResp.head.node.id must === (response.id) (taxonsResp.head.node.attributes \ "name" \ "v").extract[String] must === ( - (response.attributes \ "name" \ "v").extract[String]) + (response.attributes \ "name" \ "v").extract[String]) } "creates taxon at position" in new FlatTaxonsFixture { val response = taxonomiesApi(taxonomy.formId) - .createTaxon(CreateTaxonPayload(taxonAttributes, - location = TaxonLocationPayload(parent = None, - position = 1.some).some)) + .createTaxon( + CreateTaxonPayload(taxonAttributes, + location = TaxonLocationPayload(parent = None, position = 1.some).some)) .as[FullTaxonResponse] val newTaxons = queryGetTaxonomy(taxonomy.formId).taxons @@ -145,8 +144,7 @@ class TaxonomyIntegrationTest "creates taxon at last position" in new FlatTaxonsFixture { val response = taxonomiesApi(taxonomy.formId) .createTaxon(CreateTaxonPayload(taxonAttributes, - location = TaxonLocationPayload(parent = None, - position = None).some)) + location = TaxonLocationPayload(parent = None, position = None).some)) .as[FullTaxonResponse] val newTaxons = queryGetTaxonomy(taxonomy.formId).taxons @@ -165,8 +163,8 @@ class TaxonomyIntegrationTest val parentFormId = Taxons.mustFindById404(parent.taxonId).gimme.formId val response = taxonomiesApi(taxonomy.formId) - .createTaxon(CreateTaxonPayload(taxonAttributes, - TaxonLocationPayload(parentFormId.some, Some(0)).some)) + .createTaxon( + CreateTaxonPayload(taxonAttributes, TaxonLocationPayload(parentFormId.some, Some(0)).some)) .as[FullTaxonResponse] val newTaxons = queryGetTaxonomy(taxonomy.formId).taxons @@ -182,9 +180,8 @@ class TaxonomyIntegrationTest val parentFormId = Taxons.mustFindById404(parent.taxonId).gimme.formId val resp = taxonomiesApi(taxonomy.formId).createTaxon( - CreateTaxonPayload( - taxonAttributes, - Some(TaxonLocationPayload(Some(parentFormId), Some(Integer.MAX_VALUE))))) + CreateTaxonPayload(taxonAttributes, + Some(TaxonLocationPayload(Some(parentFormId), Some(Integer.MAX_VALUE))))) resp.status must === (StatusCodes.BadRequest) resp.error must === (NoTaxonAtPosition(parentFormId.some, Integer.MAX_VALUE).description) @@ -200,7 +197,7 @@ class TaxonomyIntegrationTest val newParentId = right.node.id val resp = taxonsApi(taxonToMoveId).update( - UpdateTaxonPayload(Map(), TaxonLocationPayload(newParentId.some, Some(0)).some)) + UpdateTaxonPayload(Map(), TaxonLocationPayload(newParentId.some, Some(0)).some)) resp.status must === (StatusCodes.OK) val taxonsAfter = queryGetTaxonomy(taxonomy.formId).taxons @@ -220,7 +217,7 @@ class TaxonomyIntegrationTest val taxonToMoveId = left.node.id val resp = taxonsApi(taxonToMoveId).update( - UpdateTaxonPayload(Map(), TaxonLocationPayload(newParentId.some, Some(0)).some)) + UpdateTaxonPayload(Map(), TaxonLocationPayload(newParentId.some, Some(0)).some)) resp.status must === (StatusCodes.BadRequest) resp.error must === (CannotMoveParentTaxonUnderChild.description) } @@ -266,19 +263,19 @@ class TaxonomyIntegrationTest activeTo: Option[String], archivedAt: Option[String]) implicit val getTaxonomiesSearchViewResult = GetResult( - r ⇒ - TaxonomiesSearchViewItem(r.nextInt, - r.nextInt, - r.nextString, - r.nextString, - r.nextString, - r.nextInt, - r.nextStringOption(), - r.nextStringOption(), - r.nextStringOption())) + r ⇒ + TaxonomiesSearchViewItem(r.nextInt, + r.nextInt, + r.nextString, + r.nextString, + r.nextString, + r.nextInt, + r.nextStringOption(), + r.nextStringOption(), + r.nextStringOption())) def selectByTaxonId(taxonomy_id: Int) = - sql"""select * from taxonomies_search_view where taxonomy_id = ${taxonomy_id}""" + sql"""select * from taxonomies_search_view where taxonomy_id = $taxonomy_id""" .as[TaxonomiesSearchViewItem] .gimme @@ -288,11 +285,11 @@ class TaxonomyIntegrationTest taxonomies.size must === (1) val item = taxonomies.head item must === ( - item.copy(taxonomyId = taxonomy.formId, - context = ctx.name, - `type` = "hierarchical", - valuesCount = taxons.size, - archivedAt = None)) + item.copy(taxonomyId = taxonomy.formId, + context = ctx.name, + `type` = "hierarchical", + valuesCount = taxons.size, + archivedAt = None)) } "should update data on taxon removal" in new HierarchyTaxonsFixture { @@ -303,11 +300,11 @@ class TaxonomyIntegrationTest taxonomies.size must === (1) val item = taxonomies.head item must === ( - item.copy(taxonomyId = taxonomy.formId, - context = ctx.name, - `type` = "hierarchical", - valuesCount = taxons.size - 1, - archivedAt = None)) + item.copy(taxonomyId = taxonomy.formId, + context = ctx.name, + `type` = "hierarchical", + valuesCount = taxons.size - 1, + archivedAt = None)) } "should update taxonomy name" in new HierarchyTaxonsFixture { diff --git a/phoenix-scala/phoenix/test/integration/VariantIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/VariantIntegrationTest.scala index 976c390e93..753f997507 100644 --- a/phoenix-scala/phoenix/test/integration/VariantIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/VariantIntegrationTest.scala @@ -68,9 +68,8 @@ class VariantIntegrationTest "PATCH v1/variants/:context/:id" - { "Updates the name of the variant successfully" in new VariantFixture { - val payload = VariantPayload(values = None, - attributes = - Map("name" → (("t" → "wtring") ~ ("v" → "New Size")))) + val payload = + VariantPayload(values = None, attributes = Map("name" → (("t" → "wtring") ~ ("v" → "New Size")))) val response = variantsApi(variant.variant.variantFormId).update(payload).as[VariantRoot] response.values.length must === (2) @@ -81,13 +80,11 @@ class VariantIntegrationTest "Fails when trying to attach archived SKU to the variant" in new ArchivedSkusFixture { var payload = VariantPayload(values = Some(Seq(archivedSkuVariantValuePayload)), - attributes = - Map("name" → (("t" → "wtring") ~ ("v" → "New Size")))) + attributes = Map("name" → (("t" → "wtring") ~ ("v" → "New Size")))) variantsApi(variant.variant.variantFormId) .update(payload) - .mustFailWith400( - LinkInactiveSkuFailure(Variant, variant.variant.variantFormId, archivedSkuCode)) + .mustFailWith400(LinkInactiveSkuFailure(Variant, variant.variant.variantFormId, archivedSkuCode)) } } @@ -114,9 +111,8 @@ class VariantIntegrationTest trait Fixture extends StoreAdmin_Seed { val scope = Scope.current - val createVariantPayload = VariantPayload(attributes = - Map("name" → (("t" → "string") ~ ("v" → "Color"))), - values = None) + val createVariantPayload = + VariantPayload(attributes = Map("name" → (("t" → "string") ~ ("v" → "Color"))), values = None) val testSkus = Seq(SimpleSku("SKU-TST", "SKU test", 1000, Currency.USD, active = true), SimpleSku("SKU-TS2", "SKU test 2", 1000, Currency.USD, active = true)) @@ -124,10 +120,10 @@ class VariantIntegrationTest val skus = Mvp.insertSkus(scope, ctx.id, testSkus).gimme val createVariantValuePayload = VariantValuePayload( - name = Some("Red"), - swatch = Some("ff0000"), - image = Some("http://t.fod4.com/t/2e6ea38d82/c640x360_1.jpg"), - skuCodes = Seq(skus.head.code)) + name = Some("Red"), + swatch = Some("ff0000"), + image = Some("http://t.fod4.com/t/2e6ea38d82/c640x360_1.jpg"), + skuCodes = Seq(skus.head.code)) } trait VariantFixture extends Fixture { @@ -138,10 +134,10 @@ class VariantIntegrationTest price = 5999, active = true) - val simpleSizeVariant = SimpleCompleteVariant( - variant = SimpleVariant("Size"), - variantValues = Seq(SimpleVariantValue("Small", "", Seq(skus.head.code)), - SimpleVariantValue("Large", "", Seq(skus(1).code)))) + val simpleSizeVariant = SimpleCompleteVariant(variant = SimpleVariant("Size"), + variantValues = + Seq(SimpleVariantValue("Small", "", Seq(skus.head.code)), + SimpleVariantValue("Large", "", Seq(skus(1).code)))) val (product, variant) = (for { productData ← * <~ Mvp.insertProduct(ctx.id, simpleProd) diff --git a/phoenix-scala/phoenix/test/integration/models/CartsIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/models/CartsIntegrationTest.scala index d920b08be6..fa4a281945 100644 --- a/phoenix-scala/phoenix/test/integration/models/CartsIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/models/CartsIntegrationTest.scala @@ -13,13 +13,9 @@ class CartsIntegrationTest extends IntegrationTestBase with TestObjectContext wi cart2.referenceNumber must !==(cart.referenceNumber) } - "doesn't overwrite a non-empty referenceNumber after insert" in new Customer_Seed - with StoreAdmin_Seed { + "doesn't overwrite a non-empty referenceNumber after insert" in new Customer_Seed with StoreAdmin_Seed { val cart = Carts - .create( - Cart(accountId = customer.accountId, - scope = Scope.current, - referenceNumber = "R123456")) + .create(Cart(accountId = customer.accountId, scope = Scope.current, referenceNumber = "R123456")) .gimme cart.referenceNumber must === ("R123456") } @@ -29,16 +25,14 @@ class CartsIntegrationTest extends IntegrationTestBase with TestObjectContext wi val failure = Carts.create(cart.copy(id = 0, referenceNumber = cart.refNum + "ZZZ")).gimmeFailures - failure.getMessage must include( - """value violates unique constraint "customer_has_only_one_cart"""") + failure.getMessage must include("""value violates unique constraint "customer_has_only_one_cart"""") } "has a unique index on referenceNumber" in new Customer_Seed with StoreAdmin_Seed { val cart = Carts.create(Cart(accountId = customer.accountId, scope = Scope.current)).gimme val failure = Carts.create(cart.copy(id = 0).copy(subTotal = 123)).gimmeFailures - failure.getMessage must include( - """value violates unique constraint "cords_reference_number_key"""") + failure.getMessage must include("""value violates unique constraint "cords_reference_number_key"""") } } } diff --git a/phoenix-scala/phoenix/test/integration/models/CreditCardIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/models/CreditCardIntegrationTest.scala index 84ff5e837a..3060cb0dd6 100644 --- a/phoenix-scala/phoenix/test/integration/models/CreditCardIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/models/CreditCardIntegrationTest.scala @@ -5,16 +5,12 @@ import phoenix.utils.seeds.Factories import testutils._ import testutils.fixtures.BakedFixtures -class CreditCardIntegrationTest - extends IntegrationTestBase - with BakedFixtures - with TestObjectContext { +class CreditCardIntegrationTest extends IntegrationTestBase with BakedFixtures with TestObjectContext { "CreditCard" - { "has only one default per customer" in new Fixture { val anotherDefault = CreditCards.create(cc.copy(id = 0, isDefault = true)).gimmeFailures - anotherDefault.getMessage must include( - "violates unique constraint \"credit_cards_default_idx\"") + anotherDefault.getMessage must include("violates unique constraint \"credit_cards_default_idx\"") } } diff --git a/phoenix-scala/phoenix/test/integration/models/GiftCardAdjustmentIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/models/GiftCardAdjustmentIntegrationTest.scala index 0922327bad..2a4851acee 100644 --- a/phoenix-scala/phoenix/test/integration/models/GiftCardAdjustmentIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/models/GiftCardAdjustmentIntegrationTest.scala @@ -26,10 +26,7 @@ class GiftCardAdjustmentIntegrationTest "only one of credit or debit can be greater than zero" in new Fixture { override def gcPaymentAmount = giftCard.availableBalance val failure = GiftCards - .adjust(giftCard = giftCard, - orderPaymentId = orderPayments.head.id.some, - debit = 50, - credit = 50) + .adjust(giftCard = giftCard, orderPaymentId = orderPayments.head.id.some, debit = 50, credit = 50) .gimmeTxnFailures failure.getMessage must include("""violates check constraint "valid_entry"""") } @@ -95,8 +92,7 @@ class GiftCardAdjustmentIntegrationTest } val finalGc = GiftCards.refresh(giftCard).gimme - (finalGc.originalBalance, finalGc.availableBalance, finalGc.currentBalance) must === ( - (500, 500, 500)) + (finalGc.originalBalance, finalGc.availableBalance, finalGc.currentBalance) must === ((500, 500, 500)) } } diff --git a/phoenix-scala/phoenix/test/integration/models/GiftCardIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/models/GiftCardIntegrationTest.scala index 9a6c9b5428..d1234cf516 100644 --- a/phoenix-scala/phoenix/test/integration/models/GiftCardIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/models/GiftCardIntegrationTest.scala @@ -4,10 +4,7 @@ import phoenix.models.payment.giftcard._ import testutils._ import testutils.fixtures.BakedFixtures -class GiftCardIntegrationTest - extends IntegrationTestBase - with BakedFixtures - with TestObjectContext { +class GiftCardIntegrationTest extends IntegrationTestBase with BakedFixtures with TestObjectContext { "GiftCardTest" - { "generates a unique alpha-numeric code of size 16 upon insert" in new SimpleFixture { @@ -37,8 +34,5 @@ class GiftCardIntegrationTest override def giftCardBalance = 50 } - trait Fixture - extends SimpleFixture - with EmptyCustomerCart_Baked - with CartWithGiftCardOnlyPayment_Raw + trait Fixture extends SimpleFixture with EmptyCustomerCart_Baked with CartWithGiftCardOnlyPayment_Raw } diff --git a/phoenix-scala/phoenix/test/integration/models/StoreCreditAdjustmentIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/models/StoreCreditAdjustmentIntegrationTest.scala index fdedb9e519..938c319554 100644 --- a/phoenix-scala/phoenix/test/integration/models/StoreCreditAdjustmentIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/models/StoreCreditAdjustmentIntegrationTest.scala @@ -20,17 +20,18 @@ class StoreCreditAdjustmentIntegrationTest "debit must be greater than zero" in new Fixture { val (sc, payment) = (for { origin ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) sc ← * <~ StoreCredits.create( - Factories.storeCredit.copy(originId = origin.id, accountId = customer.accountId)) - payment ← * <~ OrderPayments.create(Factories.giftCardPayment - .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(25))) + Factories.storeCredit.copy(originId = origin.id, accountId = customer.accountId)) + payment ← * <~ OrderPayments.create( + Factories.giftCardPayment + .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(25))) } yield (sc, payment)).gimme val adjustments = Table( - "adjustments", - StoreCredits.auth(storeCredit = sc, orderPaymentId = payment.id, amount = -1), - StoreCredits.auth(storeCredit = sc, orderPaymentId = payment.id, amount = 0) + "adjustments", + StoreCredits.auth(storeCredit = sc, orderPaymentId = payment.id, amount = -1), + StoreCredits.auth(storeCredit = sc, orderPaymentId = payment.id, amount = 0) ) forAll(adjustments) { adjustment ⇒ @@ -42,13 +43,13 @@ class StoreCreditAdjustmentIntegrationTest "updates the StoreCredit's currentBalance and availableBalance before insert" in new Fixture { val sc = (for { origin ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) sc ← * <~ StoreCredits.create( - Factories.storeCredit.copy(originalBalance = 500, - originId = origin.id, - accountId = customer.accountId)) - pay ← * <~ OrderPayments.create(Factories.giftCardPayment - .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(500))) + Factories.storeCredit + .copy(originalBalance = 500, originId = origin.id, accountId = customer.accountId)) + pay ← * <~ OrderPayments.create( + Factories.giftCardPayment + .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(500))) _ ← * <~ StoreCredits.auth(storeCredit = sc, orderPaymentId = pay.id, amount = 100) _ ← * <~ StoreCredits.auth(storeCredit = sc, orderPaymentId = pay.id, amount = 50) _ ← * <~ StoreCredits.auth(storeCredit = sc, orderPaymentId = pay.id, amount = 50) @@ -65,13 +66,13 @@ class StoreCreditAdjustmentIntegrationTest "a Postgres trigger updates the adjustment's availableBalance before insert" in new Fixture { val (adj, sc) = (for { origin ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) sc ← * <~ StoreCredits.create( - Factories.storeCredit.copy(originalBalance = 500, - originId = origin.id, - accountId = customer.accountId)) - pay ← * <~ OrderPayments.create(Factories.giftCardPayment - .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(500))) + Factories.storeCredit + .copy(originalBalance = 500, originId = origin.id, accountId = customer.accountId)) + pay ← * <~ OrderPayments.create( + Factories.giftCardPayment + .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(500))) auth ← * <~ StoreCredits.auth(storeCredit = sc, orderPaymentId = pay.id, amount = 50) adj ← * <~ StoreCredits.capture(storeCredit = sc, orderPaymentId = pay.id, amount = 50) adj ← * <~ StoreCreditAdjustments.refresh(adj) @@ -86,13 +87,13 @@ class StoreCreditAdjustmentIntegrationTest "cancels an adjustment and removes its effect on current/available balances" in new Fixture { val (sc, payment) = (for { origin ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) sc ← * <~ StoreCredits.create( - Factories.storeCredit.copy(originalBalance = 500, - originId = origin.id, - accountId = customer.accountId)) - payment ← * <~ OrderPayments.create(Factories.giftCardPayment - .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(500))) + Factories.storeCredit + .copy(originalBalance = 500, originId = origin.id, accountId = customer.accountId)) + payment ← * <~ OrderPayments.create( + Factories.giftCardPayment + .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(500))) } yield (sc, payment)).gimme val debits = List[Long](50, 25, 15, 10) @@ -107,8 +108,7 @@ class StoreCreditAdjustmentIntegrationTest } val finalSc = StoreCredits.findOneById(sc.id).gimme.value - (finalSc.originalBalance, finalSc.availableBalance, finalSc.currentBalance) must === ( - (500, 500, 500)) + (finalSc.originalBalance, finalSc.availableBalance, finalSc.currentBalance) must === ((500, 500, 500)) } } diff --git a/phoenix-scala/phoenix/test/integration/models/StoreCreditIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/models/StoreCreditIntegrationTest.scala index dc0454c31c..381f106c47 100644 --- a/phoenix-scala/phoenix/test/integration/models/StoreCreditIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/models/StoreCreditIntegrationTest.scala @@ -8,10 +8,7 @@ import testutils._ import testutils.fixtures.BakedFixtures import core.db._ -class StoreCreditIntegrationTest - extends IntegrationTestBase - with BakedFixtures - with TestObjectContext { +class StoreCreditIntegrationTest extends IntegrationTestBase with BakedFixtures with TestObjectContext { "StoreCreditTest" - { "sets availableBalance and currentBalance equal to originalBalance upon insert" in new Fixture { @@ -47,13 +44,13 @@ class StoreCreditIntegrationTest val (origin, storeCredit, payment) = (for { reason ← * <~ Reasons.create(Factories.reason(storeAdmin.accountId)) origin ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) sc ← * <~ StoreCredits.create( - Factories.storeCredit.copy(accountId = customer.accountId, originId = origin.id)) + Factories.storeCredit.copy(accountId = customer.accountId, originId = origin.id)) sCredit ← * <~ StoreCredits.findOneById(sc.id) payment ← * <~ OrderPayments.create( - Factories.storeCreditPayment - .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(25))) + Factories.storeCreditPayment + .copy(cordRef = cart.refNum, paymentMethodId = sc.id, amount = Some(25))) } yield (origin, sCredit.value, payment)).gimme } } diff --git a/phoenix-scala/phoenix/test/integration/services/CartShippingAddressUpdaterTest.scala b/phoenix-scala/phoenix/test/integration/services/CartShippingAddressUpdaterTest.scala index c16e531089..42c20bf80e 100644 --- a/phoenix-scala/phoenix/test/integration/services/CartShippingAddressUpdaterTest.scala +++ b/phoenix-scala/phoenix/test/integration/services/CartShippingAddressUpdaterTest.scala @@ -75,9 +75,9 @@ class CartShippingAddressUpdaterTest trait UpdateAddressFixture extends Fixture { val newAddress = Addresses .create( - Factories.address.copy(accountId = customer.accountId, - name = customer.name.getOrElse(faker.Name.name), - isDefaultShipping = false)) + Factories.address.copy(accountId = customer.accountId, + name = customer.name.getOrElse(faker.Name.name), + isDefaultShipping = false)) .gimme } } diff --git a/phoenix-scala/phoenix/test/integration/services/CartTotalerTest.scala b/phoenix-scala/phoenix/test/integration/services/CartTotalerTest.scala index 494ca7b16c..32810a245e 100644 --- a/phoenix-scala/phoenix/test/integration/services/CartTotalerTest.scala +++ b/phoenix-scala/phoenix/test/integration/services/CartTotalerTest.scala @@ -78,8 +78,7 @@ class CartTotalerTest extends IntegrationTestBase with TestObjectContext with Ba tup ← * <~ Mvp.getProductTuple(simpleProduct) _ ← * <~ CartLineItems.create(CartLineItem(cordRef = cart.refNum, skuId = tup.sku.id)) skuPrice ← * <~ FormShadowGet.priceAsLong(tup.skuForm, tup.skuShadow) - } yield - (productContext, tup.product, tup.productShadow, tup.sku, tup.skuShadow, skuPrice)).gimme + } yield (productContext, tup.product, tup.productShadow, tup.sku, tup.skuShadow, skuPrice)).gimme } trait ShippingMethodFixture extends Fixture { diff --git a/phoenix-scala/phoenix/test/integration/services/CartValidatorTest.scala b/phoenix-scala/phoenix/test/integration/services/CartValidatorTest.scala index 30cc2cf9a2..fcb6d0623d 100644 --- a/phoenix-scala/phoenix/test/integration/services/CartValidatorTest.scala +++ b/phoenix-scala/phoenix/test/integration/services/CartValidatorTest.scala @@ -61,15 +61,13 @@ class CartValidatorTest extends IntegrationTestBase with TestObjectContext with (for { reason ← * <~ Reasons.create(Factories.reason(storeAdmin.accountId)) origin ← * <~ GiftCardManuals.create( - GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) - giftCard ← * <~ GiftCards.create( - Factories.giftCard.copy(originId = origin.id, - state = GiftCard.Active, - originalBalance = notEnoughFunds)) + GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + giftCard ← * <~ GiftCards.create(Factories.giftCard + .copy(originId = origin.id, state = GiftCard.Active, originalBalance = notEnoughFunds)) payment ← * <~ OrderPayments.create( - Factories.giftCardPayment.copy(cordRef = cart.refNum, - amount = notEnoughFunds.some, - paymentMethodId = giftCard.id)) + Factories.giftCardPayment.copy(cordRef = cart.refNum, + amount = notEnoughFunds.some, + paymentMethodId = giftCard.id)) } yield payment).gimme val result = CartValidator(refresh(cart)).validate().gimme @@ -182,7 +180,7 @@ class CartValidatorTest extends IntegrationTestBase with TestObjectContext with val cc = (for { cc ← * <~ CreditCards.create(Factories.creditCard.copy(accountId = customer.accountId)) _ ← * <~ OrderPayments.create( - Factories.orderPayment.copy(cordRef = cart.refNum, paymentMethodId = cc.id)) + Factories.orderPayment.copy(cordRef = cart.refNum, paymentMethodId = cc.id)) } yield cc).gimme } @@ -190,13 +188,12 @@ class CartValidatorTest extends IntegrationTestBase with TestObjectContext with val (giftCard, orderPayment) = (for { reason ← * <~ Reasons.create(Factories.reason(storeAdmin.accountId)) origin ← * <~ GiftCardManuals.create( - GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) - giftCard ← * <~ GiftCards.create( - Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) + GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + giftCard ← * <~ GiftCards.create(Factories.giftCard.copy(originId = origin.id, state = GiftCard.Active)) payment ← * <~ OrderPayments.create( - OrderPayment - .build(giftCard) - .copy(cordRef = cart.refNum, amount = grandTotal.some)) + OrderPayment + .build(giftCard) + .copy(cordRef = cart.refNum, amount = grandTotal.some)) } yield (giftCard, payment)).gimme } @@ -204,15 +201,13 @@ class CartValidatorTest extends IntegrationTestBase with TestObjectContext with val (storeCredit, orderPayment) = (for { reason ← * <~ Reasons.create(Factories.reason(storeAdmin.accountId)) origin ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) - storeCredit ← * <~ StoreCredits.create( - Factories.storeCredit.copy(originId = origin.id, - state = StoreCredit.Active, - accountId = customer.accountId)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + storeCredit ← * <~ StoreCredits.create(Factories.storeCredit + .copy(originId = origin.id, state = StoreCredit.Active, accountId = customer.accountId)) payment ← * <~ OrderPayments.create( - OrderPayment - .build(storeCredit) - .copy(cordRef = cart.refNum, amount = grandTotal.some)) + OrderPayment + .build(storeCredit) + .copy(cordRef = cart.refNum, amount = grandTotal.some)) } yield (storeCredit, payment)).gimme } diff --git a/phoenix-scala/phoenix/test/integration/services/CheckoutTest.scala b/phoenix-scala/phoenix/test/integration/services/CheckoutTest.scala index c0618c17d7..17048bcb0f 100644 --- a/phoenix-scala/phoenix/test/integration/services/CheckoutTest.scala +++ b/phoenix-scala/phoenix/test/integration/services/CheckoutTest.scala @@ -95,15 +95,13 @@ class CheckoutTest Factories.giftCardPayment.copy(cordRef = cart.refNum, amount = gcAmount.some) val adjustments = (for { - ids ← * <~ generateGiftCards(List.fill(3)(gcAmount)) - _ ← * <~ OrderPayments.createAllReturningIds( - ids.map(id ⇒ gcPayment.copy(paymentMethodId = id))) + ids ← * <~ generateGiftCards(List.fill(3)(gcAmount)) + _ ← * <~ OrderPayments.createAllReturningIds(ids.map(id ⇒ gcPayment.copy(paymentMethodId = id))) _ ← * <~ Checkout(cart, cartValidator()).checkout adjustments ← * <~ GiftCardAdjustments.filter(_.giftCardId.inSet(ids)).result } yield adjustments).gimme - adjustments.map(_.state).toSet must === ( - Set[InStorePaymentStates.State](InStorePaymentStates.Auth)) + adjustments.map(_.state).toSet must === (Set[InStorePaymentStates.State](InStorePaymentStates.Auth)) adjustments.map(_.debit) must === (List(gcAmount, cart.grandTotal - gcAmount)) } @@ -113,15 +111,13 @@ class CheckoutTest Factories.storeCreditPayment.copy(cordRef = cart.refNum, amount = scAmount.some) val adjustments = (for { - ids ← * <~ generateStoreCredits(List.fill(3)(scAmount)) - _ ← * <~ OrderPayments.createAllReturningIds( - ids.map(id ⇒ scPayment.copy(paymentMethodId = id))) + ids ← * <~ generateStoreCredits(List.fill(3)(scAmount)) + _ ← * <~ OrderPayments.createAllReturningIds(ids.map(id ⇒ scPayment.copy(paymentMethodId = id))) _ ← * <~ Checkout(cart, cartValidator()).checkout adjustments ← * <~ StoreCreditAdjustments.filter(_.storeCreditId.inSet(ids)).result } yield adjustments).gimme - adjustments.map(_.state).toSet must === ( - Set[InStorePaymentStates.State](InStorePaymentStates.Auth)) + adjustments.map(_.state).toSet must === (Set[InStorePaymentStates.State](InStorePaymentStates.Auth)) adjustments.map(_.debit) must === (List(scAmount, cart.grandTotal - scAmount)) } } @@ -171,16 +167,12 @@ class CheckoutTest cart ← * <~ Carts.create(Cart(accountId = customer.accountId, scope = Scope.current)) - _ ← * <~ LineItemUpdater.updateQuantitiesOnCart(storeAdmin, - cart.refNum, - lineItemPayload(total)) + _ ← * <~ LineItemUpdater.updateQuantitiesOnCart(storeAdmin, cart.refNum, lineItemPayload(total)) c ← * <~ Carts.refresh(cart) - _ ← * <~ OrderShippingMethods.create( - OrderShippingMethod.build(cart.refNum, shipMethod)) - _ ← * <~ OrderShippingAddresses.copyFromAddress(address = address, - cordRef = cart.refNum) + _ ← * <~ OrderShippingMethods.create(OrderShippingMethod.build(cart.refNum, shipMethod)) + _ ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) gcIds ← * <~ generateGiftCards(gcData.map(_.cardAmount)) scIds ← * <~ generateStoreCredits(scData.map(_.cardAmount)) @@ -223,8 +215,8 @@ class CheckoutTest val sku = (for { productCtx ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) product ← * <~ Mvp.insertProduct( - productCtx.id, - Factories.products.head.copy(price = cost, code = Lorem.letterify("?????"))) + productCtx.id, + Factories.products.head.copy(price = cost, code = Lorem.letterify("?????"))) sku ← * <~ Skus.mustFindById404(product.skuId) } yield sku).gimme Seq(UpdateLineItemsPayload(sku.code, 1)) @@ -233,20 +225,19 @@ class CheckoutTest def generateGiftCards(amount: Seq[Long]) = for { origin ← * <~ GiftCardManuals.create( - GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + GiftCardManual(adminId = storeAdmin.accountId, reasonId = reason.id)) ids ← * <~ GiftCards.createAllReturningIds(amount.map(gcAmount ⇒ - Factories.giftCard.copy(originalBalance = gcAmount, originId = origin.id))) + Factories.giftCard.copy(originalBalance = gcAmount, originId = origin.id))) } yield ids def generateStoreCredits(amount: Seq[Long]) = for { origin ← * <~ StoreCreditManuals.create( - StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) + StoreCreditManual(adminId = storeAdmin.accountId, reasonId = reason.id)) ids ← * <~ StoreCredits.createAllReturningIds( - amount.map(scAmount ⇒ - Factories.storeCredit.copy(originalBalance = scAmount, - originId = origin.id, - accountId = customer.accountId))) + amount.map(scAmount ⇒ + Factories.storeCredit + .copy(originalBalance = scAmount, originId = origin.id, accountId = customer.accountId))) } yield ids } diff --git a/phoenix-scala/phoenix/test/integration/services/LineItemUpdaterTest.scala b/phoenix-scala/phoenix/test/integration/services/LineItemUpdaterTest.scala index bf797c8fdb..6b9ca1fd6b 100644 --- a/phoenix-scala/phoenix/test/integration/services/LineItemUpdaterTest.scala +++ b/phoenix-scala/phoenix/test/integration/services/LineItemUpdaterTest.scala @@ -17,8 +17,7 @@ class LineItemUpdaterTest with TestActivityContext.AdminAC with BakedFixtures { - def createProducts(num: Int)( - implicit au: AU): DbResultT[(ObjectContext, Seq[SimpleProductData])] = + def createProducts(num: Int)(implicit au: AU): DbResultT[(ObjectContext, Seq[SimpleProductData])] = for { context ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) products ← * <~ Mvp.insertProducts((1 to num).map { i ⇒ @@ -32,8 +31,8 @@ class LineItemUpdaterTest val (context, products) = createProducts(2).gimme val payload = Seq[Payload]( - Payload(sku = "1", quantity = 3), - Payload(sku = "2", quantity = 0) + Payload(sku = "1", quantity = 3), + Payload(sku = "2", quantity = 0) ) val root = @@ -60,9 +59,9 @@ class LineItemUpdaterTest CartLineItems.createAll(seedItems).gimme val payload = Seq[Payload]( - Payload(sku = "1", quantity = 3), - Payload(sku = "2", quantity = 0), - Payload(sku = "3", quantity = 1) + Payload(sku = "1", quantity = 3), + Payload(sku = "2", quantity = 0), + Payload(sku = "3", quantity = 1) ) val root = diff --git a/phoenix-scala/phoenix/test/integration/services/ShippingManagerTest.scala b/phoenix-scala/phoenix/test/integration/services/ShippingManagerTest.scala index dfc389e507..1fc55dc1f2 100644 --- a/phoenix-scala/phoenix/test/integration/services/ShippingManagerTest.scala +++ b/phoenix-scala/phoenix/test/integration/services/ShippingManagerTest.scala @@ -40,10 +40,10 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit "Is true when the order is shipped to Canada" in new CountryFixture { val canada = Addresses .create( - Factories.address.copy(accountId = customer.accountId, - name = "Mr Moose", - regionId = ontarioId, - isDefaultShipping = false)) + Factories.address.copy(accountId = customer.accountId, + name = "Mr Moose", + regionId = ontarioId, + isDefaultShipping = false)) .gimme OrderShippingAddresses.filter(_.id === shippingAddress.id).delete.run().futureValue OrderShippingAddresses.copyFromAddress(address = canada, cordRef = cart.refNum).gimme @@ -75,8 +75,8 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit "Is true when the order total is $27 and shipped to CA" in new StateAndPriceCondition { val (address, orderShippingAddress) = (for { - address ← * <~ Addresses.create(Factories.address.copy(accountId = customer.accountId, - regionId = washingtonId)) + address ← * <~ Addresses.create( + Factories.address.copy(accountId = customer.accountId, regionId = washingtonId)) orderShippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) } yield (address, orderShippingAddress)).gimme @@ -87,8 +87,8 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit "Is false when the order total is $27 and shipped to MI" in new StateAndPriceCondition { val (address, orderShippingAddress) = (for { - address ← * <~ Addresses.create(Factories.address.copy(accountId = customer.accountId, - regionId = michiganId)) + address ← * <~ Addresses.create( + Factories.address.copy(accountId = customer.accountId, regionId = michiganId)) orderShippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) } yield (address, orderShippingAddress)).gimme @@ -102,8 +102,8 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit "Is true when the order total is greater than $10 and no address field contains a P.O. Box" in new POCondition { val (address, orderShippingAddress) = (for { - address ← * <~ Addresses.create(Factories.address.copy(accountId = customer.accountId, - regionId = washingtonId)) + address ← * <~ Addresses.create( + Factories.address.copy(accountId = customer.accountId, regionId = washingtonId)) orderShippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) } yield (address, orderShippingAddress)).gimme @@ -115,9 +115,9 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit "Is false when the order total is greater than $10 and address1 contains a P.O. Box" in new POCondition { val (address, orderShippingAddress) = (for { address ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, - regionId = washingtonId, - address1 = "P.O. Box 1234")) + Factories.address.copy(accountId = customer.accountId, + regionId = washingtonId, + address1 = "P.O. Box 1234")) orderShippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) } yield (address, orderShippingAddress)).gimme @@ -129,9 +129,9 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit "Is false when the order total is greater than $10 and address2 contains a P.O. Box" in new POCondition { val (address, orderShippingAddress) = (for { address ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, - regionId = washingtonId, - address2 = Some("P.O. Box 1234"))) + Factories.address.copy(accountId = customer.accountId, + regionId = washingtonId, + address2 = Some("P.O. Box 1234"))) orderShippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) } yield (address, orderShippingAddress)).gimme @@ -144,10 +144,9 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit trait Fixture extends StoreAdmin_Seed with Customer_Seed { val cart = (for { - cart ← * <~ Carts.create(Factories.cart(Scope.current).copy(accountId = customer.accountId)) - product ← * <~ Mvp.insertProduct(ctx.id, - Factories.products.head.copy(title = "Donkey", price = 27)) - _ ← * <~ CartLineItems.create(CartLineItem(cordRef = cart.refNum, skuId = product.skuId)) + cart ← * <~ Carts.create(Factories.cart(Scope.current).copy(accountId = customer.accountId)) + product ← * <~ Mvp.insertProduct(ctx.id, Factories.products.head.copy(title = "Donkey", price = 27)) + _ ← * <~ CartLineItems.create(CartLineItem(cordRef = cart.refNum, skuId = product.skuId)) cart ← * <~ CartTotaler.saveTotals(cart) } yield cart).gimme @@ -162,9 +161,8 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit trait OrderFixture extends Fixture { val (address, shippingAddress) = (for { address ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, regionId = californiaId)) - shippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, - cordRef = cart.refNum) + Factories.address.copy(accountId = customer.accountId, regionId = californiaId)) + shippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) } yield (address, shippingAddress)).gimme } @@ -201,7 +199,7 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit trait CaliforniaOrderFixture extends WestCoastConditionFixture { val (address, orderShippingAddress) = (for { address ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, regionId = californiaId)) + Factories.address.copy(accountId = customer.accountId, regionId = californiaId)) orderShippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) } yield (address, orderShippingAddress)).gimme @@ -210,7 +208,7 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit trait WashingtonOrderFixture extends WestCoastConditionFixture { val (address, orderShippingAddress) = (for { address ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, regionId = washingtonId)) + Factories.address.copy(accountId = customer.accountId, regionId = washingtonId)) orderShippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) } yield (address, orderShippingAddress)).gimme @@ -219,7 +217,7 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit trait MichiganOrderFixture extends WestCoastConditionFixture { val (address, orderShippingAddress) = (for { address ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, regionId = michiganId)) + Factories.address.copy(accountId = customer.accountId, regionId = michiganId)) orderShippingAddress ← * <~ OrderShippingAddresses.copyFromAddress(address = address, cordRef = cart.refNum) } yield (address, orderShippingAddress)).gimme @@ -227,7 +225,7 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit trait POCondition extends Fixture { val conditions = parse( - """ + """ | { | "comparison": "and", | "conditions": [ @@ -253,7 +251,7 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit val scope = Scope.current val conditions = parse( - """ + """ | { | "comparison": "and", | "conditions": [{ @@ -265,46 +263,40 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit val (shippingMethod, cheapCart, expensiveCart) = (for { productContext ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) shippingMethod ← * <~ ShippingMethods.create( - Factories.shippingMethods.head.copy(conditions = Some(conditions))) + Factories.shippingMethods.head.copy(conditions = Some(conditions))) account ← * <~ Accounts.create(Account()) customer ← * <~ Users.create(Factories.customer.copy(accountId = account.id)) _ ← * <~ CustomersData.create( - CustomerData(userId = customer.id, accountId = account.id, scope = Scope.current)) + CustomerData(userId = customer.id, accountId = account.id, scope = Scope.current)) cheapCart ← * <~ Carts.create( - Factories - .cart(Scope.current) - .copy(accountId = customer.accountId, referenceNumber = "CS1234-AA")) - cheapProduct ← * <~ Mvp.insertProduct(productContext.id, - Factories.products.head.copy(title = "Cheap Donkey", - price = 10, - code = "SKU-CHP")) - _ ← * <~ CartLineItems.create( - CartLineItem(cordRef = cheapCart.refNum, skuId = cheapProduct.skuId)) + Factories + .cart(Scope.current) + .copy(accountId = customer.accountId, referenceNumber = "CS1234-AA")) + cheapProduct ← * <~ Mvp.insertProduct( + productContext.id, + Factories.products.head.copy(title = "Cheap Donkey", price = 10, code = "SKU-CHP")) + _ ← * <~ CartLineItems.create(CartLineItem(cordRef = cheapCart.refNum, skuId = cheapProduct.skuId)) cheapAddress ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, - isDefaultShipping = false)) - _ ← * <~ OrderShippingAddresses.copyFromAddress(address = cheapAddress, - cordRef = cheapCart.refNum) + Factories.address.copy(accountId = customer.accountId, isDefaultShipping = false)) + _ ← * <~ OrderShippingAddresses.copyFromAddress(address = cheapAddress, cordRef = cheapCart.refNum) account2 ← * <~ Accounts.create(Account()) customer2 ← * <~ Users.create( - Factories.customer.copy(accountId = account2.id, email = "foo@bar.baz".some)) + Factories.customer.copy(accountId = account2.id, email = "foo@bar.baz".some)) _ ← * <~ CustomersData.create( - CustomerData(userId = customer2.id, accountId = account2.id, scope = Scope.current)) + CustomerData(userId = customer2.id, accountId = account2.id, scope = Scope.current)) expensiveCart ← * <~ Carts.create( - Factories - .cart(Scope.current) - .copy(accountId = customer2.accountId, referenceNumber = "CS1234-AB")) + Factories + .cart(Scope.current) + .copy(accountId = customer2.accountId, referenceNumber = "CS1234-AB")) expensiveProduct ← * <~ Mvp.insertProduct(productContext.id, - Factories.products.head.copy(title = - "Expensive Donkey", + Factories.products.head.copy(title = "Expensive Donkey", price = 100, code = "SKU-EXP")) _ ← * <~ CartLineItems.create( - CartLineItem(cordRef = expensiveCart.refNum, skuId = expensiveProduct.skuId)) + CartLineItem(cordRef = expensiveCart.refNum, skuId = expensiveProduct.skuId)) expensiveAddress ← * <~ Addresses.create( - Factories.address.copy(accountId = customer.accountId, - isDefaultShipping = false)) + Factories.address.copy(accountId = customer.accountId, isDefaultShipping = false)) _ ← * <~ OrderShippingAddresses.copyFromAddress(address = expensiveAddress, cordRef = expensiveCart.refNum) @@ -365,7 +357,7 @@ class ShippingManagerTest extends IntegrationTestBase with TestObjectContext wit trait CountryFixture extends OrderFixture with ShipmentSeeds { val conditions = parse( - """ + """ | { | "comparison": "and", | "conditions": [ diff --git a/phoenix-scala/phoenix/test/integration/services/StripeTest.scala b/phoenix-scala/phoenix/test/integration/services/StripeTest.scala index 1f75dd6489..cccb0b2651 100644 --- a/phoenix-scala/phoenix/test/integration/services/StripeTest.scala +++ b/phoenix-scala/phoenix/test/integration/services/StripeTest.scala @@ -182,7 +182,7 @@ class StripeTest extends IntegrationTestBase with RealStripeApi { val result = stripe.authorizeRefund(auth.getId, 91, RefundReason.RequestedByCustomer).gimmeFailures result.getMessage must === ( - "Refund amount ($0.91) is greater than unrefunded amount on charge ($0.90)") + "Refund amount ($0.91) is greater than unrefunded amount on charge ($0.90)") } "successfully partially refunds a charge" taggedAs External in { diff --git a/phoenix-scala/phoenix/test/integration/testutils/DbTestSupport.scala b/phoenix-scala/phoenix/test/integration/testutils/DbTestSupport.scala index d314729d91..fb026bff4f 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/DbTestSupport.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/DbTestSupport.scala @@ -17,8 +17,7 @@ import core.db._ import scala.annotation.tailrec -trait DbTestSupport extends SuiteMixin with BeforeAndAfterAll with GimmeSupport { - this: TestSuite ⇒ +trait DbTestSupport extends SuiteMixin with BeforeAndAfterAll with GimmeSupport { this: TestSuite ⇒ import DbTestSupport._ @@ -29,18 +28,20 @@ trait DbTestSupport extends SuiteMixin with BeforeAndAfterAll with GimmeSupport val api = slick.jdbc.PostgresProfile.api /* tables which should *not* be truncated b/c they're static and seeded by migration */ - val doNotTruncate = Set("states", - "countries", - "regions", - "schema_version", - "systems", - "resources", - "scopes", - "organizations", - "scope_domains", - "roles", - "permissions", - "role_permissions") + val doNotTruncate = Set( + "states", + "countries", + "regions", + "schema_version", + "systems", + "resources", + "scopes", + "organizations", + "scope_domains", + "roles", + "permissions", + "role_permissions" + ) private def randomizeSequences(schema: String): Unit = { // When changing this, please, if anything, make them less predictable, not more. @michalrus @@ -51,10 +52,10 @@ trait DbTestSupport extends SuiteMixin with BeforeAndAfterAll with GimmeSupport // TODO: Make it possible to not filter these out… @michalrus val randomizedSequences = allSequences.filterNot( - Set( - "scopes_id_seq", // FIXME: What the hell. https://foxcommerce.slack.com/archives/C06696D1R/p1495796779988723 - "object_contexts_id_seq" // FIXME: Sigh. https://foxcommerce.slack.com/archives/C06696D1R/p1495798791447479 - ) contains _) + Set( + "scopes_id_seq", // FIXME: What the hell. https://foxcommerce.slack.com/archives/C06696D1R/p1495796779988723 + "object_contexts_id_seq" // FIXME: Sigh. https://foxcommerce.slack.com/archives/C06696D1R/p1495798791447479 + ) contains _) val gap = 1000000 val withValues = Random @@ -70,7 +71,7 @@ trait DbTestSupport extends SuiteMixin with BeforeAndAfterAll with GimmeSupport .gimme } - override protected def beforeAll(): Unit = { + override protected def beforeAll(): Unit = if (!migrated) { Locale.setDefault(Locale.US) val flyway = newFlyway(dataSource, subprojectSqlLocation) @@ -103,7 +104,6 @@ trait DbTestSupport extends SuiteMixin with BeforeAndAfterAll with GimmeSupport migrated = true } - } override abstract protected def withFixture(test: NoArgTest): Outcome = { truncateTablesStmt.executeQuery() @@ -114,7 +114,7 @@ trait DbTestSupport extends SuiteMixin with BeforeAndAfterAll with GimmeSupport test() } - private def createBaseTestSeeds() = { + private def createBaseTestSeeds() = // Base test data (for { _ ← * <~ ObjectContexts.create(SimpleContext.create()) @@ -122,7 +122,6 @@ trait DbTestSupport extends SuiteMixin with BeforeAndAfterAll with GimmeSupport // FIXME @anna @michalrus _ ← * <~ Factories.FIXME_createAllButPromoSchemas } yield {}).gimme - } } object DbTestSupport { diff --git a/phoenix-scala/phoenix/test/integration/testutils/HttpSupport.scala b/phoenix-scala/phoenix/test/integration/testutils/HttpSupport.scala index 8481596bbe..a452814340 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/HttpSupport.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/HttpSupport.scala @@ -48,8 +48,7 @@ trait HttpSupport with ScalaFutures with MustMatchers with BeforeAndAfterAll - with TestObjectContext { - self: FoxSuite ⇒ + with TestObjectContext { self: FoxSuite ⇒ import HttpSupport._ @@ -76,10 +75,11 @@ trait HttpSupport serverBinding = service .bind( - FoxConfig.http.modify(config)(_.copy( - interface = "127.0.0.1", - port = getFreePort - ))) + FoxConfig.http.modify(config)( + _.copy( + interface = "127.0.0.1", + port = getFreePort + ))) .futureValue } @@ -110,35 +110,32 @@ trait HttpSupport val request = HttpRequest(method = HttpMethods.POST, uri = pathToAbsoluteUrl(path), entity = HttpEntity.Strict( - ContentTypes.`application/json`, - ByteString(rawBody) + ContentTypes.`application/json`, + ByteString(rawBody) )) dispatchRequest(request, jwtCookie) } def POST(path: String, jwtCookie: Option[Cookie]): HttpResponse = - dispatchRequest(HttpRequest(method = HttpMethods.POST, uri = pathToAbsoluteUrl(path)), - jwtCookie) + dispatchRequest(HttpRequest(method = HttpMethods.POST, uri = pathToAbsoluteUrl(path)), jwtCookie) def PATCH(path: String, rawBody: String, jwtCookie: Option[Cookie]): HttpResponse = { val request = HttpRequest(method = HttpMethods.PATCH, uri = pathToAbsoluteUrl(path), entity = HttpEntity.Strict( - ContentTypes.`application/json`, - ByteString(rawBody) + ContentTypes.`application/json`, + ByteString(rawBody) )) dispatchRequest(request, jwtCookie) } def PATCH(path: String, jwtCookie: Option[Cookie]): HttpResponse = - dispatchRequest(HttpRequest(method = HttpMethods.PATCH, uri = pathToAbsoluteUrl(path)), - jwtCookie) + dispatchRequest(HttpRequest(method = HttpMethods.PATCH, uri = pathToAbsoluteUrl(path)), jwtCookie) def GET(path: String, jwtCookie: Option[Cookie]): HttpResponse = - dispatchRequest(HttpRequest(method = HttpMethods.GET, uri = pathToAbsoluteUrl(path)), - jwtCookie) + dispatchRequest(HttpRequest(method = HttpMethods.GET, uri = pathToAbsoluteUrl(path)), jwtCookie) def POST[T <: AnyRef](path: String, payload: T, jwtCookie: Option[Cookie]): HttpResponse = POST(path, writeJson(payload), jwtCookie) @@ -194,8 +191,8 @@ trait HttpSupport def sseProbe(path: String, jwtCookie: Cookie, skipHeartbeat: Boolean = true): Probe[String] = probe( - if (skipHeartbeat) skipHeartbeatsAndAdminCreated(sseSource(path, jwtCookie)) - else sseSource(path, jwtCookie)) + if (skipHeartbeat) skipHeartbeatsAndAdminCreated(sseSource(path, jwtCookie)) + else sseSource(path, jwtCookie)) def sseSource(path: String, jwtCookie: Cookie): Source[String, Any] = { val localAddress = serverBinding.localAddress diff --git a/phoenix-scala/phoenix/test/integration/testutils/IntegrationTestBase.scala b/phoenix-scala/phoenix/test/integration/testutils/IntegrationTestBase.scala index f5a0bdea9a..30aa131e23 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/IntegrationTestBase.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/IntegrationTestBase.scala @@ -14,7 +14,6 @@ trait IntegrationTestBase implicit val ec: ExecutionContextExecutor = scala.concurrent.ExecutionContext.Implicits.global - override protected def beforeEach(): Unit = { + override protected def beforeEach(): Unit = kafkaMock.clear() - } } diff --git a/phoenix-scala/phoenix/test/integration/testutils/JwtTestAuth.scala b/phoenix-scala/phoenix/test/integration/testutils/JwtTestAuth.scala index 6526058c6e..d27da3faa7 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/JwtTestAuth.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/JwtTestAuth.scala @@ -46,8 +46,7 @@ trait JwtTestAuth with PhoenixAdminApi with AppendedClues with MockedApis - with TestActivityContext.AdminAC { - self: FoxSuite ⇒ + with TestActivityContext.AdminAC { self: FoxSuite ⇒ val defaultAdminLoginData: TestLoginData = TestLoginData("default@admin.com") @@ -57,12 +56,14 @@ trait JwtTestAuth StoreAdminManager.getById(admin.accountId).gimme case _ ⇒ StoreAdminManager - .create(CreateStoreAdminPayload(org = "tenant", - name = faker.Name.name, - email = defaultAdminLoginData.email, - password = defaultAdminLoginData.password.some, - roles = List("admin")), - author = None) + .create( + CreateStoreAdminPayload(org = "tenant", + name = faker.Name.name, + email = defaultAdminLoginData.email, + password = defaultAdminLoginData.password.some, + roles = List("admin")), + author = None + ) .gimme } @@ -74,15 +75,15 @@ trait JwtTestAuth def withRandomAdminAuth[Out](testCode: TestAdminAuth ⇒ Out)(implicit sl: SL, sf: SF): Out = withNewAdminAuth(TestLoginData.random)(testCode) - def withNewAdminAuth[Out](loginData: TestLoginData)( - testCode: TestAdminAuth ⇒ Out)(implicit sl: SL, sf: SF): Out = { + def withNewAdminAuth[Out](loginData: TestLoginData)(testCode: TestAdminAuth ⇒ Out)(implicit sl: SL, + sf: SF): Out = { val adminId = storeAdminsApi .create( - CreateStoreAdminPayload(org = "tenant", - email = loginData.email, - password = loginData.password.some, - name = faker.Name.name, - roles = List("admin")))(defaultAdminAuth) + CreateStoreAdminPayload(org = "tenant", + email = loginData.email, + password = loginData.password.some, + name = faker.Name.name, + roles = List("admin")))(defaultAdminAuth) .as[StoreAdminResponse.Root] .id withAdminAuth(loginData, adminId)(testCode) @@ -95,8 +96,7 @@ trait JwtTestAuth val jwtCookie = bakeJwtCookie(adminId) val userId = publicApi - .login(LoginPayload(org = "tenant", email = loginData.email, password = loginData.password), - jwtCookie) + .login(LoginPayload(org = "tenant", email = loginData.email, password = loginData.password), jwtCookie) .as[UserToken] .id testCode(TestAdminAuth(adminId = userId, jwtCookie = jwtCookie, loginData = loginData)) @@ -105,13 +105,13 @@ trait JwtTestAuth def withRandomCustomerAuth[Out](testCode: TestCustomerAuth ⇒ Out)(implicit sl: SL, sf: SF): Out = withNewCustomerAuth(TestLoginData.random)(testCode) - def withNewCustomerAuth[Out](loginData: TestLoginData)( - testCode: TestCustomerAuth ⇒ Out)(implicit sl: SL, sf: SF): Out = { + def withNewCustomerAuth[Out](loginData: TestLoginData)(testCode: TestCustomerAuth ⇒ Out)(implicit sl: SL, + sf: SF): Out = { val customerId = customersApi .create( - CreateCustomerPayload(email = loginData.email, - password = loginData.password.some, - name = faker.Name.name.some))(defaultAdminAuth) + CreateCustomerPayload(email = loginData.email, + password = loginData.password.some, + name = faker.Name.name.some))(defaultAdminAuth) .as[CustomerResponse.Root] .id @@ -125,9 +125,8 @@ trait JwtTestAuth val jwtCookie = bakeJwtCookie(customerId) val userId = publicApi - .login( - LoginPayload(org = "merchant", email = loginData.email, password = loginData.password), - jwtCookie) + .login(LoginPayload(org = "merchant", email = loginData.email, password = loginData.password), + jwtCookie) .as[UserToken] .id testCode(TestCustomerAuth(customerId = userId, jwtCookie = jwtCookie, loginData = loginData)) diff --git a/phoenix-scala/phoenix/test/integration/testutils/PayloadHelpers.scala b/phoenix-scala/phoenix/test/integration/testutils/PayloadHelpers.scala index 415ba71da2..7fb92e1674 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/PayloadHelpers.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/PayloadHelpers.scala @@ -51,5 +51,5 @@ object PayloadHelpers { val imageSrc: String = "http://lorempixel/test.png" val someAlbums: Option[Seq[AlbumPayload]] = Seq( - AlbumPayload(name = "Default".some, images = Seq(ImagePayload(src = imageSrc)).some)).some + AlbumPayload(name = "Default".some, images = Seq(ImagePayload(src = imageSrc)).some)).some } diff --git a/phoenix-scala/phoenix/test/integration/testutils/SearchViewTestBase.scala b/phoenix-scala/phoenix/test/integration/testutils/SearchViewTestBase.scala index edef12e867..96f7bb93e0 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/SearchViewTestBase.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/SearchViewTestBase.scala @@ -38,21 +38,16 @@ trait SearchViewTestBase results.headOption } withClue originalSourceClue - def viewOne(queryParam: AnyVal)(implicit sl: SL, - sf: SF, - mf: Manifest[SearchViewResult]): SearchViewResult = + def viewOne(queryParam: AnyVal)(implicit sl: SL, sf: SF, mf: Manifest[SearchViewResult]): SearchViewResult = findOne(queryParam).value withClue originalSourceClue // As the name suggests, use this to debug view tests. Only to debug. - def DEBUG_rawViewResult(implicit sl: SL, - sf: SF, - mf: Manifest[SearchViewResult]): Vector[String] = + def DEBUG_rawViewResult(implicit sl: SL, sf: SF, mf: Manifest[SearchViewResult]): Vector[String] = sql"select array_to_json(array_agg(sv)) from #$searchViewName as sv".as[String].gimme - private def queryView(queryParam: AnyVal)( - implicit sl: SL, - sf: SF, - mf: Manifest[SearchViewResult]): Option[Seq[SearchViewResult]] = { + private def queryView(queryParam: AnyVal)(implicit sl: SL, + sf: SF, + mf: Manifest[SearchViewResult]): Option[Seq[SearchViewResult]] = { // Select all search view rows as JSON array, just because it's easier to implement it this way rather than // wreste with complex Slick's type definitions val query = diff --git a/phoenix-scala/phoenix/test/integration/testutils/TaxonomySeeds.scala b/phoenix-scala/phoenix/test/integration/testutils/TaxonomySeeds.scala index 40b8eac5f4..98cccce2c4 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/TaxonomySeeds.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/TaxonomySeeds.scala @@ -23,8 +23,8 @@ trait TaxonomySeeds extends TestFixtureBase { trait Taxonomy_Raw { implicit def au: AuthData[User] - val taxonomyAttributes: Map[String, Json] = Map("name" → (("t" → "string") ~ ("v" → "taxon")), - "test" → (("t" → "string") ~ ("v" → "taxon"))) + val taxonomyAttributes: Map[String, Json] = + Map("name" → (("t" → "string") ~ ("v" → "taxon")), "test" → (("t" → "string") ~ ("v" → "taxon"))) def taxonomyHierarchical = false private def _taxonomy: Taxonomy = { @@ -34,13 +34,13 @@ trait TaxonomySeeds extends TestFixtureBase { (for { ins ← * <~ ObjectUtils.insert(form, shadow) taxonomy ← * <~ Taxonomies.create( - Taxonomy(id = 0, - scope = Scope.current, - hierarchical = taxonomyHierarchical, - ctx.id, - ins.form.id, - ins.shadow.id, - ins.commit.id)) + Taxonomy(id = 0, + scope = Scope.current, + hierarchical = taxonomyHierarchical, + ctx.id, + ins.form.id, + ins.shadow.id, + ins.commit.id)) } yield taxonomy).gimme } @@ -55,9 +55,8 @@ trait TaxonomySeeds extends TestFixtureBase { val shadow = ObjectShadow.fromPayload(attributes) (for { - ins ← * <~ ObjectUtils.insert(form, shadow) - term ← * <~ Taxons.create( - Taxon(0, Scope.current, ctx.id, ins.shadow.id, ins.form.id, ins.commit.id)) + ins ← * <~ ObjectUtils.insert(form, shadow) + term ← * <~ Taxons.create(Taxon(0, Scope.current, ctx.id, ins.shadow.id, ins.form.id, ins.commit.id)) } yield term).gimme } @@ -104,28 +103,27 @@ trait TaxonomySeeds extends TestFixtureBase { val taxonsToArchive = createTaxons(attributes) DbResultT .seqCollectFailures( - taxonsToArchive - .map(taxon ⇒ Taxons.update(taxon, taxon.copy(archivedAt = Some(Instant.now)))) - .toList) + taxonsToArchive + .map(taxon ⇒ Taxons.update(taxon, taxon.copy(archivedAt = Some(Instant.now)))) + .toList) .gimme createTaxons(attributes) } val links: Seq[TaxonomyTaxonLink] = { require(taxonomy.hierarchical) - def createLinks: Seq[TaxonomyTaxonLink] = { + def createLinks: Seq[TaxonomyTaxonLink] = Seq(createLink(taxonomy, taxons.head, "", 1, 0), createLink(taxonomy, taxons(1), "", 2, 1)) ++ - Seq(createLink(taxonomy, taxons(2), "1", 3, 0), createLink(taxonomy, taxons(3), "1", 4, 1)) ++ - Seq(createLink(taxonomy, taxons(4), "2", 5, 0), createLink(taxonomy, taxons(5), "2", 6, 1)) ++ - Seq(createLink(taxonomy, taxons(6), "1.3", 7, 1)) - } + Seq(createLink(taxonomy, taxons(2), "1", 3, 0), createLink(taxonomy, taxons(3), "1", 4, 1)) ++ + Seq(createLink(taxonomy, taxons(4), "2", 5, 0), createLink(taxonomy, taxons(5), "2", 6, 1)) ++ + Seq(createLink(taxonomy, taxons(6), "1.3", 7, 1)) val linksToArchive = createLinks DbResultT .seqCollectFailures( - linksToArchive - .map(l ⇒ TaxonomyTaxonLinks.update(l, l.copy(archivedAt = Some(Instant.now())))) - .toList) + linksToArchive + .map(l ⇒ TaxonomyTaxonLinks.update(l, l.copy(archivedAt = Some(Instant.now())))) + .toList) .gimme createLinks } diff --git a/phoenix-scala/phoenix/test/integration/testutils/TestObjectContext.scala b/phoenix-scala/phoenix/test/integration/testutils/TestObjectContext.scala index 26c8230c89..8f0e5cbf32 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/TestObjectContext.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/TestObjectContext.scala @@ -4,8 +4,7 @@ import objectframework.models.{ObjectContext, ObjectContexts} import org.scalatest.{SuiteMixin, TestSuite} import phoenix.models.product.SimpleContext -trait TestObjectContext extends SuiteMixin with GimmeSupport with DbTestSupport { - this: TestSuite ⇒ +trait TestObjectContext extends SuiteMixin with GimmeSupport with DbTestSupport { this: TestSuite ⇒ implicit val database = db implicit lazy val ctx: ObjectContext = ObjectContexts.findOneById(SimpleContext.id).gimme.get diff --git a/phoenix-scala/phoenix/test/integration/testutils/TestSeeds.scala b/phoenix-scala/phoenix/test/integration/testutils/TestSeeds.scala index 3494c1473d..ef9790a190 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/TestSeeds.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/TestSeeds.scala @@ -28,11 +28,10 @@ trait TestSeeds extends TestFixtureBase { def storeAdmin: User = _storeAdmin def storeAdminUser: AdminData = _storeAdminUser def storeAdminClaims: Account.ClaimSet = _storeAdminClaims - val password = "password" + val password = "password" def storeAdminAuthData: AuthData[User] = - AuthData[User](token = - UserToken.fromUserAccount(storeAdmin, storeAdminAccount, storeAdminClaims), + AuthData[User](token = UserToken.fromUserAccount(storeAdmin, storeAdminAccount, storeAdminClaims), model = storeAdmin, account = storeAdminAccount) implicit lazy val au: AU = storeAdminAuthData @@ -44,15 +43,15 @@ trait TestSeeds extends TestFixtureBase { .headOption ad ← * <~ (maybeAdmin match { - case Some(admin) ⇒ DbResultT.pure(admin) - case None ⇒ - Factories.createStoreAdmin(user = Factories.storeAdmin, - password = password, - state = AdminData.Active, - org = TENANT, - roles = List("admin"), - author = None) - }) + case Some(admin) ⇒ DbResultT.pure(admin) + case None ⇒ + Factories.createStoreAdmin(user = Factories.storeAdmin, + password = password, + state = AdminData.Active, + org = TENANT, + roles = List("admin"), + author = None) + }) adu ← * <~ AdminsData.mustFindByAccountId(ad.accountId) ac ← * <~ Accounts.mustFindById404(ad.accountId) organization ← * <~ Organizations diff --git a/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala b/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala index 1d7da4e4f1..4ec0bf5856 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixAdminApi.scala @@ -128,8 +128,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def get()(implicit aa: TestAdminAuth): HttpResponse = GET(creditCardsPrefix, aa.jwtCookie.some) - def create(payload: CreateCreditCardFromTokenPayload)( - implicit aa: TestAdminAuth): HttpResponse = + def create(payload: CreateCreditCardFromTokenPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(creditCardsPrefix, payload, aa.jwtCookie.some) def unsetDefault()(implicit aa: TestAdminAuth): HttpResponse = @@ -182,8 +181,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def create(payload: GiftCardCreateByCsr)(implicit aa: TestAdminAuth): HttpResponse = POST(giftCardsPrefix, payload, aa.jwtCookie.some) - def createFromCustomer(payload: GiftCardCreatedByCustomer)( - implicit aa: TestAdminAuth): HttpResponse = + def createFromCustomer(payload: GiftCardCreatedByCustomer)(implicit aa: TestAdminAuth): HttpResponse = POST(customerGiftCards, payload, aa.jwtCookie.some) def createMultipleFromCustomer(payload: Seq[GiftCardCreatedByCustomer])( @@ -193,8 +191,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def createBulk(payload: GiftCardBulkCreateByCsr)(implicit aa: TestAdminAuth): HttpResponse = POST(s"$giftCardsPrefix/bulk", payload, aa.jwtCookie.some) - def updateBulk(payload: GiftCardBulkUpdateStateByCsr)( - implicit aa: TestAdminAuth): HttpResponse = + def updateBulk(payload: GiftCardBulkUpdateStateByCsr)(implicit aa: TestAdminAuth): HttpResponse = PATCH(s"$giftCardsPrefix/bulk", payload, aa.jwtCookie.some) } @@ -261,15 +258,13 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def unlock()(implicit aa: TestAdminAuth): HttpResponse = POST(s"$requestPath/unlock", aa.jwtCookie.some) - def message(payload: ReturnMessageToCustomerPayload)( - implicit aa: TestAdminAuth): HttpResponse = + def message(payload: ReturnMessageToCustomerPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(s"$requestPath/message", payload, aa.jwtCookie.some) object lineItems { val requestPath = s"${returns.requestPath}/line-items" - def addOrReplace(payload: List[ReturnSkuLineItemPayload])( - implicit aa: TestAdminAuth): HttpResponse = + def addOrReplace(payload: List[ReturnSkuLineItemPayload])(implicit aa: TestAdminAuth): HttpResponse = POST(s"$requestPath/skus", payload, aa.jwtCookie.some) def add(payload: ReturnLineItemPayload)(implicit aa: TestAdminAuth): HttpResponse = @@ -303,8 +298,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def assign(payload: BulkAssignmentPayload[String])(implicit aa: TestAdminAuth): HttpResponse = POST(s"$ordersPrefix/assignees", payload, aa.jwtCookie.some) - def unassign(payload: BulkAssignmentPayload[String])( - implicit aa: TestAdminAuth): HttpResponse = + def unassign(payload: BulkAssignmentPayload[String])(implicit aa: TestAdminAuth): HttpResponse = POST(s"$ordersPrefix/assignees/delete", payload, aa.jwtCookie.some) } @@ -340,9 +334,8 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ val updateLIAttr = s"$cartPath/line-items/attributes" def updateCartLineItem(payload: Seq[UpdateOrderLineItemsPayload])( - implicit aa: TestAdminAuth): HttpResponse = { + implicit aa: TestAdminAuth): HttpResponse = PATCH(updateLIAttr, payload, aa.jwtCookie.some) - } def get()(implicit aa: TestAdminAuth): HttpResponse = GET(cartPath, aa.jwtCookie.some) @@ -489,8 +482,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ case class customerGroupsMembersApi(groupId: Int) { val customerGroupMembersPrefix = s"$rootPrefix/customer-groups/$groupId/customers" - def syncCustomers(payload: CustomerGroupMemberSyncPayload)( - implicit aa: TestAdminAuth): HttpResponse = + def syncCustomers(payload: CustomerGroupMemberSyncPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(s"$customerGroupMembersPrefix", payload, aa.jwtCookie.some) } @@ -516,15 +508,13 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def create(payload: NodePayload)(implicit aa: TestAdminAuth): HttpResponse = POST(genericTreePath, payload, aa.jwtCookie.some) - def createInPath(path: String, payload: NodePayload)( - implicit aa: TestAdminAuth): HttpResponse = + def createInPath(path: String, payload: NodePayload)(implicit aa: TestAdminAuth): HttpResponse = POST(s"$genericTreePath/$path", payload, aa.jwtCookie.some) def moveNode(payload: MoveNodePayload)(implicit aa: TestAdminAuth): HttpResponse = PATCH(genericTreePath, payload, aa.jwtCookie.some) - def moveNodeInPath(path: String, payload: NodeValuesPayload)( - implicit aa: TestAdminAuth): HttpResponse = + def moveNodeInPath(path: String, payload: NodeValuesPayload)(implicit aa: TestAdminAuth): HttpResponse = PATCH(s"$genericTreePath/$path", payload, aa.jwtCookie.some) } @@ -550,7 +540,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ } case object skusApi { - val skusPrefix = s"$rootPrefix/skus" + val skusPrefix = s"$rootPrefix/skus" def skusPath(implicit ctx: OC) = s"$skusPrefix/${ctx.name}" def create(payload: SkuPayload)(implicit ctx: OC, aa: TestAdminAuth): HttpResponse = @@ -615,8 +605,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ POST(albumsPrefix, payload, aa.jwtCookie.some) // Why not PATCH? - def updatePosition(payload: UpdateAlbumPositionPayload)( - implicit aa: TestAdminAuth): HttpResponse = + def updatePosition(payload: UpdateAlbumPositionPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(s"$albumsPrefix/position", payload, aa.jwtCookie.some) } @@ -642,8 +631,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def update(payload: UpdateStoreAdminPayload)(implicit aa: TestAdminAuth): HttpResponse = PATCH(storeAdminPath, payload, aa.jwtCookie.some) - def updateState(payload: StateChangeStoreAdminPayload)( - implicit aa: TestAdminAuth): HttpResponse = + def updateState(payload: StateChangeStoreAdminPayload)(implicit aa: TestAdminAuth): HttpResponse = PATCH(s"$storeAdminPath/state", payload, aa.jwtCookie.some) def delete()(implicit aa: TestAdminAuth): HttpResponse = @@ -666,8 +654,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def update(payload: VariantPayload)(implicit ctx: OC, aa: TestAdminAuth): HttpResponse = PATCH(variantPath, payload, aa.jwtCookie.some) - def createValues(payload: VariantValuePayload)(implicit ctx: OC, - aa: TestAdminAuth): HttpResponse = + def createValues(payload: VariantValuePayload)(implicit ctx: OC, aa: TestAdminAuth): HttpResponse = POST(s"$variantPath/values", payload, aa.jwtCookie.some) } @@ -739,8 +726,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def delete()(implicit aa: TestAdminAuth): HttpResponse = DELETE(sharedSearchPath, aa.jwtCookie.some) - def associate(payload: SharedSearchAssociationPayload)( - implicit aa: TestAdminAuth): HttpResponse = + def associate(payload: SharedSearchAssociationPayload)(implicit aa: TestAdminAuth): HttpResponse = POST(s"$sharedSearchPath/associate", payload, aa.jwtCookie.some) def associates()(implicit aa: TestAdminAuth): HttpResponse = @@ -827,18 +813,15 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ def delete()(implicit aa: TestAdminAuth): HttpResponse = DELETE(s"v1/taxons/${ctx.name}/$taxonId", aa.jwtCookie.some) - def assignProduct(productFormId: ObjectForm#Id)(implicit ctx: OC, - aa: TestAdminAuth): HttpResponse = + def assignProduct(productFormId: ObjectForm#Id)(implicit ctx: OC, aa: TestAdminAuth): HttpResponse = PATCH(s"v1/taxons/${ctx.name}/$taxonId/product/$productFormId", aa.jwtCookie.some) - def unassignProduct(productFormId: ObjectForm#Id)(implicit ctx: OC, - aa: TestAdminAuth): HttpResponse = + def unassignProduct(productFormId: ObjectForm#Id)(implicit ctx: OC, aa: TestAdminAuth): HttpResponse = DELETE(s"v1/taxons/${ctx.name}/$taxonId/product/$productFormId", aa.jwtCookie.some) } object productReviewApi { - def create(payload: CreateProductReviewPayload)(implicit ctx: OC, - aa: TestAdminAuth): HttpResponse = + def create(payload: CreateProductReviewPayload)(implicit ctx: OC, aa: TestAdminAuth): HttpResponse = POST(s"v1/review/${ctx.name}", payload, aa.jwtCookie.some) } @@ -890,8 +873,7 @@ trait PhoenixAdminApi extends HttpSupport { self: FoxSuite ⇒ object storeCreditsApi { val storeCreditsPrefix = s"$rootPrefix/store-credits" - def update(payload: StoreCreditBulkUpdateStateByCsr)( - implicit aa: TestAdminAuth): HttpResponse = + def update(payload: StoreCreditBulkUpdateStateByCsr)(implicit aa: TestAdminAuth): HttpResponse = PATCH(storeCreditsPrefix, payload, aa.jwtCookie.some) } diff --git a/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixStorefrontApi.scala b/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixStorefrontApi.scala index 33a4dc0e9b..39550feddc 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixStorefrontApi.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/apis/PhoenixStorefrontApi.scala @@ -27,8 +27,7 @@ trait PhoenixStorefrontApi extends HttpSupport { self: FoxSuite ⇒ def checkout(payload: CheckoutCart)(implicit ca: TestCustomerAuth): HttpResponse = POST(s"$cartPath/checkout", payload, ca.jwtCookie.some) - def applePayCheckout(payload: CreateApplePayPayment)( - implicit ca: TestCustomerAuth): HttpResponse = + def applePayCheckout(payload: CreateApplePayPayment)(implicit ca: TestCustomerAuth): HttpResponse = POST(s"$cartPath/apple-pay-checkout", payload, ca.jwtCookie.some) object lineItems { @@ -79,8 +78,7 @@ trait PhoenixStorefrontApi extends HttpSupport { self: FoxSuite ⇒ def get()(implicit ca: TestCustomerAuth): HttpResponse = GET(ccPath, ca.jwtCookie.some) - def create(payload: CreateCreditCardFromTokenPayload)( - implicit ca: TestCustomerAuth): HttpResponse = + def create(payload: CreateCreditCardFromTokenPayload)(implicit ca: TestCustomerAuth): HttpResponse = POST(ccPath, payload, ca.jwtCookie.some) def unsetDefault()(implicit ca: TestCustomerAuth): HttpResponse = diff --git a/phoenix-scala/phoenix/test/integration/testutils/fixtures/BakedFixtures.scala b/phoenix-scala/phoenix/test/integration/testutils/fixtures/BakedFixtures.scala index e776a793a4..1d431832a7 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/fixtures/BakedFixtures.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/fixtures/BakedFixtures.scala @@ -33,8 +33,5 @@ trait BakedFixtures extends TestSeeds with RawFixtures { trait ProductAndSkus_Baked extends StoreAdmin_Seed with Sku_Raw with Product_Raw - trait ProductAndVariants_Baked - extends StoreAdmin_Seed - with Product_Raw - with ProductWithVariants_Raw + trait ProductAndVariants_Baked extends StoreAdmin_Seed with Product_Raw with ProductWithVariants_Raw } diff --git a/phoenix-scala/phoenix/test/integration/testutils/fixtures/PaymentFixtures.scala b/phoenix-scala/phoenix/test/integration/testutils/fixtures/PaymentFixtures.scala index 2048f36378..bb1e9687b9 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/fixtures/PaymentFixtures.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/fixtures/PaymentFixtures.scala @@ -15,13 +15,15 @@ object PaymentFixtures { val theAddress = Factories.address.copy(id = 1, accountId = 2, isDefaultShipping = false) val expYear = ZonedDateTime.now.getYear + 3 - val theAddressPayload = CreateAddressPayload(name = theAddress.name, - address1 = theAddress.address1, - address2 = theAddress.address2, - zip = theAddress.zip, - city = theAddress.city, - regionId = theAddress.regionId, - phoneNumber = theAddress.phoneNumber) + val theAddressPayload = CreateAddressPayload( + name = theAddress.name, + address1 = theAddress.address1, + address2 = theAddress.address2, + zip = theAddress.zip, + city = theAddress.city, + regionId = theAddress.regionId, + phoneNumber = theAddress.phoneNumber + ) val tokenStripeId = s"tok_${TestStripeSupport.randomStripeishId}" diff --git a/phoenix-scala/phoenix/test/integration/testutils/fixtures/PromotionFixtures.scala b/phoenix-scala/phoenix/test/integration/testutils/fixtures/PromotionFixtures.scala index 3810507512..1a8d7179e4 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/fixtures/PromotionFixtures.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/fixtures/PromotionFixtures.scala @@ -22,19 +22,18 @@ trait PromotionFixtures extends TestFixtureBase { trait Promotion_Seed { implicit def au: AU - def makeDiscountAttrs(qualifier: String, qualifierValue: JObject): Map[String, Json] = { + def makeDiscountAttrs(qualifier: String, qualifierValue: JObject): Map[String, Json] = Map[String, Any]( - "title" → s"Get $percentOff% off when you spend $totalAmount dollars", - "description" → s"$percentOff% off when you spend over $totalAmount dollars", - "tags" → tv(JArray(List.empty[JString]), "tags"), - "qualifier" → JObject(qualifier → qualifierValue).asShadowVal(t = "qualifier"), - "offer" → JObject( - "orderPercentOff" → JObject( - "discount" → JInt(percentOff) - ) - ).asShadowVal("offer") + "title" → s"Get $percentOff% off when you spend $totalAmount dollars", + "description" → s"$percentOff% off when you spend over $totalAmount dollars", + "tags" → tv(JArray(List.empty[JString]), "tags"), + "qualifier" → JObject(qualifier → qualifierValue).asShadowVal(t = "qualifier"), + "offer" → JObject( + "orderPercentOff" → JObject( + "discount" → JInt(percentOff) + ) + ).asShadowVal("offer") ).asShadow - } val percentOff = 10 val totalAmount = 0 @@ -45,13 +44,11 @@ trait PromotionFixtures extends TestFixtureBase { val promoPayload = CreatePromotion(applyType = Promotion.Coupon, attributes = promoAttributes, - discounts = - Seq(CreateDiscount(attributes = discountAttributes))) + discounts = Seq(CreateDiscount(attributes = discountAttributes))) - val (promoRoot: PromotionResponse.Root, promotion: Promotion) = createPromotionFromPayload( - promoPayload) + val (promoRoot: PromotionResponse.Root, promotion: Promotion) = createPromotionFromPayload(promoPayload) - def createPromotionFromPayload(promoPayload: CreatePromotion) = { + def createPromotionFromPayload(promoPayload: CreatePromotion) = (for { promoRoot ← * <~ PromotionManager.create(promoPayload, ctx.name, None) promotion ← * <~ Promotions @@ -59,7 +56,6 @@ trait PromotionFixtures extends TestFixtureBase { .filter(_.formId === promoRoot.id) .mustFindOneOr(NotFoundFailure404(Promotion, "test")) } yield (promoRoot, promotion)).gimme - } } @@ -69,9 +65,8 @@ trait PromotionFixtures extends TestFixtureBase { def promotion: Promotion val coupon = CouponManager.create(couponPayload(promotion.formId), ctx.name, None).gimme - def couponPayload(promoId: Int, attributes: Map[String, Json] = Map()): CreateCoupon = { + def couponPayload(promoId: Int, attributes: Map[String, Json] = Map()): CreateCoupon = CreateCoupon(attributes = attributes + ("name" → tv("donkey coupon")), promoId) - } } } diff --git a/phoenix-scala/phoenix/test/integration/testutils/fixtures/RawFixtures.scala b/phoenix-scala/phoenix/test/integration/testutils/fixtures/RawFixtures.scala index 34596eddf2..18873678a0 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/fixtures/RawFixtures.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/fixtures/RawFixtures.scala @@ -133,9 +133,7 @@ trait RawFixtures extends RawPaymentFixtures with TestSeeds { trait Sku_Raw extends StoreAdmin_Seed { val simpleSku: Sku = Mvp - .insertSku(Scope.current, - ctx.id, - SimpleSku("BY-ITSELF", "A lonely item", 9999, active = true)) + .insertSku(Scope.current, ctx.id, SimpleSku("BY-ITSELF", "A lonely item", 9999, active = true)) .gimme } @@ -148,10 +146,10 @@ trait RawFixtures extends RawPaymentFixtures with TestSeeds { val testSkus = Seq(SimpleSku("SKU-TST", "SKU test", 1000, Currency.USD, active = true), SimpleSku("SKU-TS2", "SKU test 2", 1000, Currency.USD, active = true)) - val simpleSizeVariant = SimpleCompleteVariant( - variant = SimpleVariant("Size"), - variantValues = Seq(SimpleVariantValue("Small", "", Seq("SKU-TST")), - SimpleVariantValue("Large", "", Seq("SKU-TS2")))) + val simpleSizeVariant = SimpleCompleteVariant(variant = SimpleVariant("Size"), + variantValues = + Seq(SimpleVariantValue("Small", "", Seq("SKU-TST")), + SimpleVariantValue("Large", "", Seq("SKU-TS2")))) for { skus ← * <~ Mvp.insertSkus(scope, ctx.id, testSkus) diff --git a/phoenix-scala/phoenix/test/integration/testutils/fixtures/ReturnsFixtures.scala b/phoenix-scala/phoenix/test/integration/testutils/fixtures/ReturnsFixtures.scala index d0b59c6752..998b04cc34 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/fixtures/ReturnsFixtures.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/fixtures/ReturnsFixtures.scala @@ -29,8 +29,7 @@ trait ReturnsFixtures with BakedFixtures with ApiFixtureHelpers with JwtTestAuth - with OptionValues { - self: FoxSuite ⇒ + with OptionValues { self: FoxSuite ⇒ trait OrderDefaults extends EmptyCartWithShipAddress_Baked with Reason_Baked { val shippingMethod: ShippingMethod = @@ -38,42 +37,42 @@ trait ReturnsFixtures val creditCard = { val cc = Factories.creditCard - api_newCreditCard(customer.accountId, - CreateCreditCardFromTokenPayload( - token = "whatever", - lastFour = cc.lastFour, - expYear = cc.expYear, - expMonth = cc.expMonth, - brand = cc.brand, - holderName = cc.holderName, - billingAddress = CreateAddressPayload( - name = cc.address.name, - regionId = cc.address.regionId, - address1 = cc.address.address1, - address2 = cc.address.address2, - city = cc.address.city, - zip = cc.address.zip, - isDefault = false, - phoneNumber = cc.address.phoneNumber - ), - addressIsNew = true - )) + api_newCreditCard( + customer.accountId, + CreateCreditCardFromTokenPayload( + token = "whatever", + lastFour = cc.lastFour, + expYear = cc.expYear, + expMonth = cc.expMonth, + brand = cc.brand, + holderName = cc.holderName, + billingAddress = CreateAddressPayload( + name = cc.address.name, + regionId = cc.address.regionId, + address1 = cc.address.address1, + address2 = cc.address.address2, + city = cc.address.city, + zip = cc.address.zip, + isDefault = false, + phoneNumber = cc.address.phoneNumber + ), + addressIsNew = true + ) + ) } val applePayPayment = CreateApplePayPayment(stripeToken = "tok_1A9YBQJVm1XvTUrO3V8caBvF") val giftCard = api_newGiftCard(GiftCardCreateByCsr(balance = 1000, reasonId = reason.id)) - val storeCredit = api_newStoreCredit( - customer.accountId, - CreateManualStoreCredit(amount = 1000, reasonId = reason.id)) + val storeCredit = + api_newStoreCredit(customer.accountId, CreateManualStoreCredit(amount = 1000, reasonId = reason.id)) val product: SimpleProductData = Mvp.insertProduct(ctx.id, Factories.products.head).gimme - def createOrder(lineItems: Seq[UpdateLineItemsPayload], - paymentMethods: Map[PaymentMethod.Type, Option[Long]])( - implicit sl: SL, - sf: SF): OrderResponse = { + def createOrder( + lineItems: Seq[UpdateLineItemsPayload], + paymentMethods: Map[PaymentMethod.Type, Option[Long]])(implicit sl: SL, sf: SF): OrderResponse = { val api = cartsApi(api_newCustomerCart(customer.accountId).referenceNumber) api.lineItems.add(lineItems)(defaultAdminAuth).mustBeOk() @@ -100,23 +99,24 @@ trait ReturnsFixtures api.checkout()(defaultAdminAuth).as[OrderResponse] } - def createDefaultOrder(paymentMethods: Map[PaymentMethod.Type, Option[Long]] = Map( - PaymentMethod.CreditCard → None), - items: List[UpdateLineItemsPayload] = List( - UpdateLineItemsPayload(product.code, 1)), - transitionStates: List[Order.State] = - List(Order.FulfillmentStarted, Order.Shipped)): OrderResponse = { + def createDefaultOrder( + paymentMethods: Map[PaymentMethod.Type, Option[Long]] = Map(PaymentMethod.CreditCard → None), + items: List[UpdateLineItemsPayload] = List(UpdateLineItemsPayload(product.code, 1)), + transitionStates: List[Order.State] = List(Order.FulfillmentStarted, Order.Shipped)) + : OrderResponse = { val initial = createOrder( - lineItems = items, - paymentMethods = paymentMethods + lineItems = items, + paymentMethods = paymentMethods ) val api = ordersApi(initial.referenceNumber) NonEmptyList .fromList(transitionStates) - .map(transitionEntity(_, none[OrderResponse])(_.orderState)(state ⇒ - api - .update(UpdateOrderPayload(state = state))(defaultAdminAuth) - .as[OrderResponse])) + .map( + transitionEntity(_, none[OrderResponse])(_.orderState)( + state ⇒ + api + .update(UpdateOrderPayload(state = state))(defaultAdminAuth) + .as[OrderResponse])) .getOrElse(initial) } @@ -139,13 +139,11 @@ trait ReturnsFixtures .as[ReturnResponse.Root] def completeReturn(refNum: String)(implicit sl: SL, sf: SF): ReturnResponse.Root = { - val happyPath = NonEmptyList.fromListUnsafe( - List(Return.Pending, Return.Processing, Return.Review, Return.Complete)) + val happyPath = + NonEmptyList.fromListUnsafe(List(Return.Pending, Return.Processing, Return.Review, Return.Complete)) - transitionEntity( - happyPath, - returnsApi(refNum).get()(defaultAdminAuth).as[ReturnResponse.Root].some)(_.state)(state ⇒ - updateReturnState(refNum = refNum, returnState = state)) + transitionEntity(happyPath, returnsApi(refNum).get()(defaultAdminAuth).as[ReturnResponse.Root].some)( + _.state)(state ⇒ updateReturnState(refNum = refNum, returnState = state)) } } @@ -165,8 +163,8 @@ trait ReturnsFixtures } trait ReturnLineItemFixture extends ReturnReasonFixture { - def createReturnLineItem(payload: ReturnLineItemPayload, - refNum: String)(implicit sl: SL, sf: SF): ReturnResponse.Root = + def createReturnLineItem(payload: ReturnLineItemPayload, refNum: String)(implicit sl: SL, + sf: SF): ReturnResponse.Root = returnsApi(refNum).lineItems.add(payload)(defaultAdminAuth).as[ReturnResponse.Root] def createReturnSkuLineItems(payloads: List[ReturnSkuLineItemPayload], @@ -174,10 +172,7 @@ trait ReturnsFixtures returnsApi(refNum).lineItems.addOrReplace(payloads)(defaultAdminAuth).as[ReturnResponse.Root] } - trait ReturnLineItemDefaults - extends ReturnLineItemFixture - with ReturnReasonDefaults - with ReturnDefaults { + trait ReturnLineItemDefaults extends ReturnLineItemFixture with ReturnReasonDefaults with ReturnDefaults { val shippingCostPayload = ReturnShippingCostLineItemPayload(amount = order.totals.shipping, reasonId = returnReason.id) @@ -204,10 +199,8 @@ trait ReturnsFixtures .add(payment, ReturnPaymentPayload(amount))(defaultAdminAuth) .as[ReturnResponse.Root] - val paymentMethodTable = Table("paymentMethod", - PaymentMethod.CreditCard, - PaymentMethod.GiftCard, - PaymentMethod.StoreCredit) + val paymentMethodTable = + Table("paymentMethod", PaymentMethod.CreditCard, PaymentMethod.GiftCard, PaymentMethod.StoreCredit) implicit class RichReturnPayments(payments: ReturnResponse.Payments) { def asMap: Map[PaymentMethod.Type, ReturnResponse.Payment] = @@ -219,9 +212,6 @@ trait ReturnsFixtures } } - trait ReturnPaymentDefaults - extends ReturnPaymentFixture - with ReturnLineItemDefaults - with ReturnDefaults + trait ReturnPaymentDefaults extends ReturnPaymentFixture with ReturnLineItemDefaults with ReturnDefaults } diff --git a/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/ApiFixtureHelpers.scala b/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/ApiFixtureHelpers.scala index cdad982140..94988fbbd5 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/ApiFixtureHelpers.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/ApiFixtureHelpers.scala @@ -26,9 +26,8 @@ trait ApiFixtureHelpers extends PhoenixAdminApi with ApiFixtures { self: FoxSuit val loginData = TestLoginData(randomEmail(name)) val customer = customersApi .create( - CreateCustomerPayload(name = name.some, - email = loginData.email, - password = loginData.password.some))(defaultAdminAuth) + CreateCustomerPayload(name = name.some, email = loginData.email, password = loginData.password.some))( + defaultAdminAuth) .as[CustomerResponse.Root] (customer, loginData) } @@ -46,8 +45,7 @@ trait ApiFixtureHelpers extends PhoenixAdminApi with ApiFixtures { self: FoxSuit .create(payload)(defaultAdminAuth) .as[CreditCardsResponse.Root] - def api_newGiftCard(payload: GiftCardCreateByCsr)(implicit sl: SL, - sf: SF): GiftCardResponse.Root = + def api_newGiftCard(payload: GiftCardCreateByCsr)(implicit sl: SL, sf: SF): GiftCardResponse.Root = giftCardsApi.create(payload)(defaultAdminAuth).as[GiftCardResponse.Root] def api_newStoreCredit(customerId: Int, payload: CreateManualStoreCredit)( diff --git a/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/ApiFixtures.scala b/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/ApiFixtures.scala index c160b437e6..6c2da0bd69 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/ApiFixtures.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/ApiFixtures.scala @@ -28,20 +28,21 @@ import scala.util.Random import phoenix.payloads.VariantPayloads.{VariantPayload, VariantValuePayload} -trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with JwtTestAuth { - self: FoxSuite ⇒ +trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with JwtTestAuth { self: FoxSuite ⇒ /** Transitions through list of states. * * If `initial` is empty it will transition through all of the passed `transitionStates`. * If it's defined it will skip any states in `transitionStates` until `initial` is found. */ - def transitionEntity[S, E](transitionStates: NonEmptyList[S], initial: Option[E])( - getState: E ⇒ S)(updateState: S ⇒ E): E = { - val transition = initial.map { e ⇒ - val initialState = getState(e) - transitionStates.toList.dropWhile(_ != initialState).drop(1).foldLeft(e) _ - }.getOrElse(transitionStates.tail.foldLeft(updateState(transitionStates.head)) _) + def transitionEntity[S, E](transitionStates: NonEmptyList[S], initial: Option[E])(getState: E ⇒ S)( + updateState: S ⇒ E): E = { + val transition = initial + .map { e ⇒ + val initialState = getState(e) + transitionStates.toList.dropWhile(_ != initialState).drop(1).foldLeft(e) _ + } + .getOrElse(transitionStates.tail.foldLeft(updateState(transitionStates.head)) _) transition { (_, state) ⇒ val updated = updateState(state) @@ -57,20 +58,20 @@ trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with trait ProductSku_ApiFixture { val productCode: String = s"testprod_${Lorem.numerify("####")}" val skuCode: String = s"$productCode-sku_${Lorem.letterify("????").toUpperCase}" - def skuPrice: Long = Random.nextInt(20000).toLong + 100 + def skuPrice: Long = Random.nextInt(20000).toLong + 100 private val skuPayload = SkuPayload( - attributes = Map("code" → tv(skuCode), - "title" → tv(skuCode.capitalize), - "salePrice" → usdPrice(skuPrice), - "retailPrice" → usdPrice(skuPrice)) ++ eternalActivity()) + attributes = Map("code" → tv(skuCode), + "title" → tv(skuCode.capitalize), + "salePrice" → usdPrice(skuPrice), + "retailPrice" → usdPrice(skuPrice)) ++ eternalActivity()) val productPayload = - CreateProductPayload(attributes = - Map("name" → tv(productCode.capitalize), - "title" → tv(productCode.capitalize)) ++ eternalActivity(), - skus = Seq(skuPayload), - variants = None) + CreateProductPayload( + attributes = + Map("name" → tv(productCode.capitalize), "title" → tv(productCode.capitalize)) ++ eternalActivity(), + skus = Seq(skuPayload), + variants = None) val product: ProductRoot = productsApi.create(productPayload)(implicitly, defaultAdminAuth).as[ProductRoot] @@ -85,10 +86,10 @@ trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with private val skuPayloads = skuCodes.map { skuCode ⇒ SkuPayload( - attributes = Map("code" → tv(skuCode), - "title" → tv(skuCode.capitalize), - "salePrice" → usdPrice(skuPrice), - "retailPrice" → usdPrice(skuPrice)) ++ eternalActivity()) + attributes = Map("code" → tv(skuCode), + "title" → tv(skuCode.capitalize), + "salePrice" → usdPrice(skuPrice), + "retailPrice" → usdPrice(skuPrice)) ++ eternalActivity()) } private val variantValues = skuCodes.map { skuCode ⇒ VariantValuePayload(name = s"""productCode-variantValue${Lorem.letterify("???")}""".some, @@ -98,16 +99,16 @@ trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with } private val variant = VariantPayload(values = Some(variantValues), - attributes = - Map("name" → (("t" → "string") ~ ("v" → "Color")))) + attributes = Map("name" → (("t" → "string") ~ ("v" → "Color")))) val productPayload = - CreateProductPayload(attributes = - Map("name" → tv(productCode.capitalize), - "title" → tv(productCode.capitalize)) ++ eternalActivity(), - skus = skuPayloads, - slug = "simple-product", - variants = Some(Seq(variant))) + CreateProductPayload( + attributes = + Map("name" → tv(productCode.capitalize), "title" → tv(productCode.capitalize)) ++ eternalActivity(), + skus = skuPayloads, + slug = "simple-product", + variants = Some(Seq(variant)) + ) val product: ProductRoot = productsApi.create(productPayload)(implicitly, defaultAdminAuth).as[ProductRoot] @@ -117,9 +118,9 @@ trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with def percentOff: Int = 10 private lazy val promoPayload = PromotionPayloadBuilder.build( - Promotion.Coupon, - PromoOfferBuilder.CartPercentOff(percentOff), - PromoQualifierBuilder.CartAny) + Promotion.Coupon, + PromoOfferBuilder.CartPercentOff(percentOff), + PromoQualifierBuilder.CartAny) def promotion = promotionsApi.create(promoPayload)(implicitly, defaultAdminAuth).as[PromotionResponse.Root] @@ -130,9 +131,9 @@ trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with def percentOff: Int = 10 private lazy val promoPayload = PromotionPayloadBuilder.build( - Promotion.Coupon, - PromoOfferBuilder.CartPercentOff(percentOff), - PromoQualifierBuilder.CartTotalAmount(qualifiedSubtotal)) + Promotion.Coupon, + PromoOfferBuilder.CartPercentOff(percentOff), + PromoQualifierBuilder.CartTotalAmount(qualifiedSubtotal)) def promotion = promotionsApi.create(promoPayload)(implicitly, defaultAdminAuth).as[PromotionResponse.Root] @@ -143,9 +144,9 @@ trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with def percentOff: Int = 10 private lazy val promoPayload = PromotionPayloadBuilder.build( - Promotion.Coupon, - PromoOfferBuilder.CartPercentOff(percentOff), - PromoQualifierBuilder.CartNumUnits(qualifiedNumItems)) + Promotion.Coupon, + PromoOfferBuilder.CartPercentOff(percentOff), + PromoQualifierBuilder.CartNumUnits(qualifiedNumItems)) lazy val promotion = promotionsApi.create(promoPayload)(implicitly, defaultAdminAuth).as[PromotionResponse.Root] @@ -158,9 +159,8 @@ trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with def promotion: PromotionResponse.Root lazy val coupon = couponsApi - .create(CreateCoupon(couponAttrs(couponActiveFrom, couponActiveTo), promotion.id))( - implicitly, - defaultAdminAuth) + .create(CreateCoupon(couponAttrs(couponActiveFrom, couponActiveTo), promotion.id))(implicitly, + defaultAdminAuth) .as[CouponResponse.Root] lazy val couponCode = @@ -168,17 +168,19 @@ trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with protected def couponAttrs(activeFrom: Instant, activeTo: Option[Instant]): Map[String, Json] = { val usageRules = { - ("isExclusive" → true) ~ - ("isUnlimitedPerCode" → true) ~ - ("isUnlimitedPerCustomer" → true) + ("isExclusive" → true) ~ + ("isUnlimitedPerCode" → true) ~ + ("isUnlimitedPerCustomer" → true) }.asShadowVal(t = "usageRules") - val commonAttrs = Map[String, Any]("name" → "Order coupon", - "storefrontName" → "Order coupon", - "description" → "Order coupon description", - "details" → "Order coupon details".richText, - "usageRules" → usageRules, - "activeFrom" → activeFrom) + val commonAttrs = Map[String, Any]( + "name" → "Order coupon", + "storefrontName" → "Order coupon", + "description" → "Order coupon description", + "details" → "Order coupon details".richText, + "usageRules" → usageRules, + "activeFrom" → activeFrom + ) activeTo.fold(commonAttrs)(act ⇒ commonAttrs + ("activeTo" → act)).asShadow } @@ -187,9 +189,8 @@ trait ApiFixtures extends SuiteMixin with HttpSupport with PhoenixAdminApi with trait ProductReviewApiFixture extends ProductSku_ApiFixture { val reviewAttributes: Json = ("title" → tv("title")) ~ ("body" → tv("body")) - private val payload = CreateProductReviewByCustomerPayload(attributes = reviewAttributes, - sku = skuCode, - scope = None) + private val payload = + CreateProductReviewByCustomerPayload(attributes = reviewAttributes, sku = skuCode, scope = None) val productReview = productReviewApi.create(payload)(implicitly, defaultAdminAuth).as[ProductReviewResponse] } diff --git a/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/PromotionPayloadBuilder.scala b/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/PromotionPayloadBuilder.scala index ffff966f67..eec2cbab2e 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/PromotionPayloadBuilder.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/PromotionPayloadBuilder.scala @@ -21,20 +21,22 @@ object PromotionPayloadBuilder { description: String = faker.Lorem.sentence()): CreatePromotion = { val discountAttrs = Map[String, Json]( - "title" → tv(title), - "description" → tv(description), - "tags" → tags.payloadJson, - "qualifier" → qualifier.payloadJson, - "offer" → offer.payloadJson + "title" → tv(title), + "description" → tv(description), + "tags" → tags.payloadJson, + "qualifier" → qualifier.payloadJson, + "offer" → offer.payloadJson ) - CreatePromotion(applyType = applyType, - attributes = Map( - "name" → tv(faker.Lorem.sentence(1)), - "activeFrom" → tv(Instant.now, "datetime"), - "activeTo" → tv(JNull, "datetime") - ) ++ extraAttrs, - discounts = Seq(CreateDiscount(discountAttrs))) + CreatePromotion( + applyType = applyType, + attributes = Map( + "name" → tv(faker.Lorem.sentence(1)), + "activeFrom" → tv(Instant.now, "datetime"), + "activeTo" → tv(JNull, "datetime") + ) ++ extraAttrs, + discounts = Seq(CreateDiscount(discountAttrs)) + ) } sealed trait PromoQualifierBuilder extends Jsonable @@ -47,8 +49,7 @@ object PromotionPayloadBuilder { case class CartTotalAmount(qualifiedSubtotal: Long) extends PromoQualifierBuilder { def payloadJson: Json = - tv(parseJson(s"""{ "orderTotalAmount": { "totalAmount" : ${qualifiedSubtotal} } }"""), - "qualifier") + tv(parseJson(s"""{ "orderTotalAmount": { "totalAmount" : $qualifiedSubtotal } }"""), "qualifier") } case class CartNumUnits(qualifiedNumUnits: Int) extends PromoQualifierBuilder { diff --git a/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/package.scala b/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/package.scala index 9152114537..90211dc525 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/package.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/fixtures/api/package.scala @@ -21,9 +21,9 @@ package object api { def randomGiftCardLineItemAttributes(): Option[LineItemAttributes] = LineItemAttributes( - GiftCardLineItemAttributes(recipientName = faker.Name.name, - recipientEmail = faker.Internet.email, - senderName = faker.Name.name, - message = faker.Lorem.sentence().some).some).some + GiftCardLineItemAttributes(recipientName = faker.Name.name, + recipientEmail = faker.Internet.email, + senderName = faker.Name.name, + message = faker.Lorem.sentence().some).some).some } diff --git a/phoenix-scala/phoenix/test/integration/testutils/package.scala b/phoenix-scala/phoenix/test/integration/testutils/package.scala index 8dceecde52..c5e675c2d0 100644 --- a/phoenix-scala/phoenix/test/integration/testutils/package.scala +++ b/phoenix-scala/phoenix/test/integration/testutils/package.scala @@ -91,33 +91,27 @@ package object testutils extends MustMatchers with OptionValues with AppendedClu (bodyText mustBe empty).withClue(s"Expected empty body, got $bodyText!") } - def mustFailWith404(expected: Failure*)(implicit line: SL, file: SF): Unit = { + def mustFailWith404(expected: Failure*)(implicit line: SL, file: SF): Unit = mustFailWith(StatusCodes.NotFound, expected.map(_.description): _*) - } - def mustFailWith400(expected: Failure*)(implicit line: SL, file: SF): Unit = { + def mustFailWith400(expected: Failure*)(implicit line: SL, file: SF): Unit = mustFailWith(StatusCodes.BadRequest, expected.map(_.description): _*) - } - def mustFailWith401(implicit line: SL, file: SF): Unit = { + def mustFailWith401(implicit line: SL, file: SF): Unit = mustFailWith(StatusCodes.Unauthorized, "The resource requires authentication, which was not supplied with the request") - } - def mustFailWithMessage(expected: String*)(implicit line: SL, file: SF): Unit = { + def mustFailWithMessage(expected: String*)(implicit line: SL, file: SF): Unit = mustFailWith(StatusCodes.BadRequest, expected: _*) - } - private def mustFailWith(statusCode: StatusCode, expected: String*)(implicit line: SL, - file: SF): Unit = { + private def mustFailWith(statusCode: StatusCode, expected: String*)(implicit line: SL, file: SF): Unit = { mustHaveStatus(statusCode) val expectedRegex = expected.map( - _.split( - Pattern.quote("%ANY%"), - -1 /* Keep trailing empty strings for "%ANY" at the end of the pattern. */ ).toList - .map(Pattern.quote) - .mkString(".*?")) + _.split(Pattern.quote("%ANY%"), + -1 /* Keep trailing empty strings for "%ANY" at the end of the pattern. */ ).toList + .map(Pattern.quote) + .mkString(".*?")) expectedRegex.toList match { case only :: Nil ⇒ response.error must (fullyMatch regex only) diff --git a/phoenix-scala/phoenix/test/integration/time/JavaTimeMapperTest.scala b/phoenix-scala/phoenix/test/integration/time/JavaTimeMapperTest.scala index fb0e8588bc..997221db06 100644 --- a/phoenix-scala/phoenix/test/integration/time/JavaTimeMapperTest.scala +++ b/phoenix-scala/phoenix/test/integration/time/JavaTimeMapperTest.scala @@ -46,7 +46,7 @@ class JavaTimeMapperTest extends IntegrationTestBase with DbTestSupport { .futureValue timestampAfterRoundtrip must === ( - ZonedDateTime.of(2015, 7, 1, 15, 17, 38, 0, ZoneId.of("UTC")).toInstant) + ZonedDateTime.of(2015, 7, 1, 15, 17, 38, 0, ZoneId.of("UTC")).toInstant) } } } diff --git a/phoenix-scala/phoenix/test/integration/utils/MockedApis.scala b/phoenix-scala/phoenix/test/integration/utils/MockedApis.scala index 57fecb7683..3d3843e58d 100644 --- a/phoenix-scala/phoenix/test/integration/utils/MockedApis.scala +++ b/phoenix-scala/phoenix/test/integration/utils/MockedApis.scala @@ -137,25 +137,24 @@ trait MockedApis extends MockitoSugar with MustMatchers with OptionValues with A implicit def apisOverride: Option[Apis] = apis.some - def assertActivities(assertion: List[OpaqueActivity] ⇒ Assertion): Assertion = { + def assertActivities(assertion: List[OpaqueActivity] ⇒ Assertion): Assertion = assertion( - kafkaMock - .history() - .asScala - .map { record ⇒ - val activityKind = Option(record.value().get("kind")) - .flatMap(_.cast[String]) - .value - .withClue("Failed to find activity kind inside kafka record") - val data = Option(record.value().get("data")) - .flatMap(_.cast[String]) - .flatMap(parseOpt(_)) - .value - .withClue("Failed to find activity data inside kafka record") - - OpaqueActivity(activityKind, data) - }(collection.breakOut)) - } + kafkaMock + .history() + .asScala + .map { record ⇒ + val activityKind = Option(record.value().get("kind")) + .flatMap(_.cast[String]) + .value + .withClue("Failed to find activity kind inside kafka record") + val data = Option(record.value().get("data")) + .flatMap(_.cast[String]) + .flatMap(parseOpt(_)) + .value + .withClue("Failed to find activity data inside kafka record") + + OpaqueActivity(activityKind, data) + }(collection.breakOut)) def mustProduceActivity[A <: ActivityBase[A]: Manifest](entity: A): Assertion = assertActivities(_ must contain(entity.toOpaque)) diff --git a/phoenix-scala/phoenix/test/integration/utils/ModelIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/utils/ModelIntegrationTest.scala index 2c3394c8f6..327d7d157e 100644 --- a/phoenix-scala/phoenix/test/integration/utils/ModelIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/utils/ModelIntegrationTest.scala @@ -19,7 +19,7 @@ class ModelIntegrationTest extends IntegrationTestBase with TestObjectContext wi val failures = Addresses.create(Factories.address.copy(zip = "totallyNotAValidZip")).gimmeFailures failures must === ( - GeneralFailure("zip must fully match regular expression '^\\d{5}(?:\\d{4})?$'").single) + GeneralFailure("zip must fully match regular expression '^\\d{5}(?:\\d{4})?$'").single) } "sanitizes model" in { @@ -28,9 +28,9 @@ class ModelIntegrationTest extends IntegrationTestBase with TestObjectContext wi scope ← * <~ Scopes.forOrganization(TENANT) customer ← * <~ Users.create(Factories.customer.copy(accountId = account.id)) _ ← * <~ CustomersData.create( - CustomerData(userId = customer.id, accountId = account.id, scope = scope)) + CustomerData(userId = customer.id, accountId = account.id, scope = scope)) address ← * <~ Addresses.create( - Factories.address.copy(zip = "123-45", accountId = customer.accountId)) + Factories.address.copy(zip = "123-45", accountId = customer.accountId)) } yield address).gimme result.zip must === ("12345") } @@ -42,14 +42,14 @@ class ModelIntegrationTest extends IntegrationTestBase with TestObjectContext wi customer ← * <~ Users.create(Factories.customer.copy(accountId = account.id)) scope ← * <~ Scopes.forOrganization(TENANT) _ ← * <~ CustomersData.create( - CustomerData(userId = customer.id, accountId = account.id, scope = scope)) + CustomerData(userId = customer.id, accountId = account.id, scope = scope)) _ ← * <~ Addresses.create(Factories.address.copy(accountId = customer.accountId)) copycat ← * <~ Addresses.create(Factories.address.copy(accountId = customer.accountId)) } yield copycat).gimmeTxnFailures result must === ( - DatabaseFailure( - "ERROR: duplicate key value violates unique constraint \"address_shipping_default_idx\"\n" + - s" Detail: Key (account_id, is_default_shipping)=(${account.id}, t) already exists.").single) + DatabaseFailure( + "ERROR: duplicate key value violates unique constraint \"address_shipping_default_idx\"\n" + + s" Detail: Key (account_id, is_default_shipping)=(${account.id}, t) already exists.").single) } "fails if model already exists" in { @@ -91,8 +91,7 @@ class ModelIntegrationTest extends IntegrationTestBase with TestObjectContext wi val origin = Factories.order(Scope.current) val destination = origin.copy(state = Shipped) val failure = leftValue(origin.updateTo(destination)) - failure must === ( - StateTransitionNotAllowed(origin.state, destination.state, origin.refNum).single) + failure must === (StateTransitionNotAllowed(origin.state, destination.state, origin.refNum).single) } "must update model successfully" in { diff --git a/phoenix-scala/phoenix/test/integration/utils/RemorseTimerTest.scala b/phoenix-scala/phoenix/test/integration/utils/RemorseTimerTest.scala index 822814740c..11c0adf3eb 100644 --- a/phoenix-scala/phoenix/test/integration/utils/RemorseTimerTest.scala +++ b/phoenix-scala/phoenix/test/integration/utils/RemorseTimerTest.scala @@ -36,7 +36,7 @@ class RemorseTimerTest(_system: ActorSystem) } } - def tick(): Unit = { + def tick(): Unit = // Response received (timer ? Tick).futureValue match { case r: RemorseTimerResponse ⇒ @@ -45,5 +45,4 @@ class RemorseTimerTest(_system: ActorSystem) case _ ⇒ fail("Remorse timer had to reply with Future but something went wrong") } - } } diff --git a/phoenix-scala/phoenix/test/integration/utils/SlickTest.scala b/phoenix-scala/phoenix/test/integration/utils/SlickTest.scala index c4cc309fe6..85a1ad3dcc 100644 --- a/phoenix-scala/phoenix/test/integration/utils/SlickTest.scala +++ b/phoenix-scala/phoenix/test/integration/utils/SlickTest.scala @@ -38,9 +38,8 @@ class SlickTest extends IntegrationTestBase { "supports update with returning query for mapping to a new model" in { val (customer, updatedCustomer) = (for { - account ← * <~ Accounts.create(Account()) - customer ← * <~ Users.create( - Factories.customer.copy(accountId = account.id, name = "Jane".some)) + account ← * <~ Accounts.create(Account()) + customer ← * <~ Users.create(Factories.customer.copy(accountId = account.id, name = "Jane".some)) updatedCustomer ← * <~ Users .filter(_.id === customer.id) .map(_.name) @@ -53,9 +52,8 @@ class SlickTest extends IntegrationTestBase { "supports update with returning query for mapping to a new model for multiple columns" in { val (customer, updatedCustomer) = (for { - account ← * <~ Accounts.create(Account()) - customer ← * <~ Users.create( - Factories.customer.copy(accountId = account.id, name = "Jane".some)) + account ← * <~ Accounts.create(Account()) + customer ← * <~ Users.create(Factories.customer.copy(accountId = account.id, name = "Jane".some)) updatedCustomer ← * <~ Users .filter(_.id === customer.id) .map(_.name) diff --git a/phoenix-scala/phoenix/test/integration/utils/apis/MiddlewarehouseApiTest.scala b/phoenix-scala/phoenix/test/integration/utils/apis/MiddlewarehouseApiTest.scala index 05838b5b81..74bd14c740 100644 --- a/phoenix-scala/phoenix/test/integration/utils/apis/MiddlewarehouseApiTest.scala +++ b/phoenix-scala/phoenix/test/integration/utils/apis/MiddlewarehouseApiTest.scala @@ -17,7 +17,7 @@ class MiddlewarehouseApiTest extends TestBase { "MiddlewarehouseApi" - { "returns proper error message with sinle SKU that is out of stock" in { mwhApiTest( - """{ + """{ | "errors":[ | { | "sku":"SKU", @@ -25,12 +25,12 @@ class MiddlewarehouseApiTest extends TestBase { | } | ] |}""".stripMargin, - NonEmptyList.of(SkusOutOfStockFailure(List[String]("SKU"))) + NonEmptyList.of(SkusOutOfStockFailure(List[String]("SKU"))) ) } "returns proper error message with list of SKUs that are out of stock" in { mwhApiTest( - """{ + """{ | "errors":[ | { | "sku":"SKU1", @@ -42,18 +42,18 @@ class MiddlewarehouseApiTest extends TestBase { | } | ] |}""".stripMargin, - NonEmptyList.of(SkusOutOfStockFailure(List[String]("SKU1", "SKU2"))) + NonEmptyList.of(SkusOutOfStockFailure(List[String]("SKU1", "SKU2"))) ) } "returns proper errors with list of errors" in { mwhApiTest( - """{ + """{ | "errors":[ | "test1", | "test2" | ] |}""".stripMargin, - NonEmptyList.of(MiddlewarehouseError("test1"), MiddlewarehouseError("test2")) + NonEmptyList.of(MiddlewarehouseError("test1"), MiddlewarehouseError("test2")) ) } "returns default error message with empty error list" in { diff --git a/phoenix-scala/phoenix/test/unit/models/AddressTest.scala b/phoenix-scala/phoenix/test/unit/models/AddressTest.scala index 348118f908..204529389e 100644 --- a/phoenix-scala/phoenix/test/unit/models/AddressTest.scala +++ b/phoenix-scala/phoenix/test/unit/models/AddressTest.scala @@ -29,9 +29,9 @@ class AddressTest extends TestBase { val wrongLengthZip = valid.copy(zip = "1") val addresses = Table( - ("address", "errors"), - (badZip, zipFailure(Address.zipPattern)), - (wrongLengthZip, zipFailure(Address.zipPattern)) + ("address", "errors"), + (badZip, zipFailure(Address.zipPattern)), + (wrongLengthZip, zipFailure(Address.zipPattern)) ) forAll(addresses) { (address, errors) ⇒ @@ -44,9 +44,9 @@ class AddressTest extends TestBase { val wrongLengthZip = valid.copy(zip = "123456") val addresses = Table( - ("address", "errors"), - (tooShortZip, zipFailure(Address.zipPatternUs)), - (wrongLengthZip, zipFailure(Address.zipPatternUs)) + ("address", "errors"), + (tooShortZip, zipFailure(Address.zipPatternUs)), + (wrongLengthZip, zipFailure(Address.zipPatternUs)) ) forAll(addresses) { (address, errors) ⇒ @@ -57,21 +57,21 @@ class AddressTest extends TestBase { "returns errors when name or address1 is empty" in { val result = valid.copy(name = "", address1 = "").validate invalidValue(result) must === ( - NonEmptyList.of[Failure](GeneralFailure("name must not be empty"), - GeneralFailure("address1 must not be empty"))) + NonEmptyList.of[Failure](GeneralFailure("name must not be empty"), + GeneralFailure("address1 must not be empty"))) } "returns errors if US address and Some(phoneNumber) < 10 digits" in { val result = valid.copy(regionId = Region.usRegions.head, phoneNumber = Some("5551234")).validate invalidValue(result) must includeFailure( - "phoneNumber must fully match regular expression '[0-9]{10}'") + "phoneNumber must fully match regular expression '[0-9]{10}'") } "returns errors if non-US address and Some(phoneNumber) > 15 digits" in { val result = valid.copy(regionId = 1, phoneNumber = Some("1" * 16)).validate invalidValue(result) must includeFailure( - "phoneNumber must fully match regular expression '[0-9]{0,15}'") + "phoneNumber must fully match regular expression '[0-9]{0,15}'") } } } diff --git a/phoenix-scala/phoenix/test/unit/models/CartShippingAddressTest.scala b/phoenix-scala/phoenix/test/unit/models/CartShippingAddressTest.scala index a5363c931d..2ef54a1d64 100644 --- a/phoenix-scala/phoenix/test/unit/models/CartShippingAddressTest.scala +++ b/phoenix-scala/phoenix/test/unit/models/CartShippingAddressTest.scala @@ -19,9 +19,9 @@ class CartShippingAddressTest extends TestBase { val wrongLengthZip = Factories.shippingAddress.copy(regionId = 1, zip = "1") val addresses = Table( - ("address", "errors"), - (badZip, zipFailure(Address.zipPattern)), - (wrongLengthZip, zipFailure(Address.zipPattern)) + ("address", "errors"), + (badZip, zipFailure(Address.zipPattern)), + (wrongLengthZip, zipFailure(Address.zipPattern)) ) forAll(addresses) { (address, errors) ⇒ diff --git a/phoenix-scala/phoenix/test/unit/models/CreditCardTest.scala b/phoenix-scala/phoenix/test/unit/models/CreditCardTest.scala index e8ca9f5793..5e14fb57d4 100644 --- a/phoenix-scala/phoenix/test/unit/models/CreditCardTest.scala +++ b/phoenix-scala/phoenix/test/unit/models/CreditCardTest.scala @@ -21,9 +21,9 @@ class CreditCardTest extends TestBase { card.copy(expMonth = today.getMonthValue, expYear = today.minusYears(1).getYear) val cards = Table( - ("card", "errors"), - (expiredCard, NonEmptyList.of(GeneralFailure("credit card is expired"))), - (card.copy(expYear = 2000), NonEmptyList.of(GeneralFailure("credit card is expired"))) + ("card", "errors"), + (expiredCard, NonEmptyList.of(GeneralFailure("credit card is expired"))), + (card.copy(expYear = 2000), NonEmptyList.of(GeneralFailure("credit card is expired"))) ) forAll(cards) { (card, errors) ⇒ @@ -43,15 +43,15 @@ class CreditCardTest extends TestBase { "returns errors when zip is invalid" in { val zipFailure: NonEmptyList[Failure] = NonEmptyList.of( - GeneralFailure(s"zip must fully match regular expression '${Address.zipPatternUs}'")) + GeneralFailure(s"zip must fully match regular expression '${Address.zipPatternUs}'")) val badZip = card.copy(address = card.address.copy(zip = "AB+123")) val wrongLengthZip = card.copy(address = card.address.copy(zip = "1")) val cards = Table( - ("creditCards", "errors"), - (badZip, zipFailure), - (wrongLengthZip, zipFailure) + ("creditCards", "errors"), + (badZip, zipFailure), + (wrongLengthZip, zipFailure) ) forAll(cards) { (cc, errors) ⇒ diff --git a/phoenix-scala/phoenix/test/unit/models/CustomerTest.scala b/phoenix-scala/phoenix/test/unit/models/CustomerTest.scala index e0878d37b9..234da6f9c1 100644 --- a/phoenix-scala/phoenix/test/unit/models/CustomerTest.scala +++ b/phoenix-scala/phoenix/test/unit/models/CustomerTest.scala @@ -27,9 +27,9 @@ class CustomerTest extends TestBase { val c = Factories.customer val customers = Table( - ("users", "errors"), - (c.copy(email = Some("")), "email must not be empty"), - (c.copy(name = Some("")), "name must not be empty") + ("users", "errors"), + (c.copy(email = Some("")), "email must not be empty"), + (c.copy(name = Some("")), "name must not be empty") ) forAll(customers) { diff --git a/phoenix-scala/phoenix/test/unit/models/GiftCardTest.scala b/phoenix-scala/phoenix/test/unit/models/GiftCardTest.scala index 9a1b07ef91..2f3a6da80a 100644 --- a/phoenix-scala/phoenix/test/unit/models/GiftCardTest.scala +++ b/phoenix-scala/phoenix/test/unit/models/GiftCardTest.scala @@ -25,8 +25,7 @@ class GiftCardTest extends TestBase { "returns errors when balances >= 0" in { val gc = Factories.giftCard.copy(originalBalance = 0, currentBalance = -1) val result = gc.validate - invalidValue(result) must includeFailure( - "currentBalance should be greater or equal than zero") + invalidValue(result) must includeFailure("currentBalance should be greater or equal than zero") } } } diff --git a/phoenix-scala/phoenix/test/unit/models/ReasonTest.scala b/phoenix-scala/phoenix/test/unit/models/ReasonTest.scala index 5e40791f1b..80dc32a639 100644 --- a/phoenix-scala/phoenix/test/unit/models/ReasonTest.scala +++ b/phoenix-scala/phoenix/test/unit/models/ReasonTest.scala @@ -15,8 +15,8 @@ class ReasonTest extends TestBase { val emptyBodyReason = Factories.reason(0).copy(body = "") val reasons = Table( - ("reason", "errors"), - (emptyBodyReason, NonEmptyList.of(GeneralFailure("body must not be empty"))) + ("reason", "errors"), + (emptyBodyReason, NonEmptyList.of(GeneralFailure("body must not be empty"))) ) forAll(reasons) { (reason: Reason, errors: NonEmptyList[GeneralFailure]) ⇒ diff --git a/phoenix-scala/phoenix/test/unit/models/StoreCreditTest.scala b/phoenix-scala/phoenix/test/unit/models/StoreCreditTest.scala index ba81085b8a..3b42232f8b 100644 --- a/phoenix-scala/phoenix/test/unit/models/StoreCreditTest.scala +++ b/phoenix-scala/phoenix/test/unit/models/StoreCreditTest.scala @@ -18,16 +18,14 @@ class StoreCreditTest extends TestBase { "StoreCredit" - { ".validateNew" - { "fails when originalBalance is less than zero" in { - val sc = Factories.storeCredit.copy(originalBalance = -1, - availableBalance = 0, - currentBalance = 0) + val sc = Factories.storeCredit.copy(originalBalance = -1, availableBalance = 0, currentBalance = 0) val result = sc.validate result mustBe 'invalid result.fold(identity, m ⇒ NEL.of(m.modelName)) mustBe NEL.of( - GeneralFailure("originalBalance cannot be less than currentBalance"), - GeneralFailure("originalBalance cannot be less than availableBalance"), - GeneralFailure("originalBalance must be greater than zero") + GeneralFailure("originalBalance cannot be less than currentBalance"), + GeneralFailure("originalBalance cannot be less than availableBalance"), + GeneralFailure("originalBalance must be greater than zero") ) } @@ -37,7 +35,7 @@ class StoreCreditTest extends TestBase { result mustBe 'invalid result.fold(identity, m ⇒ NEL.of(m.modelName)) mustBe NEL.of( - GeneralFailure("canceledAmount must be present when canceled") + GeneralFailure("canceledAmount must be present when canceled") ) } diff --git a/phoenix-scala/phoenix/test/unit/models/objects/ObjectUtilsTest.scala b/phoenix-scala/phoenix/test/unit/models/objects/ObjectUtilsTest.scala index c4843c67ae..c63ce352c2 100644 --- a/phoenix-scala/phoenix/test/unit/models/objects/ObjectUtilsTest.scala +++ b/phoenix-scala/phoenix/test/unit/models/objects/ObjectUtilsTest.scala @@ -47,7 +47,7 @@ class ObjectUtilsTest extends TestBase with GeneratorDrivenPropertyChecks { ObjectUtils.updateForm(oldForm, toJObject(humanFormUpdate)) updatedForm.asInstanceOf[JObject].obj.toMap must === ( - toForm(oldHumanForm) ++ toForm(humanFormUpdate)) + toForm(oldHumanForm) ++ toForm(humanFormUpdate)) updatedKeymap must === (toKeyMap(humanFormUpdate)) } } diff --git a/phoenix-scala/phoenix/test/unit/models/rules/ConditionTest.scala b/phoenix-scala/phoenix/test/unit/models/rules/ConditionTest.scala index 7ad3c17ef1..e5f770384b 100644 --- a/phoenix-scala/phoenix/test/unit/models/rules/ConditionTest.scala +++ b/phoenix-scala/phoenix/test/unit/models/rules/ConditionTest.scala @@ -9,17 +9,13 @@ class ConditionTest extends TestBase { "#matches(Int, Condition)" - { "Equals" - { "returns true when values are equal" in { - val c = Factories.condition.copy(operator = Condition.Equals, - valInt = Some(50), - valString = None) + val c = Factories.condition.copy(operator = Condition.Equals, valInt = Some(50), valString = None) val result = Condition.matches(50, c) result must === (true) } "returns false when values are not equal" in { - val c = Factories.condition.copy(operator = Condition.Equals, - valInt = Some(50), - valString = None) + val c = Factories.condition.copy(operator = Condition.Equals, valInt = Some(50), valString = None) val result = Condition.matches(51, c) result must === (false) } @@ -27,17 +23,15 @@ class ConditionTest extends TestBase { "NotEquals" - { "returns false when values are equal" in { - val c = Factories.condition.copy(operator = Condition.NotEquals, - valInt = Some(50), - valString = None) + val c = + Factories.condition.copy(operator = Condition.NotEquals, valInt = Some(50), valString = None) val result = Condition.matches(50, c) result must === (false) } "returns true when values are not equal" in { - val c = Factories.condition.copy(operator = Condition.NotEquals, - valInt = Some(50), - valString = None) + val c = + Factories.condition.copy(operator = Condition.NotEquals, valInt = Some(50), valString = None) val result = Condition.matches(51, c) result must === (true) } @@ -45,25 +39,22 @@ class ConditionTest extends TestBase { "GreaterThan" - { "returns true when value is greater than condition" in { - val c = Factories.condition.copy(operator = Condition.GreaterThan, - valInt = Some(50), - valString = None) + val c = + Factories.condition.copy(operator = Condition.GreaterThan, valInt = Some(50), valString = None) val result = Condition.matches(51, c) result must === (true) } "returns false when value is equal to condition" in { - val c = Factories.condition.copy(operator = Condition.GreaterThan, - valInt = Some(50), - valString = None) + val c = + Factories.condition.copy(operator = Condition.GreaterThan, valInt = Some(50), valString = None) val result = Condition.matches(50, c) result must === (false) } "returns false when value is less than condition" in { - val c = Factories.condition.copy(operator = Condition.GreaterThan, - valInt = Some(50), - valString = None) + val c = + Factories.condition.copy(operator = Condition.GreaterThan, valInt = Some(50), valString = None) val result = Condition.matches(49, c) result must === (false) } @@ -71,25 +62,19 @@ class ConditionTest extends TestBase { "LessThan" - { "returns false when value is greater than condition" in { - val c = Factories.condition.copy(operator = Condition.LessThan, - valInt = Some(50), - valString = None) + val c = Factories.condition.copy(operator = Condition.LessThan, valInt = Some(50), valString = None) val result = Condition.matches(51, c) result must === (false) } "returns false when value is equal to condition" in { - val c = Factories.condition.copy(operator = Condition.LessThan, - valInt = Some(50), - valString = None) + val c = Factories.condition.copy(operator = Condition.LessThan, valInt = Some(50), valString = None) val result = Condition.matches(50, c) result must === (false) } "returns true when value is less than condition" in { - val c = Factories.condition.copy(operator = Condition.LessThan, - valInt = Some(50), - valString = None) + val c = Factories.condition.copy(operator = Condition.LessThan, valInt = Some(50), valString = None) val result = Condition.matches(49, c) result must === (true) } @@ -167,15 +152,13 @@ class ConditionTest extends TestBase { "NotEquals" - { "returns false when values are equal" in { - val c = Factories.condition.copy(operator = Condition.NotEquals, - valString = Some("some string")) + val c = Factories.condition.copy(operator = Condition.NotEquals, valString = Some("some string")) val result = Condition.matches("some string", c) result must === (false) } "returns true when values are not equal" in { - val c = Factories.condition.copy(operator = Condition.NotEquals, - valString = Some("some string")) + val c = Factories.condition.copy(operator = Condition.NotEquals, valString = Some("some string")) val result = Condition.matches("another string", c) result must === (true) } @@ -233,15 +216,13 @@ class ConditionTest extends TestBase { "NotEquals" - { "returns false when values are equal" in { - val c = Factories.condition.copy(operator = Condition.NotEquals, - valString = Some("some string")) + val c = Factories.condition.copy(operator = Condition.NotEquals, valString = Some("some string")) val result = Condition.matches(Some("some string"), c) result must === (false) } "returns true when values are not equal" in { - val c = Factories.condition.copy(operator = Condition.NotEquals, - valString = Some("some string")) + val c = Factories.condition.copy(operator = Condition.NotEquals, valString = Some("some string")) val result = Condition.matches(Some("another string"), c) result must === (true) } diff --git a/phoenix-scala/phoenix/test/unit/payloads/PaymentPayloadsTest.scala b/phoenix-scala/phoenix/test/unit/payloads/PaymentPayloadsTest.scala index 1ca11e7fb9..891a9e2786 100644 --- a/phoenix-scala/phoenix/test/unit/payloads/PaymentPayloadsTest.scala +++ b/phoenix-scala/phoenix/test/unit/payloads/PaymentPayloadsTest.scala @@ -56,14 +56,13 @@ class PaymentPayloadsTest extends TestBase { } "fails with expired date" in { - val expired = valid.copy(expMonth = today.getMonthValue.some, - expYear = today.minusYears(1).getYear.some) + val expired = + valid.copy(expMonth = today.getMonthValue.some, expYear = today.minusYears(1).getYear.some) val cards = Table( - ("payload", "errors"), - (expired, NonEmptyList.of(GeneralFailure("credit card is expired"))), - (expired.copy(expYear = 2000.some), - NonEmptyList.of(GeneralFailure("credit card is expired"))) + ("payload", "errors"), + (expired, NonEmptyList.of(GeneralFailure("credit card is expired"))), + (expired.copy(expYear = 2000.some), NonEmptyList.of(GeneralFailure("credit card is expired"))) ) forAll(cards) { (card, errors) ⇒ diff --git a/phoenix-scala/phoenix/test/unit/services/OfferAstCompilerTest.scala b/phoenix-scala/phoenix/test/unit/services/OfferAstCompilerTest.scala index b441a80805..ea67ef1ba1 100644 --- a/phoenix-scala/phoenix/test/unit/services/OfferAstCompilerTest.scala +++ b/phoenix-scala/phoenix/test/unit/services/OfferAstCompilerTest.scala @@ -21,8 +21,7 @@ class OfferAstCompilerTest extends TestBase { "fails when typo in configuration found" in new OrderPercentOfferTypoFixture { val cause = "No usable value for discount\nDid not find value which can be converted into long" - leftValue(compiler.compile()) must === ( - OfferAttributesExtractionFailure(OrderPercentOff, cause).single) + leftValue(compiler.compile()) must === (OfferAttributesExtractionFailure(OrderPercentOff, cause).single) } } diff --git a/phoenix-scala/phoenix/test/unit/services/QualifierAstCompilerTest.scala b/phoenix-scala/phoenix/test/unit/services/QualifierAstCompilerTest.scala index 517a04344f..43e524c028 100644 --- a/phoenix-scala/phoenix/test/unit/services/QualifierAstCompilerTest.scala +++ b/phoenix-scala/phoenix/test/unit/services/QualifierAstCompilerTest.scala @@ -15,15 +15,14 @@ class QualifierAstCompilerTest extends TestBase { } "succeeds for case class with valid attributes" in new OrderTotalAmountValidFixture { - rightValue(compiler.compile()) must === ( - AndQualifier(Seq(OrderTotalAmountQualifier(totalAmount = 1)))) + rightValue(compiler.compile()) must === (AndQualifier(Seq(OrderTotalAmountQualifier(totalAmount = 1)))) } "fails when typo in configuration found" in new OrderTotalAmountTypoFixture { val cause = "No usable value for totalAmount\nDid not find value which can be converted into long" leftValue(compiler.compile()) must === ( - QualifierAttributesExtractionFailure(OrderTotalAmount, cause).single) + QualifierAttributesExtractionFailure(OrderTotalAmount, cause).single) } } diff --git a/phoenix-scala/phoenix/test/unit/testutils/CatsHelpers.scala b/phoenix-scala/phoenix/test/unit/testutils/CatsHelpers.scala index 620260c455..34f094558d 100644 --- a/phoenix-scala/phoenix/test/unit/testutils/CatsHelpers.scala +++ b/phoenix-scala/phoenix/test/unit/testutils/CatsHelpers.scala @@ -9,27 +9,26 @@ trait CatsHelpers extends Assertions { def rightValue[A, B](either: Either[A, B])(implicit ttA: TypeTag[A], ttB: TypeTag[B]): B = either.fold( - l ⇒ fail(s"Expected Right[${ttB.tpe.dealias}], got Left[${ttA.tpe.dealias}]: $l"), - r ⇒ r + l ⇒ fail(s"Expected Right[${ttB.tpe.dealias}], got Left[${ttA.tpe.dealias}]: $l"), + r ⇒ r ) def leftValue[A, B](either: Either[A, B])(implicit ttA: TypeTag[A], ttB: TypeTag[B]): A = either.fold( - l ⇒ l, - r ⇒ fail(s"Expected Left[${ttA.tpe.dealias}], got Right[${ttB.tpe.dealias}]: $r") + l ⇒ l, + r ⇒ fail(s"Expected Left[${ttA.tpe.dealias}], got Right[${ttB.tpe.dealias}]: $r") ) def validValue[E, A](validated: Validated[E, A])(implicit ttA: TypeTag[A], ttE: TypeTag[E]): A = validated.fold( - e ⇒ fail(s"Expected Valid[${ttA.tpe.dealias}], got Invalid[${ttE.tpe.dealias}]: $e"), - a ⇒ a + e ⇒ fail(s"Expected Valid[${ttA.tpe.dealias}], got Invalid[${ttE.tpe.dealias}]: $e"), + a ⇒ a ) - def invalidValue[E, A](validated: Validated[E, A])(implicit ttA: TypeTag[A], - ttE: TypeTag[E]): E = + def invalidValue[E, A](validated: Validated[E, A])(implicit ttA: TypeTag[A], ttE: TypeTag[E]): E = validated.fold( - e ⇒ e, - a ⇒ fail(s"Expected Invalid[${ttA.tpe.dealias}], got Valid[${ttE.tpe.dealias}]: $a") + e ⇒ e, + a ⇒ fail(s"Expected Invalid[${ttA.tpe.dealias}], got Valid[${ttE.tpe.dealias}]: $a") ) implicit class ImplicitCatsHelpersEither[A, B](either: Either[A, B]) { diff --git a/phoenix-scala/phoenix/test/unit/testutils/CatsHelpersTest.scala b/phoenix-scala/phoenix/test/unit/testutils/CatsHelpersTest.scala index 546ec1ac10..3ebee98fc7 100644 --- a/phoenix-scala/phoenix/test/unit/testutils/CatsHelpersTest.scala +++ b/phoenix-scala/phoenix/test/unit/testutils/CatsHelpersTest.scala @@ -20,10 +20,10 @@ class CatsHelpersTest extends TestBase with CatsHelpers { } exception.getMessage must (include("Expected Right") and - include("got Left") and - include("Invalid number") and - include("Option[Long]") and - include("String")) + include("got Left") and + include("Invalid number") and + include("Option[Long]") and + include("String")) } } } @@ -37,10 +37,10 @@ class CatsHelpersTest extends TestBase with CatsHelpers { } exception.getMessage must (include("Expected Left") and - include("got Right") and - include("Some(42)") and - include("Option[Long]") and - include("String")) + include("got Right") and + include("Some(42)") and + include("Option[Long]") and + include("String")) } } @@ -70,9 +70,9 @@ class CatsHelpersTest extends TestBase with CatsHelpers { } exception.getMessage must (include("Expected Valid") and - include("got Invalid") and - include("That is not a number!") and - include("String")) + include("got Invalid") and + include("That is not a number!") and + include("String")) } } } @@ -88,9 +88,9 @@ class CatsHelpersTest extends TestBase with CatsHelpers { } exception.getMessage must (include("Expected Invalid") and - include("got Valid") and - include("Some(42)") and - include("String")) + include("got Valid") and + include("Some(42)") and + include("String")) } } diff --git a/phoenix-scala/phoenix/test/unit/testutils/CustomMatchers.scala b/phoenix-scala/phoenix/test/unit/testutils/CustomMatchers.scala index ee7ec304dc..ca3a1ceb0d 100644 --- a/phoenix-scala/phoenix/test/unit/testutils/CustomMatchers.scala +++ b/phoenix-scala/phoenix/test/unit/testutils/CustomMatchers.scala @@ -7,13 +7,12 @@ import org.scalatest.matchers._ object CustomMatchers { // Same as `include`, used for Failure inner Strings class IncludeFailureMatcher(f: Failure) extends Matcher[NonEmptyList[Failure]] { - def apply(left: NonEmptyList[Failure]) = { + def apply(left: NonEmptyList[Failure]) = MatchResult( - left.exists(_.description.toSet.subsetOf(f.description.toSet)), - s"""$left does not contain "$f"""", - s"""$left contains "$f"""" + left.exists(_.description.toSet.subsetOf(f.description.toSet)), + s"""$left does not contain "$f"""", + s"""$left contains "$f"""" ) - } } def includeFailure(expectedSubstring: String) = @@ -21,11 +20,9 @@ object CustomMatchers { def includeFailure(f: Failure) = new IncludeFailureMatcher(f) - def buildMatchesFailure(constraint: String, pattern: String) = { + def buildMatchesFailure(constraint: String, pattern: String) = GeneralFailure(s"$constraint must fully match regular expression '$pattern'") - } - def includeMatchesFailure(constraint: String, pattern: String) = { + def includeMatchesFailure(constraint: String, pattern: String) = includeFailure(buildMatchesFailure(constraint, pattern)) - } } diff --git a/phoenix-scala/phoenix/test/unit/testutils/TestBase.scala b/phoenix-scala/phoenix/test/unit/testutils/TestBase.scala index 280b28f0e8..559e00fdfe 100644 --- a/phoenix-scala/phoenix/test/unit/testutils/TestBase.scala +++ b/phoenix-scala/phoenix/test/unit/testutils/TestBase.scala @@ -22,8 +22,8 @@ trait TestBase with CatsHelpers { override implicit def patienceConfig: PatienceConfig = PatienceConfig( - timeout = Span(10, Seconds), - interval = Span(15, Milliseconds) + timeout = Span(10, Seconds), + interval = Span(15, Milliseconds) ) implicit val timeout: Timeout = Timeout(10, TimeUnit.SECONDS) diff --git a/phoenix-scala/phoenix/test/unit/utils/FSMTest.scala b/phoenix-scala/phoenix/test/unit/utils/FSMTest.scala index b371c16930..717001875c 100644 --- a/phoenix-scala/phoenix/test/unit/utils/FSMTest.scala +++ b/phoenix-scala/phoenix/test/unit/utils/FSMTest.scala @@ -16,18 +16,16 @@ class FSMTest extends TestBase { case object LockAndPop extends Operation case object BreakItDown extends Operation - case class Robot(id: Int = 0, state: Operation) - extends FoxModel[Robot] - with FSM[Operation, Robot] { + case class Robot(id: Int = 0, state: Operation) extends FoxModel[Robot] with FSM[Operation, Robot] { def stateLens = lens[Robot].state override def updateTo(newModel: Robot): Either[Failures, Robot] = super.transitionModel(newModel) val fsm: Map[Operation, Set[Operation]] = Map( - Pop → Set(Lock, LockAndPop), - Lock → Set(Pop, PopAndLock), - PopAndLock → Set(Pop, BreakItDown), - LockAndPop → Set(Lock, BreakItDown) + Pop → Set(Lock, LockAndPop), + Lock → Set(Pop, PopAndLock), + PopAndLock → Set(Pop, BreakItDown), + LockAndPop → Set(Lock, BreakItDown) ) } @@ -46,12 +44,12 @@ class FSMTest extends TestBase { "can always transition to identity state" in { val states = Table( - "state", - Pop, - Lock, - PopAndLock, - LockAndPop, - BreakItDown + "state", + Pop, + Lock, + PopAndLock, + LockAndPop, + BreakItDown ) forAll(states) { diff --git a/phoenix-scala/phoenix/test/unit/utils/JsonFormattersTest.scala b/phoenix-scala/phoenix/test/unit/utils/JsonFormattersTest.scala index 6a2862a592..6d18c5f4c6 100644 --- a/phoenix-scala/phoenix/test/unit/utils/JsonFormattersTest.scala +++ b/phoenix-scala/phoenix/test/unit/utils/JsonFormattersTest.scala @@ -19,20 +19,17 @@ class JsonFormattersTest extends TestBase { implicit val formats: Formats = phoenixFormats - case class Test(order: Order.State, - gc: GiftCard.State, - cc: ExternalCharge.State, - sas: AdminData.State) + case class Test(order: Order.State, gc: GiftCard.State, cc: ExternalCharge.State, sas: AdminData.State) case class Product(price: Long, currency: Currency) "Adt serialization" - { "can (de-)serialize JSON" in { val ast = parse( - write( - Test(order = Order.ManualHold, - cc = ExternalCharge.Auth, - gc = GiftCard.OnHold, - sas = AdminData.Invited))) + write( + Test(order = Order.ManualHold, + cc = ExternalCharge.Auth, + gc = GiftCard.OnHold, + sas = AdminData.Invited))) (ast \ "order").extract[Order.State] mustBe Order.ManualHold (ast \ "gc").extract[GiftCard.State] mustBe GiftCard.OnHold (ast \ "cc").extract[ExternalCharge.State] mustBe ExternalCharge.Auth diff --git a/phoenix-scala/phoenix/test/unit/utils/UtilsTest.scala b/phoenix-scala/phoenix/test/unit/utils/UtilsTest.scala index ae385e5708..0358676b9e 100644 --- a/phoenix-scala/phoenix/test/unit/utils/UtilsTest.scala +++ b/phoenix-scala/phoenix/test/unit/utils/UtilsTest.scala @@ -18,8 +18,7 @@ class UtilsTest extends TestBase { "camelToUnderscores" - { "should convert camelCase class to snake_case string" in { snakeCaseName(CreateNote(body = "test")) must === ("create_note") - snakeCaseName(GiftCardCreateByCsr(balance = 10, reasonId = 1)) must === ( - "gift_card_create_by_csr") + snakeCaseName(GiftCardCreateByCsr(balance = 10, reasonId = 1)) must === ("gift_card_create_by_csr") } } diff --git a/phoenix-scala/project/Dependencies.scala b/phoenix-scala/project/Dependencies.scala index af5dd592a8..3516f3b5e0 100644 --- a/phoenix-scala/project/Dependencies.scala +++ b/phoenix-scala/project/Dependencies.scala @@ -1,16 +1,16 @@ import sbt._ object Versions { - val scala = "2.11.11-bin-typelevel-4" - val slick = "3.2.0" - val json4s = "3.4.0" - val akka = "2.4.7" - val slickPg = "0.15.0" - val gatling = "2.2.1" - val dispatch = "0.11.3" - val fasterxml = "2.8.2" - val elastic4s = "2.3.0" - val scalatest = "3.0.1" + val scala = "2.11.11-bin-typelevel-4" + val slick = "3.2.0" + val json4s = "3.4.0" + val akka = "2.4.7" + val slickPg = "0.15.0" + val gatling = "2.2.1" + val dispatch = "0.11.3" + val fasterxml = "2.8.2" + val elastic4s = "2.3.0" + val scalatest = "3.0.1" val scalacheck = "1.13.4" } @@ -49,14 +49,14 @@ object Dependencies { ) val db = Seq( - "com.github.tminglei" %% "slick-pg" % Versions.slickPg, - "com.github.tminglei" %% "slick-pg_json4s" % Versions.slickPg, - "com.zaxxer" % "HikariCP" % "2.6.1", - "org.postgresql" % "postgresql" % "42.1.1", - "org.flywaydb" % "flyway-core" % "4.0.3", - "com.wix" %% "accord-core" % "0.5", // Validation - "io.backchat.inflector" %% "scala-inflector" % "1.3.5", // used only for singularizing table names in error messages… - ("org.joda" % "joda-money" % "0.11").exclude("org.joda", "joda-time"), + "com.github.tminglei" %% "slick-pg" % Versions.slickPg, + "com.github.tminglei" %% "slick-pg_json4s" % Versions.slickPg, + "com.zaxxer" % "HikariCP" % "2.6.1", + "org.postgresql" % "postgresql" % "42.1.1", + "org.flywaydb" % "flyway-core" % "4.0.3", + "com.wix" %% "accord-core" % "0.5", // Validation + "io.backchat.inflector" %% "scala-inflector" % "1.3.5", // used only for singularizing table names in error messages… + ("org.joda" % "joda-money" % "0.11").exclude("org.joda", "joda-time"), "com.github.mauricio" %% "postgresql-async" % "0.2.20" ) @@ -94,21 +94,21 @@ object Dependencies { ) val misc = Seq( - "com.github.scopt" %% "scopt" % "3.5.0", // CLI args - "com.pellucid" %% "sealerate" % "0.0.3", - "it.justwrote" %% "scala-faker" % "0.3", - "org.conbere" % "markov_2.10" % "0.2.0", - "com.github.tototoshi" %% "scala-csv" % "1.3.3", - "com.github.melrief" %% "pureconfig" % "0.5.1", - "com.sksamuel.elastic4s"%% "elastic4s-streams" % Versions.elastic4s + "com.github.scopt" %% "scopt" % "3.5.0", // CLI args + "com.pellucid" %% "sealerate" % "0.0.3", + "it.justwrote" %% "scala-faker" % "0.3", + "org.conbere" % "markov_2.10" % "0.2.0", + "com.github.tototoshi" %% "scala-csv" % "1.3.3", + "com.github.melrief" %% "pureconfig" % "0.5.1", + "com.sksamuel.elastic4s" %% "elastic4s-streams" % Versions.elastic4s ) val cats = Seq( - "org.typelevel" %% "cats" % "0.9.0" + "org.typelevel" %% "cats" % "0.9.0" ) val shapeless = Seq( - "com.chuusai" %% "shapeless" % "2.3.1" + "com.chuusai" %% "shapeless" % "2.3.1" ) val kafka = Seq( diff --git a/phoenix-scala/project/Settings.scala b/phoenix-scala/project/Settings.scala index c51cfec2ee..6a4c65a77c 100644 --- a/phoenix-scala/project/Settings.scala +++ b/phoenix-scala/project/Settings.scala @@ -55,9 +55,9 @@ object Settings { }, resolvers ++= Seq( "hseeberger bintray" at "http://dl.bintray.com/hseeberger/maven", - "pellucid bintray" at "http://dl.bintray.com/pellucid/maven", - "justwrote" at "http://repo.justwrote.it/releases/", - "confluent" at "http://packages.confluent.io/maven/", + "pellucid bintray" at "http://dl.bintray.com/pellucid/maven", + "justwrote" at "http://repo.justwrote.it/releases/", + "confluent" at "http://packages.confluent.io/maven/", Resolver.bintrayRepo("kwark", "maven") // Slick with deadlock patch ) ) ++ sourceLocationSettings ++ Revolver.settings @@ -65,7 +65,7 @@ object Settings { // Let's keep project sources in `app` directory instead of `src/scala/main` // I also prefer `app` over `src` because sources end up on top of list in the project tree view! -- Anna lazy val sourceLocationSettings: Seq[Setting[_]] = Seq( - scalaSource in Compile := baseDirectory.value / "app", + scalaSource in Compile := baseDirectory.value / "app", resourceDirectory in Compile := baseDirectory.value / "resources" ) @@ -73,11 +73,11 @@ object Settings { Defaults.testTasks ++ Defaults.itSettings lazy val itSettings: Seq[Setting[_]] = inConfig(IT)(sharedItSettings) ++ Seq( - testOptions in IT := (testOptions in Test).value :+ Tests.Argument("-l", "tags.External") - ) + testOptions in IT := (testOptions in Test).value :+ Tests.Argument("-l", "tags.External") + ) lazy val etSettings: Seq[Setting[_]] = inConfig(ET)(sharedItSettings) ++ Seq( - testOptions in ET := (testOptions in Test).value :+ Tests.Argument("-n", "tags.External") - ) + testOptions in ET := (testOptions in Test).value :+ Tests.Argument("-n", "tags.External") + ) } diff --git a/phoenix-scala/seeder/app/gatling/package.scala b/phoenix-scala/seeder/app/gatling/package.scala index f17994d6e1..3e83b2e7dc 100644 --- a/phoenix-scala/seeder/app/gatling/package.scala +++ b/phoenix-scala/seeder/app/gatling/package.scala @@ -4,7 +4,7 @@ import io.gatling.core.scenario.Simulation import io.gatling.core.structure.StructureBuilder import io.gatling.http.request.builder.HttpRequestBuilder -import scala.reflect.{ClassTag, classTag} +import scala.reflect.{classTag, ClassTag} package object gatling { diff --git a/phoenix-scala/seeder/app/gatling/seeds/Seeder.scala b/phoenix-scala/seeder/app/gatling/seeds/Seeder.scala index d24febbde8..3da506302e 100644 --- a/phoenix-scala/seeder/app/gatling/seeds/Seeder.scala +++ b/phoenix-scala/seeder/app/gatling/seeds/Seeder.scala @@ -1,6 +1,6 @@ package gatling.seeds -import scala.reflect.{ClassTag, classTag} +import scala.reflect.{classTag, ClassTag} import io.gatling.app.Gatling import io.gatling.core.scenario.Simulation diff --git a/phoenix-scala/seeder/app/gatling/seeds/requests/Addresses.scala b/phoenix-scala/seeder/app/gatling/seeds/requests/Addresses.scala index 601e2e7f55..29b162a970 100644 --- a/phoenix-scala/seeder/app/gatling/seeds/requests/Addresses.scala +++ b/phoenix-scala/seeder/app/gatling/seeds/requests/Addresses.scala @@ -16,7 +16,7 @@ object Addresses { val USA_COUNTRY_CODE = 234 private val addressFeeder = dbFeeder( - s"""select id as "customerRegionId", name as "customerCity" from regions where country_id=$USA_COUNTRY_CODE""") + s"""select id as "customerRegionId", name as "customerCity" from regions where country_id=$USA_COUNTRY_CODE""") private val addCustomerAddress = http("Add new address for customer") .post("/v1/customers/${customerId}/addresses") @@ -29,14 +29,16 @@ object Addresses { city ← session("customerCity").validate[String] } yield json { - CreateAddressPayload(name = name, - regionId = regionId.toInt, - address1 = address, - city = city, - zip = nDigits(5), - isDefault = true, - phoneNumber = Some(nDigits(10)), - address2 = session("customerAddress2").asOption[String]) + CreateAddressPayload( + name = name, + regionId = regionId.toInt, + address1 = address, + city = city, + zip = nDigits(5), + isDefault = true, + phoneNumber = Some(nDigits(10)), + address2 = session("customerAddress2").asOption[String] + ) } }) .check(jsonPath("$.id").ofType[Int].saveAs("addressId")) @@ -44,7 +46,7 @@ object Addresses { private def nDigits(n: Int): String = numerify("#" * n) private val setDefaultShipping = http("Set address as default shipping address").post( - "/v1/customers/${customerId}/addresses/${addressId}/default") + "/v1/customers/${customerId}/addresses/${addressId}/default") private val randomAddressLine1 = feed(csv("data/address_gen.csv").random, 3).exec { session ⇒ val streetName = @@ -53,8 +55,8 @@ object Addresses { } private val randomAddressLine2 = uniformRandomSwitch( - exec(session ⇒ session.set("customerAddress2", s"Suite ${Random.nextInt(500) + 1}")), - exec(session ⇒ session.set("customerAddress2", s"Apt ${Random.nextInt(50) + 1}")) + exec(session ⇒ session.set("customerAddress2", s"Suite ${Random.nextInt(500) + 1}")), + exec(session ⇒ session.set("customerAddress2", s"Apt ${Random.nextInt(50) + 1}")) ) val addRandomAddress = step(randomAddressLine1) diff --git a/phoenix-scala/seeder/app/gatling/seeds/requests/Auth.scala b/phoenix-scala/seeder/app/gatling/seeds/requests/Auth.scala index 137ca80cdc..f8d2c5c49f 100644 --- a/phoenix-scala/seeder/app/gatling/seeds/requests/Auth.scala +++ b/phoenix-scala/seeder/app/gatling/seeds/requests/Auth.scala @@ -13,9 +13,8 @@ object Auth { val loginAsAdmin = http("Login as Admin") .post("/v1/public/login") - .body(StringBody(json(LoginPayload(email = "${adminEmail}", - password = "${adminPassword}", - org = "${adminOrg}")))) + .body(StringBody( + json(LoginPayload(email = "${adminEmail}", password = "${adminPassword}", org = "${adminOrg}")))) .check(header("JWT").saveAs("jwtTokenAdmin")) val loginAsRandomAdmin = feed(csv("data/store_admins.csv").random).exec(loginAsAdmin) diff --git a/phoenix-scala/seeder/app/gatling/seeds/requests/Cart.scala b/phoenix-scala/seeder/app/gatling/seeds/requests/Cart.scala index f3e2403283..ef42db202d 100644 --- a/phoenix-scala/seeder/app/gatling/seeds/requests/Cart.scala +++ b/phoenix-scala/seeder/app/gatling/seeds/requests/Cart.scala @@ -84,10 +84,9 @@ object Cart { .requireAdminAuth .body(StringBody { session ⇒ json( - OrderTimeMachine( - referenceNumber = session.get("referenceNumber").as[String], - placedAt = Instant.now.minusSeconds( - (Random.nextInt(15) * 60 * 60 * 24 * 30).toLong) // Minus ~15 months - )) + OrderTimeMachine( + referenceNumber = session.get("referenceNumber").as[String], + placedAt = Instant.now.minusSeconds((Random.nextInt(15) * 60 * 60 * 24 * 30).toLong) // Minus ~15 months + )) }) } diff --git a/phoenix-scala/seeder/app/gatling/seeds/requests/CreditCards.scala b/phoenix-scala/seeder/app/gatling/seeds/requests/CreditCards.scala index 2b7fe400ad..295c33b7a3 100644 --- a/phoenix-scala/seeder/app/gatling/seeds/requests/CreditCards.scala +++ b/phoenix-scala/seeder/app/gatling/seeds/requests/CreditCards.scala @@ -16,15 +16,16 @@ object CreditCards { .post("/v1/customers/${customerId}/payment-methods/credit-cards") .body(StringBody { session ⇒ json( - CreateCreditCardFromSourcePayload( - holderName = session.get("customerName").as[String], - cardNumber = session.get("ccNumber").as[String], - cvv = Lorem.numerify("###"), - expYear = - LocalDateTime.ofInstant(Instant.now, ZoneId.systemDefault).getYear + - 2 + Random.nextInt(5), - expMonth = Random.nextInt(12) + 1, - addressId = Some(session.get("addressId").as[Int]))) + CreateCreditCardFromSourcePayload( + holderName = session.get("customerName").as[String], + cardNumber = session.get("ccNumber").as[String], + cvv = Lorem.numerify("###"), + expYear = + LocalDateTime.ofInstant(Instant.now, ZoneId.systemDefault).getYear + + 2 + Random.nextInt(5), + expMonth = Random.nextInt(12) + 1, + addressId = Some(session.get("addressId").as[Int]) + )) }) .check(jsonPath("$.id").ofType[Int].saveAs("creditCardId")) @@ -38,7 +39,7 @@ object CreditCards { val payWithCc = feed(csv("data/credit_cards.csv").random) .doIfOrElse(session ⇒ session.contains("creditCardId")) { randomSwitch( - 30.0 → exec(createCreditCard) + 30.0 → exec(createCreditCard) ) } { exec(createCreditCard) diff --git a/phoenix-scala/seeder/app/gatling/seeds/requests/Customers.scala b/phoenix-scala/seeder/app/gatling/seeds/requests/Customers.scala index f14709d543..a1e92baf5a 100644 --- a/phoenix-scala/seeder/app/gatling/seeds/requests/Customers.scala +++ b/phoenix-scala/seeder/app/gatling/seeds/requests/Customers.scala @@ -12,9 +12,11 @@ object Customers { private val createCustomer = http("Create customer") .post("/v1/customers") .requireAdminAuth - .body(StringBody(json(CreateCustomerPayload(name = Option("${customerName}"), - email = "${customerEmail}", - password = Option("${customerPassword}"))))) + .body( + StringBody( + json(CreateCustomerPayload(name = Option("${customerName}"), + email = "${customerEmail}", + password = Option("${customerPassword}"))))) .check(jsonPath("$.id").ofType[Int].saveAs("customerId")) val createStaticCustomers = foreach(csv("data/customers.csv").records, "customerRecord") { diff --git a/phoenix-scala/seeder/app/gatling/seeds/requests/GiftCards.scala b/phoenix-scala/seeder/app/gatling/seeds/requests/GiftCards.scala index df907a0d78..5c711e61fc 100644 --- a/phoenix-scala/seeder/app/gatling/seeds/requests/GiftCards.scala +++ b/phoenix-scala/seeder/app/gatling/seeds/requests/GiftCards.scala @@ -16,24 +16,24 @@ object GiftCards { private val reasonType = Reason.GiftCardCreation.toString.lowerCaseFirstLetter private val reasonFeeder = dbFeeder( - s"""select id as "reasonId" from reasons where reason_type = '$reasonType'""") + s"""select id as "reasonId" from reasons where reason_type = '$reasonType'""") val createGiftCard = http("Create gift card") .post("/v1/gift-cards") .body( - StringBody( - session ⇒ - json(GiftCardCreateByCsr( - reasonId = session.get("reasonId").as[Int], - currency = Currency.USD, - balance = Random.nextInt(9500).toLong + 500 // from $5 to $100 - )))) + StringBody( + session ⇒ + json( + GiftCardCreateByCsr( + reasonId = session.get("reasonId").as[Int], + currency = Currency.USD, + balance = Random.nextInt(9500).toLong + 500 // from $5 to $100 + )))) .check(jsonPath("$.code").ofType[String].saveAs("giftCardCode")) val payWithGiftCard = http("Pay with gift card") .post("/v1/orders/${referenceNumber}/payment-methods/gift-cards") - .body(StringBody(session ⇒ - json(GiftCardPayment(code = session.get("giftCardCode").as[String])))) + .body(StringBody(session ⇒ json(GiftCardPayment(code = session.get("giftCardCode").as[String])))) val payWithGc = feed(reasonFeeder.random).exec(createGiftCard).exec(payWithGiftCard) } diff --git a/phoenix-scala/seeder/app/gatling/seeds/requests/Payments.scala b/phoenix-scala/seeder/app/gatling/seeds/requests/Payments.scala index 16ea84cfb1..312cdbb7d3 100644 --- a/phoenix-scala/seeder/app/gatling/seeds/requests/Payments.scala +++ b/phoenix-scala/seeder/app/gatling/seeds/requests/Payments.scala @@ -8,7 +8,7 @@ object Payments { // Add payment sequences here val pay = uniformRandomSwitch( - exec(payWithGc).exec(payWithCc), - exec(payWithCc) + exec(payWithGc).exec(payWithCc), + exec(payWithCc) ) } diff --git a/phoenix-scala/seeder/app/gatling/seeds/simulations/OneshotSeedsSimulation.scala b/phoenix-scala/seeder/app/gatling/seeds/simulations/OneshotSeedsSimulation.scala index 0e0cf8306a..2be1289b03 100644 --- a/phoenix-scala/seeder/app/gatling/seeds/simulations/OneshotSeedsSimulation.scala +++ b/phoenix-scala/seeder/app/gatling/seeds/simulations/OneshotSeedsSimulation.scala @@ -8,10 +8,10 @@ import gatling.seeds.requests.Auth._ class OneshotSeedsSimulation extends Simulation { setUp( - scenario("Base data") - .step(loginAsRandomAdmin) - // Add seeds here - .inject(atOnceUsers(1))) + scenario("Base data") + .step(loginAsRandomAdmin) + // Add seeds here + .inject(atOnceUsers(1))) .assertions(global.failedRequests.percent.lessThan(99)) .protocols(httpConf) } diff --git a/phoenix-scala/seeder/app/seeds/Seeds.scala b/phoenix-scala/seeder/app/seeds/Seeds.scala index 798c57e09e..e6b625a199 100644 --- a/phoenix-scala/seeder/app/seeds/Seeds.scala +++ b/phoenix-scala/seeder/app/seeds/Seeds.scala @@ -68,58 +68,58 @@ object Seeds { .action((_, c) ⇒ c.copy(mode = Seed)) .text("Insert seeds") .children( - opt[Unit]("skipMigrate") - .action((_, c) ⇒ c.copy(migrateDb = false)) - .text("Skip migration step for database."), - opt[Unit]("skipBase") - .action((x, c) ⇒ c.copy(seedBase = false)) - .text("Skip seed base seeds."), - opt[Unit]("seedShippingRules") - .action((_, c) ⇒ c.copy(seedShippingRules = true)) - .text("Create predefined shipping rules"), - opt[Unit]("seedAdmins") - .action((_, c) ⇒ c.copy(seedAdmins = true)) - .text("Create predefined admins"), - opt[Int]("seedRandom") - .action((x, c) ⇒ c.copy(seedRandom = x)) - .text("Create random seeds"), - opt[Int]("customersScaleMultiplier") - .action((x, c) ⇒ c.copy(customersScaleMultiplier = x)) - .text("Customers scale multiplier for random seeds"), - opt[Unit]("seedStage") - .action((x, c) ⇒ c.copy(seedStage = true)) - .text("Create stage seeds"), - opt[Int]("seedDemo").action((x, c) ⇒ c.copy(seedDemo = x)).text("Create demo seeds")) + opt[Unit]("skipMigrate") + .action((_, c) ⇒ c.copy(migrateDb = false)) + .text("Skip migration step for database."), + opt[Unit]("skipBase") + .action((x, c) ⇒ c.copy(seedBase = false)) + .text("Skip seed base seeds."), + opt[Unit]("seedShippingRules") + .action((_, c) ⇒ c.copy(seedShippingRules = true)) + .text("Create predefined shipping rules"), + opt[Unit]("seedAdmins") + .action((_, c) ⇒ c.copy(seedAdmins = true)) + .text("Create predefined admins"), + opt[Int]("seedRandom") + .action((x, c) ⇒ c.copy(seedRandom = x)) + .text("Create random seeds"), + opt[Int]("customersScaleMultiplier") + .action((x, c) ⇒ c.copy(customersScaleMultiplier = x)) + .text("Customers scale multiplier for random seeds"), + opt[Unit]("seedStage") + .action((x, c) ⇒ c.copy(seedStage = true)) + .text("Create stage seeds"), + opt[Int]("seedDemo").action((x, c) ⇒ c.copy(seedDemo = x)).text("Create demo seeds") + ) cmd("createAdmin") .action((_, c) ⇒ c.copy(mode = CreateAdmin)) - .text( - "Create Admin. Password prompts via stdin or can be set via admin_password env or prop") + .text("Create Admin. Password prompts via stdin or can be set via admin_password env or prop") .children( - opt[String]("name") - .required() - .action((x, c) ⇒ c.copy(adminName = x)) - .text("Admin name"), - opt[String]("email") - .required() - .action((x, c) ⇒ c.copy(adminEmail = x)) - .text("Admin email"), - opt[String]("org").required().action((x, c) ⇒ c.copy(adminOrg = x)).text("Admin Org"), - opt[String]("roles") - .required() - .action((x, c) ⇒ c.copy(adminRoles = x)) - .text("Admin Roles") + opt[String]("name") + .required() + .action((x, c) ⇒ c.copy(adminName = x)) + .text("Admin name"), + opt[String]("email") + .required() + .action((x, c) ⇒ c.copy(adminEmail = x)) + .text("Admin email"), + opt[String]("org").required().action((x, c) ⇒ c.copy(adminOrg = x)).text("Admin Org"), + opt[String]("roles") + .required() + .action((x, c) ⇒ c.copy(adminRoles = x)) + .text("Admin Roles") ) cmd("updateObjectSchemas") .action((_, c) ⇒ c.copy(mode = UpdateObjectSchemas)) .text("Update or create Object Schemas") .children( - arg[String]("schema") - .optional() - .unbounded() - .action((x, c) ⇒ c.copy(schemasToUpdate = c.schemasToUpdate :+ x)) - .text("Schemas to update, if ommited update all schemas") + arg[String]("schema") + .optional() + .unbounded() + .action((x, c) ⇒ c.copy(schemasToUpdate = c.schemasToUpdate :+ x)) + .text("Schemas to update, if ommited update all schemas") ) } @@ -135,11 +135,8 @@ object Seeds { val config: Config = FoxConfig.unsafe implicit val db: DatabaseDef = Database.forConfig("db", config) implicit val ac: AC = EnrichedActivityContext( - ctx = ActivityContext(userId = 1, - userType = "user", - scope = LTree("1"), - transactionId = "seeds"), - producer = new MockProducer[GenericData.Record, GenericData.Record](true, null, null) + ctx = ActivityContext(userId = 1, userType = "user", scope = LTree("1"), transactionId = "seeds"), + producer = new MockProducer[GenericData.Record, GenericData.Record](true, null, null) ) cfg.mode match { @@ -195,10 +192,9 @@ object Seeds { step("Create stage admins seeds", r) } - private[this] def step[T](name: String, f: DbResultT[T], waitFor: FiniteDuration = 4.minute)( - implicit db: DB, - ec: EC, - ac: AC): T = { + private[this] def step[T](name: String, + f: DbResultT[T], + waitFor: FiniteDuration = 4.minute)(implicit db: DB, ec: EC, ac: AC): T = { Console.out.println(name) // TODO: Should we really be discarding all warnings here (and git-grep 'runEmptyA')? Rethink! @michalrus val result: Either[Failures, T] = Await.result(f.runTxn().runEmptyA.value, waitFor) @@ -208,8 +204,7 @@ object Seeds { val MERCHANT = "merchant" val MERCHANT_EMAIL = "hackerman@yahoo.com" - def getMerchant(implicit db: DB, - ac: AC): DbResultT[(Organization, User, Account, Account.ClaimSet)] = + def getMerchant(implicit db: DB, ac: AC): DbResultT[(Organization, User, Account, Account.ClaimSet)] = for { organization ← * <~ Organizations .findByName(MERCHANT) @@ -280,8 +275,7 @@ object Seeds { r ← * <~ getMerchant (organization, merchant, account, claims) = r _ ← * <~ { - implicit val au = AuthData[User](token = - UserToken.fromUserAccount(merchant, account, claims), + implicit val au = AuthData[User](token = UserToken.fromUserAccount(merchant, account, claims), model = merchant, account = account) @@ -289,7 +283,7 @@ object Seeds { admin ← * <~ Users.take(1).mustFindOneOr(NotFoundFailure404(User, "first")) context ← * <~ ObjectContexts.mustFindById404(SimpleContext.id) ruContext ← * <~ ObjectContexts.create( - SimpleContext.create(name = SimpleContext.ru, lang = "ru")) + SimpleContext.create(name = SimpleContext.ru, lang = "ru")) customers ← * <~ Factories.createCustomers(organization.scopeId) _ ← * <~ Factories.createAddresses(customers) _ ← * <~ Factories.createCreditCards(customers) @@ -325,12 +319,14 @@ object Seeds { source } - private def validateResults[R](seed: String, result: Either[Failures, R])(implicit db: DB): R = { - result.fold(failures ⇒ { - Console.err.println(s"'$seed' has failed!") - failures.flatten.foreach(Console.err.println) - db.close() - sys.exit(1) - }, v ⇒ { Console.err.println(s"Successfully completed '$seed'!"); v }) - } + private def validateResults[R](seed: String, result: Either[Failures, R])(implicit db: DB): R = + result.fold( + failures ⇒ { + Console.err.println(s"'$seed' has failed!") + failures.flatten.foreach(Console.err.println) + db.close() + sys.exit(1) + }, + v ⇒ { Console.err.println(s"Successfully completed '$seed'!"); v } + ) } From 4abecf94f102e8189edb4063460b9d70b50edf21 Mon Sep 17 00:00:00 2001 From: Anna Zubenko Date: Wed, 7 Jun 2017 18:52:13 +0300 Subject: [PATCH 82/93] Cleanup after merge --- .../app/phoenix/services/AmazonOrderManager.scala | 9 --------- 1 file changed, 9 deletions(-) diff --git a/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala b/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala index 043c97dd98..1ddbd27234 100644 --- a/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala +++ b/phoenix-scala/phoenix/app/phoenix/services/AmazonOrderManager.scala @@ -23,15 +23,6 @@ object AmazonOrderManager { .findOrCreate(inner) } yield AmazonOrderResponse.build(amazonOrder) - private def createInner( - payload: CreateAmazonOrderPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrder] = - for { - user ← * <~ Users - .findByEmail(payload.customerEmail) - .mustFindOneOr(NotFoundFailure404(User, "email", payload.customerEmail)) - amazonOrder ← * <~ AmazonOrders.create(AmazonOrder.build(payload, user.accountId)) - } yield amazonOrder - def updateAmazonOrder( amazonOrderId: String, payload: UpdateAmazonOrderPayload)(implicit ec: EC, db: DB, au: AU): DbResultT[AmazonOrderResponse] = From 97537e393febb0bfd29606461c198101655f7a65 Mon Sep 17 00:00:00 2001 From: Roman Sotnikov Date: Tue, 6 Jun 2017 16:48:21 +0700 Subject: [PATCH 83/93] Fix description --- .../content/reference/resources/admin_amazon_orders.apib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer-portal/content/reference/resources/admin_amazon_orders.apib b/developer-portal/content/reference/resources/admin_amazon_orders.apib index ac6a284f96..54e9620934 100644 --- a/developer-portal/content/reference/resources/admin_amazon_orders.apib +++ b/developer-portal/content/reference/resources/admin_amazon_orders.apib @@ -3,7 +3,7 @@ All orders from Amazon sales channel duplicated in Fox platform. Orders are fetched by platform automatically but also can be added via API. -`CREATE` call is immutable — if order with such `amazonOrderId` has +`CREATE` call is idempotent — if order with such `amazonOrderId` has been created already — previously created order will return. ### Create [POST /v1/amazon-orders] From c2d45863172a4912b60e7d4dd2d30cdac6af01cb Mon Sep 17 00:00:00 2001 From: Anna Zubenko Date: Tue, 13 Jun 2017 13:39:36 +0300 Subject: [PATCH 84/93] Fix customer email test --- .../test/integration/CustomerIntegrationTest.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala index 6c8aa954f9..8f07f0c722 100644 --- a/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala @@ -3,6 +3,7 @@ import java.time.temporal.ChronoUnit import cats.implicits._ import com.stripe.exception.CardException +import core.db._ import core.failures.NotFoundFailure404 import org.mockito.ArgumentMatchers.any import org.mockito.Mockito.when @@ -33,13 +34,14 @@ import slick.jdbc.PostgresProfile.api._ import testutils._ import testutils.apis.{PhoenixAdminApi, PhoenixPublicApi} import testutils.fixtures.BakedFixtures -import core.db._ +import testutils.fixtures.api.ApiFixtureHelpers class CustomerIntegrationTest extends IntegrationTestBase with PhoenixAdminApi with PhoenixPublicApi with DefaultJwtAdminAuth + with ApiFixtureHelpers with TestActivityContext.AdminAC with BakedFixtures { @@ -53,7 +55,8 @@ class CustomerIntegrationTest created.accountId must === (root.id) } - "fails if email is already in use" in new Customer_Seed { + "fails if email is already in use" in { + val customer = api_newCustomer() customersApi .create(CreateCustomerPayload(email = customer.email.value, name = "test".some)) .mustFailWith400(CustomerEmailNotUnique) @@ -83,7 +86,8 @@ class CustomerIntegrationTest } "GET /v1/customers/email/:email" - { - "fetches customer info by email" in new Customer_Seed { + "fetches customer info by email" in { + val customer = api_newCustomer() customersApi.getByEmail(customer.email.value).as[Root].id must === (customer.id) } From f57bf58b35a0fd1cce8c3217c452a404dda72eaa Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Tue, 13 Jun 2017 13:55:10 +0300 Subject: [PATCH 85/93] fix hyperion marathon group config --- .../templates/core-integrations/hyperion.json.j2 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tabernacle/ansible/roles/dev/marathon_groups/templates/core-integrations/hyperion.json.j2 b/tabernacle/ansible/roles/dev/marathon_groups/templates/core-integrations/hyperion.json.j2 index f420dfb990..b51bd817c4 100644 --- a/tabernacle/ansible/roles/dev/marathon_groups/templates/core-integrations/hyperion.json.j2 +++ b/tabernacle/ansible/roles/dev/marathon_groups/templates/core-integrations/hyperion.json.j2 @@ -25,10 +25,11 @@ "PHOENIX_USER": "{{phoenix_api_user}}", "PHOENIX_PASSWORD": "{{phoenix_api_password}}", "PHOENIX_ORG": "{{phoenix_api_user_org}}", - "PHOENIX_URL": "https://{{storefront_server_name}}", + "PHOENIX_URL": "http://{{phoenix_server}}", "PUBLIC_KEY": "{{public_keys_dest_dir}}/public_key.pem", "PUSH_CHECK_INTERVAL": "{{hyperion_push_check_interval}}", - "CREATE_ASHES_PLUGIN": "{{hyperion_create_plugin_in_ashes_on_start}}" + "ORDERS_FETCH_INTERVAL" : "{{hyperion_orders_fetch_interval}}", + "CREATE_ASHES_PLUGIN": "{{hyperion_create_plugin_in_ashes_on_start | bool | lower}}" }, "container": { "type": "DOCKER", From c6d9263684b820b500c960f938b61a60101c9a46 Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Wed, 21 Jun 2017 16:09:20 +0300 Subject: [PATCH 86/93] update sql versions --- ...zon_orders.sql => V5.20170621160816__create_amazon_orders.sql} | 0 ....20170621160817__alter_assignment_domain_add_amazon_order.sql} | 0 ...160818__add_orders_search_view_id_seq_and_change_triggers.sql} | 0 ...able.sql => V5.20170621160819__change_amazon_orders_table.sql} | 0 ...V5.20170621160820__drop_order_id_from_returns_search_view.sql} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename phoenix-scala/sql/{V4.221__create_amazon_orders.sql => V5.20170621160816__create_amazon_orders.sql} (100%) rename phoenix-scala/sql/{V4.222__alter_assignment_domain_add_amazon_order.sql => V5.20170621160817__alter_assignment_domain_add_amazon_order.sql} (100%) rename phoenix-scala/sql/{V4.223__add_orders_search_view_id_seq_and_change_triggers.sql => V5.20170621160818__add_orders_search_view_id_seq_and_change_triggers.sql} (100%) rename phoenix-scala/sql/{V4.224__change_amazon_orders_table.sql => V5.20170621160819__change_amazon_orders_table.sql} (100%) rename phoenix-scala/sql/{V4.225__drop_order_id_from_returns_search_view.sql => V5.20170621160820__drop_order_id_from_returns_search_view.sql} (100%) diff --git a/phoenix-scala/sql/V4.221__create_amazon_orders.sql b/phoenix-scala/sql/V5.20170621160816__create_amazon_orders.sql similarity index 100% rename from phoenix-scala/sql/V4.221__create_amazon_orders.sql rename to phoenix-scala/sql/V5.20170621160816__create_amazon_orders.sql diff --git a/phoenix-scala/sql/V4.222__alter_assignment_domain_add_amazon_order.sql b/phoenix-scala/sql/V5.20170621160817__alter_assignment_domain_add_amazon_order.sql similarity index 100% rename from phoenix-scala/sql/V4.222__alter_assignment_domain_add_amazon_order.sql rename to phoenix-scala/sql/V5.20170621160817__alter_assignment_domain_add_amazon_order.sql diff --git a/phoenix-scala/sql/V4.223__add_orders_search_view_id_seq_and_change_triggers.sql b/phoenix-scala/sql/V5.20170621160818__add_orders_search_view_id_seq_and_change_triggers.sql similarity index 100% rename from phoenix-scala/sql/V4.223__add_orders_search_view_id_seq_and_change_triggers.sql rename to phoenix-scala/sql/V5.20170621160818__add_orders_search_view_id_seq_and_change_triggers.sql diff --git a/phoenix-scala/sql/V4.224__change_amazon_orders_table.sql b/phoenix-scala/sql/V5.20170621160819__change_amazon_orders_table.sql similarity index 100% rename from phoenix-scala/sql/V4.224__change_amazon_orders_table.sql rename to phoenix-scala/sql/V5.20170621160819__change_amazon_orders_table.sql diff --git a/phoenix-scala/sql/V4.225__drop_order_id_from_returns_search_view.sql b/phoenix-scala/sql/V5.20170621160820__drop_order_id_from_returns_search_view.sql similarity index 100% rename from phoenix-scala/sql/V4.225__drop_order_id_from_returns_search_view.sql rename to phoenix-scala/sql/V5.20170621160820__drop_order_id_from_returns_search_view.sql From 038cee5e7454109deca24d9a9e3f74814764101a Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Wed, 21 Jun 2017 17:43:20 +0300 Subject: [PATCH 87/93] fix tests --- .../phoenix/test/integration/CustomerIntegrationTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala b/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala index f6495bd1fb..40ea2e0fe9 100644 --- a/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala +++ b/phoenix-scala/phoenix/test/integration/CustomerIntegrationTest.scala @@ -88,7 +88,7 @@ class CustomerIntegrationTest "GET /v1/customers/email/:email" - { "fetches customer info by email" in { val customer = api_newCustomer() - customersApi.getByEmail(customer.email.value).as[Root].id must === (customer.id) + customersApi.getByEmail(customer.email.value).as[CustomerResponse].id must === (customer.id) } "fails if customer not found" in { From 323a263d295115b106ba581b6f79da9e6e7f876c Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Wed, 21 Jun 2017 18:55:40 +0300 Subject: [PATCH 88/93] fix type in ashes --- ashes/src/components/orders/order.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ashes/src/components/orders/order.jsx b/ashes/src/components/orders/order.jsx index 95d1cd9909..1909675a15 100644 --- a/ashes/src/components/orders/order.jsx +++ b/ashes/src/components/orders/order.jsx @@ -88,7 +88,7 @@ export default class Order extends React.Component { if (this.props.route.amazon) { this.props.fetchAmazonOrder(orderNum); } else { - this.props.fetchOrderå(orderNum); + this.props.fetchOrder(orderNum); } } From 7e666b9bd87d02a458ca245a3a837ba1c1dd9de0 Mon Sep 17 00:00:00 2001 From: Tony Grebnev Date: Wed, 21 Jun 2017 20:29:55 +0300 Subject: [PATCH 89/93] fix phoenix client amazon-orders path --- hyperion/lib/hyperion/phoenix_scala/client.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyperion/lib/hyperion/phoenix_scala/client.ex b/hyperion/lib/hyperion/phoenix_scala/client.ex index b555e95e7c..7adb6c2735 100644 --- a/hyperion/lib/hyperion/phoenix_scala/client.ex +++ b/hyperion/lib/hyperion/phoenix_scala/client.ex @@ -121,7 +121,7 @@ defmodule Hyperion.PhoenixScala.Client do scope: Hyperion.JwtAuth.get_scope(token), customerName: payload["BuyerName"], customerEmail: payload["BuyerEmail"]}) - {st, resp} = post("/v1/amazon_orders", params, make_request_headers(token)) + {st, resp} = post("/v1/amazon-orders", params, make_request_headers(token)) case resp.status_code do code when code in [200, 201] -> parse_response({st, resp}, token) _ -> From 1ea9a98ac4ce7601fd7bd106306ce68b9f0afaa1 Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Tue, 27 Jun 2017 21:49:27 +0300 Subject: [PATCH 90/93] fix amazon entities rendering --- .../customer-card/customer-card.jsx | 25 ++++++----- .../src/components/customers/title-block.css | 25 +++++------ .../src/components/customers/title-block.jsx | 12 +++--- .../components/orders/order-line-items.jsx | 22 ++++++++-- ashes/src/components/orders/payments.jsx | 7 +--- .../components/payment-row/payment-row.jsx | 29 ++++++++----- .../src/components/payment/payment-method.jsx | 28 +++++++++---- .../sku-line-items/sku-line-items.jsx | 34 +++++++-------- ashes/src/modules/orders/details.js | 42 ++++++++----------- ashes/src/routes.js | 4 +- 10 files changed, 125 insertions(+), 103 deletions(-) diff --git a/ashes/src/components/customer-card/customer-card.jsx b/ashes/src/components/customer-card/customer-card.jsx index a6c64cc820..593ad47496 100644 --- a/ashes/src/components/customer-card/customer-card.jsx +++ b/ashes/src/components/customer-card/customer-card.jsx @@ -1,6 +1,7 @@ /* @flow */ // libs +import { isEmpty } from 'lodash'; import React, { Component } from 'react'; //components @@ -29,9 +30,9 @@ export default class CustomerInfo extends Component { return
Guest
; } else if (customer.groups) { return ( -
- {customer.groups.map((customer) => { - return
{customer}
; +
+ {customer.groups.map(group => { + return
{group.name}
; })}
); @@ -76,24 +77,22 @@ export default class CustomerInfo extends Component {
  • {customer.id}
    -
  • - } + } {customer.phoneNumber &&
  • {customer.phoneNumber}
    -
  • - } + } {customer.location &&
  • {customer.location}
    -
  • - } -
  • - - {this.customerGroups} -
  • + } + {!isEmpty(customer.groups) && +
  • + + {this.customerGroups} +
  • }
    diff --git a/ashes/src/components/customers/title-block.css b/ashes/src/components/customers/title-block.css index d502dc8ed1..111fa331e7 100644 --- a/ashes/src/components/customers/title-block.css +++ b/ashes/src/components/customers/title-block.css @@ -6,7 +6,7 @@ } :root { - --avatar-margin-top: calc(- var(--circle-size) / 3); /* stylelint-disable-line */ + --avatar-margin-top: calc(-var(--circle-size) / 3); /* stylelint-disable-line */ } .block { @@ -15,13 +15,11 @@ } .header { - background: #263349; - height: 60px; text-align: center; } .head { - height: 91px; + height: 60px; color: var(--color-light-text); background-color: var(--bg-nav-main); border-radius: 3px 3px 0 0; @@ -104,23 +102,21 @@ display: inline-block; width: 50%; - &:only-child { - width: 100%; - } - & > li { - height: 40px; display: flex; align-items: center; + padding: 7px 0 8px; & > i { + width: 40px; + font-style: normal; + font-size: 22px; line-height: 24px; text-align: center; color: var(--color-additional-text); } &.fc-customer-info-days > i { - margin-right: 8px; font-size: 15px; font-weight: 700; line-height: 20px; @@ -134,9 +130,15 @@ word-wrap: break-word; } +.groups { + display: flex; + padding: 10px; +} + .group { padding: 5px 10px; - margin: 0 5px 5px 8px; + margin-right: 5px; + margin-bottom: 5px; display: inline-block; vertical-align: top; font-size: 14px; @@ -150,5 +152,4 @@ .guest { color: var(--color-additional-text); padding-top: 5px; - margin-left: 8px; } diff --git a/ashes/src/components/customers/title-block.jsx b/ashes/src/components/customers/title-block.jsx index 84c9a3e3d1..a04cbb403b 100644 --- a/ashes/src/components/customers/title-block.jsx +++ b/ashes/src/components/customers/title-block.jsx @@ -14,9 +14,8 @@ import Currency from '../common/currency'; import { DateTime } from 'components/common/datetime'; export default class Customer extends React.Component { - static propTypes = { - customer: PropTypes.object.isRequired + customer: PropTypes.object.isRequired, }; get customerName() { @@ -53,6 +52,7 @@ export default class Customer extends React.Component { return (
    +
    @@ -72,21 +72,21 @@ export default class Customer extends React.Component {
    • - { customer.id } + {customer.id}
    • - { customer.phoneNumber } + {customer.phoneNumber}
    • - { customer.location } + {customer.location}
    • - { joinedAt } + {joinedAt}  Date joined
    • diff --git a/ashes/src/components/orders/order-line-items.jsx b/ashes/src/components/orders/order-line-items.jsx index 0790c0d33e..88eb27fb88 100644 --- a/ashes/src/components/orders/order-line-items.jsx +++ b/ashes/src/components/orders/order-line-items.jsx @@ -1,22 +1,38 @@ /* @flow */ +import { findIndex } from 'lodash'; import React from 'react'; import ContentBox from 'components/content-box/content-box'; -import SkuLineItems from 'components/sku-line-items/sku-line-items'; +import SkuLineItems, { defaultColumns } from 'components/sku-line-items/sku-line-items'; import OrderParagon from 'paragons/order'; type Props = { - order: OrderParagon; + order: OrderParagon, }; const OrderLineItems = (props: Props) => { const { skus } = props.order.lineItems; + let columns = defaultColumns; + + if (props.order.channel === 'Amazon.com') { + const skuFieldIndex = findIndex(defaultColumns, { field: 'sku' }); + + columns = [ + ...defaultColumns.slice(0, skuFieldIndex), + { + field: 'sku', + text: 'SKU', + }, + ...defaultColumns.slice(skuFieldIndex + 1), + ]; + } + return ( - + ); }; diff --git a/ashes/src/components/orders/payments.jsx b/ashes/src/components/orders/payments.jsx index 59a20a1ca7..6d15d313af 100644 --- a/ashes/src/components/orders/payments.jsx +++ b/ashes/src/components/orders/payments.jsx @@ -21,13 +21,8 @@ export default class Payments extends React.Component { const { order } = this.props.details; const { paymentMethods } = order; - const title = ; - return ( - + ); diff --git a/ashes/src/components/payment-row/payment-row.jsx b/ashes/src/components/payment-row/payment-row.jsx index 12827d50b1..0f46815c1f 100644 --- a/ashes/src/components/payment-row/payment-row.jsx +++ b/ashes/src/components/payment-row/payment-row.jsx @@ -22,7 +22,7 @@ import Icon from 'components/core/icon'; import styles from './payment-row.css'; // redux -import {deleteCreditCardPayment, deleteGiftCardPayment, deleteStoreCreditPayment} from 'modules/carts/details'; +import { deleteCreditCardPayment, deleteGiftCardPayment, deleteStoreCreditPayment } from 'modules/carts/details'; import type { PaymentMethod } from 'paragons/order'; @@ -41,6 +41,8 @@ type State = { showDetails: boolean, }; +const availablePaymentMethods = ['creditCard', 'giftCard', 'storeCredit']; + class PaymentRow extends Component { props: Props; state: State = { @@ -82,7 +84,7 @@ class PaymentRow extends Component { }; let DetailsElement = null; - switch(paymentMethod.type) { + switch (paymentMethod.type) { case 'creditCard': DetailsElement = CreditCardDetails; break; @@ -94,8 +96,10 @@ class PaymentRow extends Component { break; } - if (DetailsElement == null) { - throw `Unexpected payment method ${paymentMethod.type}`; + if (DetailsElement === null) { + console.warn(`Unexpected payment method ${paymentMethod.type}`); + + return null; } return ( @@ -110,9 +114,7 @@ class PaymentRow extends Component { get editActions(): ?Element<*> { if (this.props.editMode) { - const editButton = !this.state.isEditing - ? - : null; + const editButton = !this.state.isEditing ? : null; return ( @@ -128,10 +130,14 @@ class PaymentRow extends Component { const dir = this.state.showDetails ? 'up' : 'down'; const iconClass = `chevron-${dir}`; + const toggler = + availablePaymentMethods.indexOf(paymentMethod.type) > -1 && + ; + return ( - + {toggler} @@ -165,7 +171,7 @@ class PaymentRow extends Component { @autobind toggleDetails() { this.setState({ - showDetails: !this.state.showDetails + showDetails: !this.state.showDetails, }); } @@ -180,8 +186,9 @@ class PaymentRow extends Component { } const deleteActions = { - deleteCreditCardPayment, deleteGiftCardPayment, deleteStoreCreditPayment + deleteCreditCardPayment, + deleteGiftCardPayment, + deleteStoreCreditPayment, }; export default connect(void 0, deleteActions)(PaymentRow); - diff --git a/ashes/src/components/payment/payment-method.jsx b/ashes/src/components/payment/payment-method.jsx index cfe02f840a..aa14ef0927 100644 --- a/ashes/src/components/payment/payment-method.jsx +++ b/ashes/src/components/payment/payment-method.jsx @@ -1,4 +1,3 @@ - /* @flow */ import _ from 'lodash'; @@ -13,17 +12,17 @@ import type { PaymentMethod as TPaymentMethod } from 'paragons/order'; import styles from './payment-method.css'; type Props = { - paymentMethod: TPaymentMethod; - type?: string; - className?: string; + paymentMethod: TPaymentMethod, + type?: string, + className?: string, }; function getIconType(type, paymentMethod) { - switch (type) { + switch (type && paymentMethod.brand) { case 'creditCard': return paymentMethod.brand.toLowerCase().replace(/ /g, ''); default: - return _.snakeCase(type); + return null; } } @@ -51,10 +50,23 @@ const PaymentMethod = (props: Props) => { const { paymentMethod } = props; const type = _.get(props, 'paymentMethod.type', 'creditCard'); - const icon = static_url(`images/payments/payment_${getIconType(type, paymentMethod)}.svg`); + const iconType = getIconType(type, paymentMethod); + + let icon; + + if (iconType) { + icon = ( + + ); + } + return (
      - + {icon}
      {getTitle(type, paymentMethod)}
      {getSubtitle(type, paymentMethod)}
      diff --git a/ashes/src/components/sku-line-items/sku-line-items.jsx b/ashes/src/components/sku-line-items/sku-line-items.jsx index dd94beaded..fe274b9c42 100644 --- a/ashes/src/components/sku-line-items/sku-line-items.jsx +++ b/ashes/src/components/sku-line-items/sku-line-items.jsx @@ -16,7 +16,7 @@ export const defaultColumns = [ { field: 'sku', text: 'SKU', - render: (code: string) => {code} + render: (code: string) => {code}, }, { field: 'price', text: 'Price', type: 'currency' }, { field: 'quantity', text: 'Qty' }, @@ -24,11 +24,11 @@ export const defaultColumns = [ ]; const attributesColumns = { - 'giftCard': [ + giftCard: [ { field: 'code', text: 'Gift Card Number', - render: code => !_.isEmpty(code) ? {code} : 'N/A' + render: code => (!_.isEmpty(code) ? {code} : 'N/A'), }, { field: 'recipientName', text: 'Recipient Name' }, { field: 'recipientEmail', text: 'Recipient Email' }, @@ -42,6 +42,7 @@ type Props = { items: Array, renderRow?: Function, withAttributes?: boolean, + withLink?: boolean, className?: string, }; @@ -49,14 +50,16 @@ const lineItemAttributes = (item: SkuItem, columns: Columns): Array> const attributes = _.get(item, 'attributes', {}); if (!_.isEmpty(attributes)) { - return Object.keys(attributes).map((name: string) => ( - _.get(attributesColumns, name) ? - : null - )); + return Object.keys(attributes).map( + (name: string) => + _.get(attributesColumns, name) + ? + : null + ); } return []; @@ -71,10 +74,7 @@ const SkuLineItems = (props: Props) => { const attributes = _.get(items[index], 'attributes'); const className = classNames({ '_with-attributes': !_.isEmpty(attributes) }); - return [ - React.cloneElement(row, { className }), - lineItemAttributes(items[index], columns), - ]; + return [React.cloneElement(row, { className }), lineItemAttributes(items[index], columns)]; }); if (items.length > 0) { @@ -84,14 +84,14 @@ const SkuLineItems = (props: Props) => { className={className} columns={columns} emptyMessage="No items yet." - data={{rows: items}} + data={{ rows: items }} renderRow={renderRow} processRows={withAttributes ? processRows : _.identity} /> ); } else { return ( -
      +
      No items yet.
      ); diff --git a/ashes/src/modules/orders/details.js b/ashes/src/modules/orders/details.js index 4f2624dc86..4f68f42f37 100644 --- a/ashes/src/modules/orders/details.js +++ b/ashes/src/modules/orders/details.js @@ -13,31 +13,23 @@ const initialState: State = { order: null, }; -const _getOrder = createAsyncActions( - 'getOrder', - (refNum: string) => Api.get(`/orders/${refNum}`) -); +const _getOrder = createAsyncActions('getOrder', (refNum: string) => Api.get(`/orders/${refNum}`)); -const _getAmazonOrder = createAsyncActions( - 'getAmazonOrder', - (refNum: string) => Api.get(`/hyperion/orders/${refNum}/full`) +const _getAmazonOrder = createAsyncActions('getAmazonOrder', (refNum: string) => + Api.get(`/hyperion/orders/${refNum}/full`) ); -const _updateOrder = createAsyncActions( - 'updateOrder', - (id: number, data: Object) => Api.patch(`/orders/${id}`, data) -); +const _updateOrder = createAsyncActions('updateOrder', (id: number, data: Object) => Api.patch(`/orders/${id}`, data)); -const _updateShipments = createAsyncActions( - 'updateShipments', - (refNum: string) => Api.patch(`/inventory/shipments/for-order/${refNum}`, { state: 'shipped' }) +const _updateShipments = createAsyncActions('updateShipments', (refNum: string) => + Api.patch(`/inventory/shipments/for-order/${refNum}`, { state: 'shipped' }) ); export const fetchOrder = _getOrder.perform; export const fetchAmazonOrder = _getAmazonOrder.perform; export const updateOrder = _updateOrder.perform; export const updateShipments = _updateShipments.perform; -export const clearFetchErrors =_getOrder.clearErrors; +export const clearFetchErrors = _getOrder.clearErrors; function orderSucceeded(state: State, payload: Object): State { const order: OrderParagon = new OrderParagon(payload.result); @@ -48,8 +40,6 @@ function orderSucceeded(state: State, payload: Object): State { function amazonOrderSucceeded(state: State, payload: Object): State { const res = payload.result; - res.customer.id = res.customer.email; - const order: OrderParagon = new OrderParagon(res); return { ...state, order }; @@ -57,15 +47,17 @@ function amazonOrderSucceeded(state: State, payload: Object): State { export function increaseRemorsePeriod(refNum: string) { return (dispatch: Function): Promise<*> => - Api.post(`/orders/${refNum}/increase-remorse-period`) - .then(order => dispatch(_updateOrder.succeeded(order))); + Api.post(`/orders/${refNum}/increase-remorse-period`).then(order => dispatch(_updateOrder.succeeded(order))); } -const reducer = createReducer({ - [_getOrder.succeeded]: orderSucceeded, - [_getAmazonOrder.succeeded]: amazonOrderSucceeded, - [_updateOrder.succeeded]: orderSucceeded, - [_updateShipments.succeeded]: (state) => state, -}, initialState); +const reducer = createReducer( + { + [_getOrder.succeeded]: orderSucceeded, + [_getAmazonOrder.succeeded]: amazonOrderSucceeded, + [_updateOrder.succeeded]: orderSucceeded, + [_updateShipments.succeeded]: state => state, + }, + initialState +); export default reducer; diff --git a/ashes/src/routes.js b/ashes/src/routes.js index 120a7de66e..e73dfa8e09 100644 --- a/ashes/src/routes.js +++ b/ashes/src/routes.js @@ -22,7 +22,7 @@ export default function makeRoutes(jwtToken) { const claims = getClaims(jwtToken); return [ - + {authRoutes(claims)} @@ -36,6 +36,6 @@ export default function makeRoutes(jwtToken) { , - + , ]; } From 80d978052f26f4549c9bfe5134b11cb765416086 Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Wed, 28 Jun 2017 02:09:54 +0300 Subject: [PATCH 91/93] more fixes for order payments --- ashes/src/components/orders/payments.jsx | 1 - .../components/payment-row/payment-row.jsx | 15 ++-- .../src/components/payment/payment-method.jsx | 6 +- .../payments-panel/payments-panel.jsx | 30 +++---- ashes/src/interfaces/paragons/customer.js | 2 +- ashes/src/lib/credit-card-utils.js | 13 ++- hyperion/lib/hyperion/amazon/amazon.ex | 9 +- hyperion/mix.lock | 82 +++++++++---------- 8 files changed, 83 insertions(+), 75 deletions(-) diff --git a/ashes/src/components/orders/payments.jsx b/ashes/src/components/orders/payments.jsx index 6d15d313af..9f165b9c6c 100644 --- a/ashes/src/components/orders/payments.jsx +++ b/ashes/src/components/orders/payments.jsx @@ -3,7 +3,6 @@ import React, { Element } from 'react'; import ContentBox from 'components/content-box/content-box'; -import PanelHeader from 'components/panel-header/panel-header'; import PaymentsPanel from 'components/payments-panel/payments-panel'; import OrderParagon from 'paragons/order'; diff --git a/ashes/src/components/payment-row/payment-row.jsx b/ashes/src/components/payment-row/payment-row.jsx index 0f46815c1f..742b058991 100644 --- a/ashes/src/components/payment-row/payment-row.jsx +++ b/ashes/src/components/payment-row/payment-row.jsx @@ -24,13 +24,15 @@ import styles from './payment-row.css'; // redux import { deleteCreditCardPayment, deleteGiftCardPayment, deleteStoreCreditPayment } from 'modules/carts/details'; -import type { PaymentMethod } from 'paragons/order'; +import type Order from 'paragons/order'; +import type { Cart, PaymentMethod } from 'paragons/order'; type Props = { customerId: number, editMode: boolean, orderReferenceNumber: string, paymentMethod: PaymentMethod, + order: Cart | Order, deleteCreditCardPayment: (refNum: string) => Promise<*>, deleteGiftCardPayment: (refNum: string, code: string) => Promise<*>, deleteStoreCreditPayment: (refNum: string) => Promise<*>, @@ -41,8 +43,6 @@ type State = { showDetails: boolean, }; -const availablePaymentMethods = ['creditCard', 'giftCard', 'storeCredit']; - class PaymentRow extends Component { props: Props; state: State = { @@ -73,6 +73,10 @@ class PaymentRow extends Component { } get details(): ?Element<*> { + if (this.props.order.channel === 'Amazon.com') { + return null; + } + if (this.state.showDetails) { const { customerId, orderReferenceNumber, paymentMethod } = this.props; const detailsProps = { @@ -126,13 +130,12 @@ class PaymentRow extends Component { } get summary(): Element<*> { - const { paymentMethod } = this.props; + const { order, paymentMethod } = this.props; const dir = this.state.showDetails ? 'up' : 'down'; const iconClass = `chevron-${dir}`; const toggler = - availablePaymentMethods.indexOf(paymentMethod.type) > -1 && - ; + order.channel !== 'Amazon.com' && ; return ( diff --git a/ashes/src/components/payment/payment-method.jsx b/ashes/src/components/payment/payment-method.jsx index aa14ef0927..d449279bfc 100644 --- a/ashes/src/components/payment/payment-method.jsx +++ b/ashes/src/components/payment/payment-method.jsx @@ -18,11 +18,11 @@ type Props = { }; function getIconType(type, paymentMethod) { - switch (type && paymentMethod.brand) { + switch (type) { case 'creditCard': - return paymentMethod.brand.toLowerCase().replace(/ /g, ''); + return paymentMethod.brand ? paymentMethod.brand.toLowerCase().replace(/ /g, '') : null; default: - return null; + return _.snakeCase(type); } } diff --git a/ashes/src/components/payments-panel/payments-panel.jsx b/ashes/src/components/payments-panel/payments-panel.jsx index 22ebde20bc..542015c11a 100644 --- a/ashes/src/components/payments-panel/payments-panel.jsx +++ b/ashes/src/components/payments-panel/payments-panel.jsx @@ -14,7 +14,7 @@ import type { Cart, PaymentMethod } from 'paragons/order'; type Props = { isAdding: boolean, isEditing: boolean, - order: Cart|OrderParagon, + order: Cart | OrderParagon, paymentMethods: Array, cancelAdding?: () => void, }; @@ -25,14 +25,14 @@ type DefaultProps = { }; type State = { - showDetails: { [key:number|string]: boolean }, + showDetails: { [key: number | string]: boolean }, }; const viewColumns = [ - {field: 'name', text: 'Method'}, - {field: 'amount', text: 'Amount', type: 'currency'}, - {field: 'status', text: 'Status'}, - {field: 'createdAt', text: 'Date/Time', type: 'datetime'}, + { field: 'name', text: 'Method' }, + { field: 'amount', text: 'Amount', type: 'currency' }, + { field: 'status', text: 'Status' }, + { field: 'createdAt', text: 'Date/Time', type: 'datetime' }, ]; export default class PaymentsPanel extends Component { @@ -50,11 +50,7 @@ export default class PaymentsPanel extends Component { return ( - + ); } @@ -62,10 +58,7 @@ export default class PaymentsPanel extends Component { @autobind processRows(rows: Array): Array { if (this.props.isAdding) { - return [ - this.newPayment, - ...rows, - ]; + return [this.newPayment, ...rows]; } return rows; @@ -85,12 +78,13 @@ export default class PaymentsPanel extends Component { editMode={this.props.isEditing} orderReferenceNumber={referenceNumber} paymentMethod={row} + order={order} /> ); } @autobind - toggleDetails(id: number|string) { + toggleDetails(id: number | string) { this.setState({ showDetails: { [id]: !this.state.showDetails[id], @@ -98,7 +92,7 @@ export default class PaymentsPanel extends Component { }); } - get viewContent(){ + get viewContent() { const { isEditing, paymentMethods } = this.props; const editColumns = isEditing ? [{ field: 'edit' }] : []; @@ -117,7 +111,7 @@ export default class PaymentsPanel extends Component { wrapToTbody={false} renderRow={this.renderRow} processRows={this.processRows} - data={{rows: paymentMethods}} + data={{ rows: paymentMethods }} emptyMessage="No payment method applied" /> ); diff --git a/ashes/src/interfaces/paragons/customer.js b/ashes/src/interfaces/paragons/customer.js index 4fa8e4c5da..efc571b22b 100644 --- a/ashes/src/interfaces/paragons/customer.js +++ b/ashes/src/interfaces/paragons/customer.js @@ -5,7 +5,7 @@ type Customer = { phoneNumber?: string, isGuest?: boolean, - groups?: Array, + groups?: Array, avatarUrl?: string, rank?: number, location?: string, diff --git a/ashes/src/lib/credit-card-utils.js b/ashes/src/lib/credit-card-utils.js index 314698d613..37628baac3 100644 --- a/ashes/src/lib/credit-card-utils.js +++ b/ashes/src/lib/credit-card-utils.js @@ -23,13 +23,18 @@ export function expirationYears() { return _.range(20).map(n => [current + n, current + n]); } -export function formatExpiration(card) { - return `${card.expMonth}/${card.expYear}`; -} +export function formatExpiration({ expMonth, expYear }) { + if (!expMonth || !expYear) { + return 'N/A'; + } + return `${expMonth}/${expYear}`; +} export function formatNumber(card) { - return `xxxx xxxx xxxx ${card.lastFour}`; + const lastFour = card.lastFour || 'xxxx'; + + return `xxxx xxxx xxxx ${lastFour}`; } export function getBillingAddress(getState, customerId, addressId) { diff --git a/hyperion/lib/hyperion/amazon/amazon.ex b/hyperion/lib/hyperion/amazon/amazon.ex index 87e2b241ca..b841b42c4a 100644 --- a/hyperion/lib/hyperion/amazon/amazon.ex +++ b/hyperion/lib/hyperion/amazon/amazon.ex @@ -154,7 +154,7 @@ defmodule Hyperion.Amazon do currentBalance: 0, availableBalance: 0, createdAt: order["PurchaseDate"], - type: order["PaymentMethodDetails"]["PaymentMethodDetail"] + type: lower_first(order["PaymentMethodDetails"]["PaymentMethodDetail"]) }], orderState: order["OrderStatus"], shippingState: "---", @@ -418,4 +418,11 @@ defmodule Hyperion.Amazon do |> String.replace(~r/\s+/, "") |> String.to_atom end + + defp lower_first(str) do + str + |> String.first + |> String.downcase + |> Kernel.<>(String.slice(str, 1, String.length(str))) + end end diff --git a/hyperion/mix.lock b/hyperion/mix.lock index 6625b9fbaa..4a8306b832 100644 --- a/hyperion/mix.lock +++ b/hyperion/mix.lock @@ -1,43 +1,43 @@ -%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []}, - "combine": {:hex, :combine, "0.9.6", "8d1034a127d4cbf6924c8a5010d3534d958085575fa4d9b878f200d79ac78335", [:mix], []}, - "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []}, - "cors_plug": {:hex, :cors_plug, "1.2.1", "bbe1381a52e4a16e609cf3c4cbfde6884726a58b9a1a205db104dbdfc542f447", [:mix], [{:plug, "> 0.8.0", [hex: :plug, optional: false]}]}, - "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, optional: false]}]}, - "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []}, - "csv": {:hex, :csv, "1.4.4", "992f2e1418849a326fd1d9287801fa2d86091db4f9611f60781da6d236f64cd4", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, optional: false]}]}, - "db_connection": {:hex, :db_connection, "1.1.1", "f9d246e8f65b9490945cf7360875eee18fcec9a0115207603215eb1fd94c39ef", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]}, - "decimal": {:hex, :decimal, "1.3.1", "157b3cedb2bfcb5359372a7766dd7a41091ad34578296e951f58a946fcab49c6", [:mix], []}, - "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]}, +%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], [], "hexpm"}, + "combine": {:hex, :combine, "0.9.6", "8d1034a127d4cbf6924c8a5010d3534d958085575fa4d9b878f200d79ac78335", [:mix], [], "hexpm"}, + "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, + "cors_plug": {:hex, :cors_plug, "1.2.1", "bbe1381a52e4a16e609cf3c4cbfde6884726a58b9a1a205db104dbdfc542f447", [:mix], [{:plug, "> 0.8.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, + "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"}, + "csv": {:hex, :csv, "1.4.4", "992f2e1418849a326fd1d9287801fa2d86091db4f9611f60781da6d236f64cd4", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"}, + "db_connection": {:hex, :db_connection, "1.1.1", "f9d246e8f65b9490945cf7360875eee18fcec9a0115207603215eb1fd94c39ef", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, + "decimal": {:hex, :decimal, "1.3.1", "157b3cedb2bfcb5359372a7766dd7a41091ad34578296e951f58a946fcab49c6", [:mix], [], "hexpm"}, + "ecto": {:hex, :ecto, "2.1.4", "d1ba932813ec0e0d9db481ef2c17777f1cefb11fc90fa7c142ff354972dfba7e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, "elixir_xml_to_map": {:git, "https://github.com/retgoat/elixir-xml-to-map.git", "c5171c8173ec72fb35d306eb3b8fb6e03741a4e2", [tag: "0.1.2"]}, - "envy": {:hex, :envy, "1.0.0", "d8385715b908f3972f85cbffa0ffbd36fec017601258bcb6be9003c11ece3e75", [:mix], []}, - "erlsom": {:hex, :erlsom, "1.4.1", "53dbacf35adfea6f0714fd0e4a7b0720d495e88c5e24e12c5dc88c7b62bd3e49", [:rebar3], []}, - "espec": {:hex, :espec, "1.3.2", "20c96d580df671860bd8e7de1523be9ead34bbdca4912689a54f295add56d683", [:mix], [{:meck, "0.8.4", [hex: :meck, optional: false]}]}, - "ex_aws": {:hex, :ex_aws, "1.1.1", "58c46d9a0b395d7cbb065424c109feb6a7385907c12a91d3032a1e8baf3d6220", [:mix], [{:configparser_ex, "~> 0.2.1", [hex: :configparser_ex, optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1", [hex: :hackney, optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, optional: true]}, {:xml_builder, "~> 0.0.6", [hex: :xml_builder, optional: true]}]}, - "ex_machina": {:hex, :ex_machina, "2.0.0", "ec284c6f57233729cea9319e083f66e613e82549f78eccdb2059aeba5d0df9f3", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, optional: true]}]}, - "exfswatch": {:hex, :exfswatch, "0.2.1", "3f34190e2750ae6d924ce53729bb40e050dd8a08fee683847e6ddfa03ea5429f", [:mix], [{:fs, "~> 0.9", [hex: :fs, optional: false]}]}, - "exsync": {:hex, :exsync, "0.1.3", "84c66a4f60505d1baeb8a79cbf713ae98276f23b4bc7d676c6cb2d663fced5f3", [:mix], [{:exfswatch, "~> 0.2.1", [hex: :exfswatch, optional: false]}]}, - "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []}, - "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], []}, - "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, - "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.0.1", "2572e7122c78ab7e57b613e7c7f5e42bf9b3c25e430e32f23f1413d86db8a0af", [:mix], [{:mochiweb, "~> 2.12.2", [hex: :mochiweb, optional: false]}]}, - "httpoison": {:hex, :httpoison, "0.11.1", "d06c571274c0e77b6cc50e548db3fd7779f611fbed6681fd60a331f66c143a0b", [:mix], [{:hackney, "~> 1.7.0", [hex: :hackney, optional: false]}]}, - "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []}, - "inflex": {:hex, :inflex, "1.7.0", "4466a34b7d8e871d8164619ba0f3b8410ec782e900f0ae1d3d27a5875a29532e", [:mix], []}, - "json_web_token": {:hex, :json_web_token, "0.2.8", "c79d4c36cfd6f205be7099713e67d6057bde64ee9c64363f9001e3de86de703c", [:mix], [{:poison, "~> 3.1", [hex: :poison, optional: false]}]}, - "maru": {:hex, :maru, "0.11.3", "0bf2f26955430c4878dab91fe44aeb8b3aaed338b4f6ffd0729ea119284c374d", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: false]}, {:plug, "~> 1.0", [hex: :plug, optional: false]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}]}, - "meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], []}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, - "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []}, - "mochiweb": {:hex, :mochiweb, "2.12.2", "80804ad342afa3d7f3524040d4eed66ce74b17a555de454ac85b07c479928e46", [:make, :rebar], []}, + "envy": {:hex, :envy, "1.0.0", "d8385715b908f3972f85cbffa0ffbd36fec017601258bcb6be9003c11ece3e75", [:mix], [], "hexpm"}, + "erlsom": {:hex, :erlsom, "1.4.1", "53dbacf35adfea6f0714fd0e4a7b0720d495e88c5e24e12c5dc88c7b62bd3e49", [:rebar3], [], "hexpm"}, + "espec": {:hex, :espec, "1.3.2", "20c96d580df671860bd8e7de1523be9ead34bbdca4912689a54f295add56d683", [:mix], [{:meck, "0.8.4", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"}, + "ex_aws": {:hex, :ex_aws, "1.1.1", "58c46d9a0b395d7cbb065424c109feb6a7385907c12a91d3032a1e8baf3d6220", [:mix], [{:configparser_ex, "~> 0.2.1", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.0.6", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"}, + "ex_machina": {:hex, :ex_machina, "2.0.0", "ec284c6f57233729cea9319e083f66e613e82549f78eccdb2059aeba5d0df9f3", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, + "exfswatch": {:hex, :exfswatch, "0.2.1", "3f34190e2750ae6d924ce53729bb40e050dd8a08fee683847e6ddfa03ea5429f", [:mix], [{:fs, "~> 0.9", [hex: :fs, repo: "hexpm", optional: false]}], "hexpm"}, + "exsync": {:hex, :exsync, "0.1.3", "84c66a4f60505d1baeb8a79cbf713ae98276f23b4bc7d676c6cb2d663fced5f3", [:mix], [{:exfswatch, "~> 0.2.1", [hex: :exfswatch, repo: "hexpm", optional: false]}], "hexpm"}, + "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], [], "hexpm"}, + "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "4.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.0.1", "2572e7122c78ab7e57b613e7c7f5e42bf9b3c25e430e32f23f1413d86db8a0af", [:mix], [{:mochiweb, "~> 2.12.2", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, + "httpoison": {:hex, :httpoison, "0.11.1", "d06c571274c0e77b6cc50e548db3fd7779f611fbed6681fd60a331f66c143a0b", [:mix], [{:hackney, "~> 1.7.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], [], "hexpm"}, + "inflex": {:hex, :inflex, "1.7.0", "4466a34b7d8e871d8164619ba0f3b8410ec782e900f0ae1d3d27a5875a29532e", [:mix], [], "hexpm"}, + "json_web_token": {:hex, :json_web_token, "0.2.8", "c79d4c36cfd6f205be7099713e67d6057bde64ee9c64363f9001e3de86de703c", [:mix], [{:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, + "maru": {:hex, :maru, "0.11.3", "0bf2f26955430c4878dab91fe44aeb8b3aaed338b4f6ffd0729ea119284c374d", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, + "meck": {:hex, :meck, "0.8.4", "59ca1cd971372aa223138efcf9b29475bde299e1953046a0c727184790ab1520", [:make, :rebar], [], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, + "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, + "mochiweb": {:hex, :mochiweb, "2.12.2", "80804ad342afa3d7f3524040d4eed66ce74b17a555de454ac85b07c479928e46", [:make, :rebar], [], "hexpm"}, "mws_client": {:git, "https://github.com/FoxComm/elixir-amazon-mws-client.git", "145210296b12d0aaa5ee6cabb21c6a79fea6e96d", []}, - "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [:mix], []}, - "plug": {:hex, :plug, "1.3.3", "d9be189924379b4e9d470caef87380d09549aea1ceafe6a0d41292c8c317c923", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []}, - "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], []}, - "postgrex": {:hex, :postgrex, "0.13.2", "2b88168fc6a5456a27bfb54ccf0ba4025d274841a7a3af5e5deb1b755d95154e", [:mix], [{:connection, "~> 1.0", [hex: :connection, optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}]}, - "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}, - "timex": {:hex, :timex, "3.1.13", "48b33162e3ec33e9a08fb5f98e3f3c19c3e328dded3156096c1969b77d33eef0", [:mix], [{:combine, "~> 0.7", [hex: :combine, optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, optional: false]}]}, - "timex_ecto": {:hex, :timex_ecto, "3.1.1", "37d54f6879d96a6789bb497296531cfb853631de78e152969d95cff03c1368dd", [:mix], [{:ecto, "~> 2.1.0", [hex: :ecto, optional: false]}, {:timex, "~> 3.0", [hex: :timex, optional: false]}]}, - "tzdata": {:hex, :tzdata, "0.5.11", "3d5469a9f46bdf4a8760333dbdabdcc4751325035c454b10521f71e7c611ae50", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, optional: false]}]}} + "parallel_stream": {:hex, :parallel_stream, "1.0.5", "4c78d3e675f9eff885cbe252c89a8fc1d2fb803c0d03a914281e587834e09431", [:mix], [], "hexpm"}, + "plug": {:hex, :plug, "1.3.3", "d9be189924379b4e9d470caef87380d09549aea1ceafe6a0d41292c8c317c923", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, + "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, + "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, + "postgrex": {:hex, :postgrex, "0.13.2", "2b88168fc6a5456a27bfb54ccf0ba4025d274841a7a3af5e5deb1b755d95154e", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, + "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, + "timex": {:hex, :timex, "3.1.13", "48b33162e3ec33e9a08fb5f98e3f3c19c3e328dded3156096c1969b77d33eef0", [:mix], [{:combine, "~> 0.7", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, + "timex_ecto": {:hex, :timex_ecto, "3.1.1", "37d54f6879d96a6789bb497296531cfb853631de78e152969d95cff03c1368dd", [:mix], [{:ecto, "~> 2.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:timex, "~> 3.0", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm"}, + "tzdata": {:hex, :tzdata, "0.5.11", "3d5469a9f46bdf4a8760333dbdabdcc4751325035c454b10521f71e7c611ae50", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}} From b94816f23b706ff75ab7f519aab270c67ff78b6b Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Wed, 28 Jun 2017 16:10:10 +0300 Subject: [PATCH 92/93] fix route for order on customer transactions page --- .../transactions/transaction-row.jsx | 36 ++++++++++++------- ashes/src/components/orders/details.jsx | 14 +++----- .../components/orders/order-line-items.jsx | 4 +-- ashes/src/components/orders/order-row.jsx | 33 +++++++++-------- .../components/payment-row/payment-row.jsx | 7 ++-- ashes/src/paragons/order.js | 13 +++++++ 6 files changed, 65 insertions(+), 42 deletions(-) diff --git a/ashes/src/components/customers/transactions/transaction-row.jsx b/ashes/src/components/customers/transactions/transaction-row.jsx index d4fe15fc37..4fe26ae9a7 100644 --- a/ashes/src/components/customers/transactions/transaction-row.jsx +++ b/ashes/src/components/customers/transactions/transaction-row.jsx @@ -1,9 +1,11 @@ /* @flow */ -import React from 'react'; - // libs import _ from 'lodash'; +import React from 'react'; + +// helpers +import { isAmazonListItemOrder } from 'paragons/order'; // components import MultiSelectRow from '../../table/multi-select-row'; @@ -20,16 +22,22 @@ const OrderTransactionRow = (props: Props) => { const computePaymentState = (order: Object) => { // This is a pretty limited algorithm, but it matches what Phoenix is doing. // We'll beef it up when we get shipping and payment capture in the system. - const authorizations = _.reduce(order.payments, (result, payment) => { - const { paymentMethodType } = payment; - if ((paymentMethodType == 'creditCard' && payment.creditCardState == 'fullCapture') || - (paymentMethodType == 'giftCard' && payment.giftCardState == 'capture') || - (paymentMethodType == 'storeCredit' && payment.storeCreditState == 'capture')) { - return result + 1; - } + const authorizations = _.reduce( + order.payments, + (result, payment) => { + const { paymentMethodType } = payment; + if ( + (paymentMethodType == 'creditCard' && payment.creditCardState == 'fullCapture') || + (paymentMethodType == 'giftCard' && payment.giftCardState == 'capture') || + (paymentMethodType == 'storeCredit' && payment.storeCreditState == 'capture') + ) { + return result + 1; + } - return result; - }, 0); + return result; + }, + 0 + ); return authorizations > 0 && authorizations == order.payments.length ? 'Full Capture' : 'Auth'; }; @@ -59,11 +67,13 @@ const OrderTransactionRow = (props: Props) => { } }; + const route = !isAmazonListItemOrder(order) ? 'order' : 'amazon-order'; + return (
      - {order.channel !== 'Amazon.com' && - - } - {order.channel !== 'Amazon.com' && - - } + {!isAmazonOrder(order) && } + {!isAmazonOrder(order) && } @@ -51,7 +47,7 @@ export default class OrderDetails extends Component {
      - +
      diff --git a/ashes/src/components/orders/order-line-items.jsx b/ashes/src/components/orders/order-line-items.jsx index 88eb27fb88..3b9ff4a425 100644 --- a/ashes/src/components/orders/order-line-items.jsx +++ b/ashes/src/components/orders/order-line-items.jsx @@ -6,7 +6,7 @@ import React from 'react'; import ContentBox from 'components/content-box/content-box'; import SkuLineItems, { defaultColumns } from 'components/sku-line-items/sku-line-items'; -import OrderParagon from 'paragons/order'; +import OrderParagon, { isAmazonOrder } from 'paragons/order'; type Props = { order: OrderParagon, @@ -17,7 +17,7 @@ const OrderLineItems = (props: Props) => { let columns = defaultColumns; - if (props.order.channel === 'Amazon.com') { + if (isAmazonOrder(props.order)) { const skuFieldIndex = findIndex(defaultColumns, { field: 'sku' }); columns = [ diff --git a/ashes/src/components/orders/order-row.jsx b/ashes/src/components/orders/order-row.jsx index 684b336247..8c87c0751b 100644 --- a/ashes/src/components/orders/order-row.jsx +++ b/ashes/src/components/orders/order-row.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import _ from 'lodash'; import MultiSelectRow from '../table/multi-select-row'; -import OrderParagon from 'paragons/order'; +import OrderParagon, { isAmazonListItemOrder } from 'paragons/order'; const compileShippingStatus = order => { if (order.state == 'canceled') { @@ -17,7 +17,7 @@ const compileShippingStatus = order => { let deliveredItemCount = 0; _.forEach(order.shipments, shipment => { - switch(shipment.state) { + switch (shipment.state) { case 'canceled': canceledItemCount += 1; break; @@ -43,11 +43,18 @@ const compileShippingStatus = order => { }); if (order.shipments.length > 0) { - if (order.state == 'fulfillmentStarted' && shippedItemCount > 0 && - deliveredItemCount == 0 && (pendingItemCount > 0 || partiallyShippedItemCount > 0)) { + if ( + order.state == 'fulfillmentStarted' && + shippedItemCount > 0 && + deliveredItemCount == 0 && + (pendingItemCount > 0 || partiallyShippedItemCount > 0) + ) { return 'Partially Shipped'; - } else if (order.state == 'fulfillmentStarted' && deliveredItemCount > 0 && - (shippedItemCount > 0 || pendingItemCount > 0)) { + } else if ( + order.state == 'fulfillmentStarted' && + deliveredItemCount > 0 && + (shippedItemCount > 0 || pendingItemCount > 0) + ) { return 'Partially Delivered'; } else if (canceledItemCount == order.shipments.length) { return 'Canceled'; @@ -62,7 +69,7 @@ const compileShippingStatus = order => { }; const setCellContents = (order, field) => { - switch(field) { + switch (field) { case 'referenceNumber': case 'placedAt': case 'customer.name': @@ -78,24 +85,22 @@ const setCellContents = (order, field) => { }; type Props = { - order: OrderParagon; - columns: Array<*>; - params: Object; + order: OrderParagon, + columns: Array<*>, + params: Object, }; const OrderRow = (props: Props) => { const { order, columns, params } = props; - // @todo verify isAmazon more strictly and convenient - const email = _.get(order, 'customer.email', ''); - const isAmazon = email.endsWith('@marketplace.amazon.com'); + const isAmazon = isAmazonListItemOrder(order); const linkTo = isAmazon ? 'amazon-order' : 'order'; return ( { - if (this.props.order.channel === 'Amazon.com') { + if (isAmazonOrder(this.props.order)) { return null; } @@ -134,8 +134,7 @@ class PaymentRow extends Component { const dir = this.state.showDetails ? 'up' : 'down'; const iconClass = `chevron-${dir}`; - const toggler = - order.channel !== 'Amazon.com' && ; + const toggler = isAmazonOrder(order) && ; return ( diff --git a/ashes/src/paragons/order.js b/ashes/src/paragons/order.js index 52012d0948..54b90bb970 100644 --- a/ashes/src/paragons/order.js +++ b/ashes/src/paragons/order.js @@ -27,6 +27,7 @@ export type Order = { paymentMethods: Array, orderState: string, lineItems: Object, + channel?: string, }; export type ShippingMethod = { @@ -90,6 +91,18 @@ function collectLineItems(skus: Array): Array { }); } +export function isAmazonOrder(order: Order) { + return order.channel === 'Amazon.com'; +} + +// @todo verify isAmazon more strictly and convenient +// @todo: introduce flow types for list responses from ES +export function isAmazonListItemOrder(order: any) { + const customerEmail = _.get(order, 'customer.email', ''); + + return customerEmail.endsWith('@marketplace.amazon.com'); +} + export default class OrderParagon { constructor(order: Order) { Object.assign(this, order); From 163dfe0850e835fd6d0e4c90ce9747d678c58c06 Mon Sep 17 00:00:00 2001 From: "tony.pizzicato" Date: Wed, 28 Jun 2017 16:26:50 +0300 Subject: [PATCH 93/93] fix flow --- ashes/src/components/payment-row/payment-row.jsx | 9 +++++---- ashes/src/paragons/order.js | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ashes/src/components/payment-row/payment-row.jsx b/ashes/src/components/payment-row/payment-row.jsx index b69f51bc10..def3104815 100644 --- a/ashes/src/components/payment-row/payment-row.jsx +++ b/ashes/src/components/payment-row/payment-row.jsx @@ -24,15 +24,15 @@ import styles from './payment-row.css'; // redux import { deleteCreditCardPayment, deleteGiftCardPayment, deleteStoreCreditPayment } from 'modules/carts/details'; -import type Order, { isAmazonOrder } from 'paragons/order'; -import type { Cart, PaymentMethod } from 'paragons/order'; +import OrderParagon, { isAmazonOrder } from 'paragons/order'; +import type { PaymentMethod } from 'paragons/order'; type Props = { customerId: number, editMode: boolean, orderReferenceNumber: string, paymentMethod: PaymentMethod, - order: Cart | Order, + order: OrderParagon, deleteCreditCardPayment: (refNum: string) => Promise<*>, deleteGiftCardPayment: (refNum: string, code: string) => Promise<*>, deleteStoreCreditPayment: (refNum: string) => Promise<*>, @@ -134,7 +134,8 @@ class PaymentRow extends Component { const dir = this.state.showDetails ? 'up' : 'down'; const iconClass = `chevron-${dir}`; - const toggler = isAmazonOrder(order) && ; + const toggler = + !isAmazonOrder(order) && ; return ( diff --git a/ashes/src/paragons/order.js b/ashes/src/paragons/order.js index 54b90bb970..9be54e7e83 100644 --- a/ashes/src/paragons/order.js +++ b/ashes/src/paragons/order.js @@ -27,7 +27,7 @@ export type Order = { paymentMethods: Array, orderState: string, lineItems: Object, - channel?: string, + channel: ?string, }; export type ShippingMethod = { @@ -91,7 +91,7 @@ function collectLineItems(skus: Array): Array { }); } -export function isAmazonOrder(order: Order) { +export function isAmazonOrder(order: OrderParagon) { return order.channel === 'Amazon.com'; }