Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion phoenix-scala/core/app/core/db/Star.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ object * extends LazyLogging {
DbResultT.fromResult(fa)

def <~[A](v: A)(implicit ec: EC): DbResultT[A] =
DbResultT.pure(v)
v.pure[DbResultT]

def <~[A](v: Validated[Failures, A])(implicit ec: EC): DbResultT[A] =
DbResultT.fromEither(v.toEither)
Expand Down
23 changes: 7 additions & 16 deletions phoenix-scala/core/app/core/db/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,14 @@ package object db {
}

trait FoxyTFunctions[F[_]] {
def apply[A](a: A)(implicit F: Monad[F]): FoxyT[F, A] = // TODO: remove me? @michalrus

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code.

pure(a)

def pure[A](a: A)(implicit F: Monad[F]): FoxyT[F, A] =

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed, we have pure from cats.

Monad[FoxyT[F, ?]].pure(a)

def good[A](a: A)(implicit F: Monad[F]): FoxyT[F, A] = // TODO: remove me @michalrus
pure(a)
a.pure[FoxyT[F, ?]]

def unit(implicit F: Monad[F]): FoxyT[F, Unit] =
pure(()) // TODO: remove me? @michalrus
().pure[FoxyT[F, ?]] // TODO: remove me? @michalrus

def none[A](implicit F: Monad[F]): FoxyT[F, Option[A]] =
pure(None) // TODO: remove me? @michalrus
(None: Option[A]).pure[FoxyT[F, ?]] // TODO: remove me? @michalrus

def uiWarning(f: Failure)(implicit F: Monad[F]): FoxyT[F, Unit] =
StateT.modify(MetaResponse.Warning(f) :: _)
Expand Down Expand Up @@ -161,7 +155,7 @@ package object db {
L.map(lfa)(_.fold(Either.left(_), Either.right(_))).sequence.flatMap { xa ⇒
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(_))
NonEmptyList.fromList(failures).fold(values.pure[FoxyT[F, ?]])(FoxyT[F].failures(_))
}

/** A bit like ``sequence`` but will ignore failed Foxies. */
Expand Down Expand Up @@ -276,15 +270,12 @@ package object db {
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)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed, we have pure from cats.


def liftFuture[A](future: Future[A]): DBIO[A] = DBIO.from(future)

// TODO: I don’t know… does this help? @michalrus
def ifElse[A](condition: Boolean, ifBranch: ⇒ DbResultT[A], elseBranch: ⇒ DbResultT[A]) =
if (condition) ifBranch else elseBranch

def doOrMeh(condition: Boolean, action: ⇒ DbResultT[_])(implicit ec: EC): DbResultT[Unit] =
if (condition) action.meh else DbResultT.unit
def when[F[_]](p: Boolean, s: ⇒ F[Unit])(implicit F: Applicative[F]): F[Unit] =

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (p) s.void else F.pure(())

def doOrGood[A](condition: Boolean, action: ⇒ DbResultT[A], good: ⇒ A)(implicit ec: EC): DbResultT[A] =
if (condition) action else DbResultT.good(good)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ object ObjectUtils {
for {
commit ← * <~ ObjectCommits.create(ObjectCommit(formId = form.id, shadowId = shadow.id))
} yield commit.some
else DbResultT.pure(None)
else none[ObjectCommit].pure[DbResultT]

private def updateIfDifferent(
old: FormAndShadow,
Expand All @@ -244,14 +244,14 @@ object ObjectUtils {
}
_ ← * <~ validateShadow(form, shadow)
} yield UpdateResult(form, shadow, updated = true)
else DbResultT.pure(UpdateResult(old.form, old.shadow, updated = false))
else UpdateResult(old.form, old.shadow, updated = false).pure[DbResultT]

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 {
case head :: tail ⇒ DbResultT.failures(NonEmptyList(head, tail))
case Nil ⇒ DbResultT.pure(Unit)
case Nil ⇒ ().pure[DbResultT]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package objectframework.models

import java.time.Instant

import cats.implicits._
import core.db.ExPostgresDriver.api._
import core.db._
import objectframework.services.ObjectManager
Expand Down Expand Up @@ -88,7 +89,7 @@ object ObjectHeadLinks {
def createIfNotExist(left: L, right: R)(implicit ec: EC, db: DB): DbResultT[Unit] =
for {
linkExists ← * <~ filterLeft(left).filter(_.rightId === right.id).exists.result
_ ← * <~ doOrMeh(!linkExists, create(build(left, right)))
_ ← * <~ when(!linkExists, create(build(left, right)).void)
} yield {}

def build(left: L, right: R): M
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package objectframework.services

import org.json4s._

import cats.data._
import cats.implicits._

import cats.kernel.Monoid
import core.db.ExPostgresDriver.api._
import core.db._
import core.failures.Failure

import objectframework.IlluminateAlgorithm
import objectframework.content._
import objectframework.db._
Expand Down Expand Up @@ -54,7 +52,7 @@ object ContentManager {

type FullContentRelations = Map[String, Seq[Content]]
def getRelations(content: Content)(implicit ec: EC): DbResultT[FullContentRelations] = {
val empty = DbResultT.pure(Map.empty[String, Seq[Content]])
val empty = (Map.empty : FullContentRelations).pure[DbResultT]

content.relations.foldLeft(empty) { (accRelations, relation) ⇒
accRelations.flatMap { relations ⇒
Expand Down Expand Up @@ -106,6 +104,6 @@ object ContentManager {
private def failIfErrors(errors: Seq[Failure])(implicit ec: EC): DbResultT[Unit] =
errors match {
case head :: tail ⇒ DbResultT.failures(NonEmptyList(head, tail))
case Nil ⇒ DbResultT.pure(Unit)
case Nil ⇒ ().pure[DbResultT]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ case class CustomerGroup(id: Int = 0,
scope: LTree,
createdBy: Int,
name: String,
customersCount: Int = 0,
customersCount: Int = 0, // FIXME: is this denormalization needed at all? https://foxcommerce.slack.com/archives/C06696D1R/p1498564090580988 @michalrus
clientState: Json,
elasticRequest: Json,
groupType: GroupType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,6 @@ object SearchReference {
def productsSearchField: String = "productId"
def skuSearchField: String = "code"

def pureMetrics(implicit ec: EC): Result[Long] = Result.pure(0L)
def pureBuckets(implicit ec: EC): Result[Buckets] = Result.pure(Seq.empty)
def pureMetrics(implicit ec: EC): Result[Long] = 0L.pure[Result]
def pureBuckets(implicit ec: EC): Result[Buckets] = (Seq.empty : Buckets).pure[Result]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package phoenix.responses

import java.time.Instant

import cats.implicits._
import core.db._
import core.utils.Money._
import phoenix.models.account.{Organization, Organizations, Users}
import phoenix.models.account.{Organization, Organizations, User, Users}
import phoenix.models.admin.AdminsData
import phoenix.models.customer.CustomersData
import phoenix.models.payment.giftcard.GiftCard
Expand Down Expand Up @@ -103,9 +104,9 @@ object ReturnResponse {
// Either customer or storeAdmin as creator
customer ← * <~ Users.findOneByAccountId(rma.accountId)
customerData ← * <~ CustomersData.findOneByAccountId(rma.accountId)
storeAdmin ← * <~ rma.storeAdminId.map(Users.findOneByAccountId).getOrElse(lift(None))
adminData ← * <~ rma.storeAdminId.map(AdminsData.findOneByAccountId).getOrElse(lift(None))
organization ← * <~ rma.storeAdminId.map(Organizations.mustFindByAccountId)
storeAdmin rma.storeAdminId.flatTraverse(Users.findOneByAccountId(_).dbresult)
adminData ← * <~ rma.storeAdminId.flatTraverse(AdminsData.findOneByAccountId(_).dbresult)
organization ← * <~ rma.storeAdminId.traverse(Organizations.mustFindByAccountId)
// Payment methods
ccPayment ← * <~ ReturnPayments.findAllByReturnId(rma.id).creditCards.one
applePayPayment ← * <~ ReturnPayments.findAllByReturnId(rma.id).applePays.one
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ object CordResponsePromotions {
/** 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]] =
fa.flatMap(_.map(a ⇒ DbResultT.pure(a.some)).getOrElse(fb))
fa.flatMap(_.map(a ⇒ a.some.pure[DbResultT]).getOrElse(fb))

private def renderPromotionResponse(
promotion: Promotion)(implicit ec: EC, ctx: OC, db: DB): DbResultT[PromotionResponse.Root] =
Expand Down
2 changes: 1 addition & 1 deletion phoenix-scala/phoenix/app/phoenix/routes/AuthRoutes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object AuthRoutes {

pathPrefix("public") {
(post & path("login") & entity(as[LoginPayload])) { payload ⇒
doLogin(DbResultT.pure(payload))(_.runDBIO())
doLogin(payload.pure[DbResultT] )(_.runDBIO())
} ~
activityContext(defaultScope) { implicit ac ⇒
(post & path("send-password-reset") & pathEnd & entity(as[ResetPasswordSend])) { payload ⇒
Expand Down
18 changes: 10 additions & 8 deletions phoenix-scala/phoenix/app/phoenix/services/Capture.scala
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap
externalCaptureTotal ← * <~ determineExternalCapture(total, gcPayments, scPayments, order.currency)
internalCaptureTotal = total - externalCaptureTotal
_ ← * <~ internalCapture(internalCaptureTotal, order, customer, gcPayments, scPayments)
_ ← * <~ doOrMeh(externalCaptureTotal > 0, externalCapture(externalCaptureTotal, order))
_ ← * <~ when(externalCaptureTotal > 0, externalCapture(externalCaptureTotal, order))

resp = CaptureResponse(
order = order.refNum,
Expand Down Expand Up @@ -142,8 +142,8 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap
scIds = scPayments.map { case (_, sc) ⇒ sc.id }.distinct
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))
_ ← * <~ when(scTotal > 0, LogActivity().scFundsCaptured(customer, order, scIds, scTotal).void)
_ ← * <~ when(gcTotal > 0, LogActivity().gcFundsCaptured(customer, order, gcCodes, gcTotal).void)
} yield {}

private def externalCapture(total: Long, order: Order): DbResultT[Unit] = {
Expand Down Expand Up @@ -277,10 +277,12 @@ 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))
LineItemPrice(item.lineItem.referenceNumber, item.sku.code, price, currency).pure[DbResultT]
case None ⇒ DbResultT.failure(CaptureFailures.SkuMissingPrice(item.sku.code))
}

// FIXME: use MonadError below, no need for DbResultT @michalrus

private def validatePayload(payload: CapturePayloads.Capture,
orderSkus: Seq[OrderLineItemProductData]): DbResultT[Unit] =
for {
Expand All @@ -299,12 +301,12 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap
private def paymentStateMustBeInAuth(order: Order, paymentState: CordPaymentState.State): DbResultT[Unit] =
if (paymentState != CordPaymentState.Auth)
DbResultT.failure(CaptureFailures.OrderMustBeInAuthState(order.refNum))
else DbResultT.pure(Unit)
else ().pure[DbResultT]

private def mustHavePositiveShippingCost(shippingCost: CapturePayloads.ShippingCost): DbResultT[Unit] =
if (shippingCost.total < 0)
DbResultT.failure(CaptureFailures.ShippingCostNegative(shippingCost.total))
else DbResultT.pure(Unit)
else ().pure[DbResultT]

private def mustHaveCodes(items: Seq[CapturePayloads.CaptureLineItem],
codes: Seq[String],
Expand All @@ -316,10 +318,10 @@ case class Capture(payload: CapturePayloads.Capture)(implicit ec: EC, db: DB, ap
private def mustHaveCode(item: CapturePayloads.CaptureLineItem,
codes: Seq[String],
orderRef: String): DbResultT[Unit] =
if (codes.contains(item.sku)) DbResultT.pure(Unit)
if (codes.contains(item.sku)) ().pure[DbResultT]
else DbResultT.failure(CaptureFailures.SkuNotFoundInOrder(item.sku, orderRef))

private def mustHaveSameLineItems(lOne: Int, lTwo: Int, orderRef: String): DbResultT[Unit] =
if (lOne == lTwo) DbResultT.pure(Unit)
if (lOne == lTwo) ().pure[DbResultT]
else DbResultT.failure(CaptureFailures.SplitCaptureNotSupported(orderRef))
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C
// Deactivation/archival don’t happen often enough to justify
// this additional overhead for each cart GET request.
hasActiveLineItems(state)
} else DbResultT.pure(state))
} else state.pure[DbResultT])
state ← * <~ hasShipAddress(state)
state ← * <~ validShipMethod(state)
state ← * <~ sufficientPayments(state, isCheckout)
Expand Down Expand Up @@ -145,7 +145,7 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C
// 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)) {
lift(response)
response.pure[DBIO]
} else if (payments.nonEmpty) {
cartFunds(payments).map {
case Some(funds) if funds >= grandTotal ⇒
Expand All @@ -155,7 +155,7 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C
warning(response, InsufficientFunds(cart.refNum))
}
} else {
lift(warning(response, InsufficientFunds(cart.refNum)))
warning(response, InsufficientFunds(cart.refNum)).pure[DBIO]
}

if (cart.grandTotal > 0 || cart.subTotal > 0) {
Expand All @@ -164,7 +164,7 @@ case class CartValidator(cart: Cart)(implicit ec: EC, db: DB, ctx: OC) extends C
.result
.flatMap(availableFunds(cart.grandTotal, _))
} else {
lift(response)
response.pure[DBIO]
}
}

Expand Down
15 changes: 8 additions & 7 deletions phoenix-scala/phoenix/app/phoenix/services/Checkout.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ object PaymentHelper {
apis: Apis,
ac: AC): DbResultT[Long] =
if (payments.isEmpty) {
DbResultT.pure(0L)
0L.pure[DbResultT]
} else {

val amounts: Seq[Long] = payments.map { case (payment, _) ⇒ payment.getAmount() }
Expand Down Expand Up @@ -195,6 +195,7 @@ object Checkout {
}

class ExternalCalls {
// FIXME: have mercy… @michalrus
@volatile var authPaymentsSuccess: Boolean = false
@volatile var middleWarehouseSuccess: Boolean = false
}
Expand Down Expand Up @@ -240,10 +241,10 @@ case class Checkout(
liSkus ← * <~ CartLineItems.byCordRef(cart.refNum).countSkus
inventoryTrackedSkus ← * <~ filterInventoryTrackingSkus(liSkus)
skusToHold ← * <~ inventoryTrackedSkus.map(sku ⇒ SkuInventoryHold(sku.code, sku.qty))
_ ← * <~ doOrMeh(skusToHold.nonEmpty,
_ ← * <~ when(skusToHold.nonEmpty,
DbResultT.fromResult(
apis.middlewarehouse.hold(OrderInventoryHold(cart.referenceNumber, skusToHold))))
mutating = externalCalls.middleWarehouseSuccess = skusToHold.nonEmpty
mutating = externalCalls.middleWarehouseSuccess = skusToHold.nonEmpty // FIXME: I almost removed that, having read `==` here. Please, don’t… @michalrus
} yield {}

private def filterInventoryTrackingSkus(skus: Map[String, Int]) =
Expand Down Expand Up @@ -331,13 +332,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))
_ ← * <~ when(scTotal > 0, LogActivity().scFundsAuthorized(customer, cart, scIds, scTotal).void)
_ ← * <~ when(gcTotal > 0, LogActivity().gcFundsAuthorized(customer, cart, gcCodes, gcTotal).void)

grandTotal = cart.grandTotal
internalPayments = gcTotal + scTotal
_ ← * <~ doOrMeh(grandTotal > internalPayments, // run external payments only if we have to pay more
doExternalPayment(grandTotal - internalPayments))
_ ← * <~ when(grandTotal > internalPayments, // run external payments only if we have to pay more
doExternalPayment(grandTotal - internalPayments).void)

mutatingResult = externalCalls.authPaymentsSuccess = true // fixme is this flag used anywhere? @aafa
} yield {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ object CreditCardManager {
.map(_.gatewayCustomerId)
.one
address = Address.fromPayload(payload.billingAddress, customer.accountId)
_ ← * <~ doOrMeh(payload.addressIsNew, Addresses.create(address))
_ ← * <~ when(payload.addressIsNew, Addresses.create(address).void)
stripes ← * <~ apis.stripe.createCardFromToken(email = customer.email,
token = payload.token,
stripeCustomerId = customerToken,
Expand All @@ -69,7 +69,7 @@ object CreditCardManager {

def createCard(customer: User, sCustomer: StripeCustomer, sCard: StripeCard, address: Address) =
for {
_ ← * <~ doOrMeh(address.isNew, Addresses.create(address.copy(accountId = accountId)))
_ ← * <~ when(address.isNew, Addresses.create(address.copy(accountId = accountId)).void)
cc = CreditCard.buildFromSource(accountId, sCustomer, sCard, payload, address)
newCard ← * <~ CreditCards.create(cc)
region ← * <~ Regions.findOneById(newCard.address.regionId).safeGet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ object AccountManager {
.filter(_.state === (AdminData.Invited: AdminData.State))
.one
_ ← * <~ adminCreated.map(ad ⇒ AdminsData.update(ad, ad.copy(state = AdminData.Active)))
_ ← * <~ doOrMeh(adminCreated.isEmpty, LogActivity().userPasswordReset(user))
_ ← * <~ when(adminCreated.isEmpty, LogActivity().userPasswordReset(user).void)
} yield ResetPasswordDoneAnswer(email = remind.email, org = organization.name)

def getById(accountId: Int)(implicit ec: EC, db: DB): DbResultT[UserResponse] =
Expand All @@ -114,7 +114,7 @@ object AccountManager {
.findByNameInScope(context.org, scope.id)
.mustFindOr(OrganizationNotFound(context.org, scope.path))

_ ← * <~ doOrMeh(checkEmail, email.fold(DbResultT.unit)(Users.createEmailMustBeUnique))
_ ← * <~ when(checkEmail, email.fold(DbResultT.unit)(Users.createEmailMustBeUnique))

account ← * <~ Accounts.create(Account())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class RemorseTimer(implicit db: DB, ec: EC, apis: Apis) extends Actor {
val query = for {
cordRefs ← * <~ orders.result
count ← * <~ orders.map(_.state).update(newState)
_ ← * <~ doOrMeh(count > 0, logAcitvity(newState, cordRefs))
_ ← * <~ when(count > 0, logAcitvity(newState, cordRefs))
} yield count

RemorseTimerResponse(query.runTxn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ object CartLineItemUpdater {
.filterByContext(ctx.id)
.filter(_.code === lineItem.sku)
.mustFindOneOr(SkuNotFoundForContext(lineItem.sku, ctx.id))
fullSku ← ObjectManager.getFullObject(DbResultT.pure(sku))
fullSku ← ObjectManager.getFullObject(sku.pure[DbResultT])
_ ← * <~ IlluminatedSku.illuminate(ctx, fullSku).mustBeActive
// TODO: check if that SKU’s Product is not archived/deactivated @michalrus
_ ← * <~ mustFindProductIdForSku(sku, cart.refNum)
Expand Down
Loading