package services.auctions import dao.{AuctionsDAO, UsersDAO} import models.Auction import play.api.libs.functional.syntax.toFunctionalBuilderOps import play.api.libs.json.{JsPath, JsResult, Reads} import java.time.Instant import javax.inject.Inject import scala.concurrent.{ExecutionContext, Future} object NewBid { case class Request(bid: BigDecimal, bidderGid: String, timestamp: Instant) given Reads[Request] = ( (JsPath \ "bid").read[BigDecimal] and (JsPath \ "bidder_gid").read[String] and (JsPath \ "timestamp").read[Instant] )(Request.apply) } class NewBid @Inject()(auctionsDao: AuctionsDAO, usersDAO: UsersDAO)(using ec: ExecutionContext) { import NewBid.Request def perform(auctionGid: String, request: Request): Future[Option[Auction]] = { val dataFuture = for { auction <- auctionsDao.find_by_gid(auctionGid) bidder <- usersDAO.find_by_gid(request.bidderGid) } yield (auction, bidder) dataFuture.flatMap { case (Some(auction), Some(bidder)) => auctionsDao.newBid(auction, bidder, bid = request.bid, timestamp = request.timestamp) case (_, _) => // One of them (or both) aren't found Future.successful(None) } } }