diff --git a/app/controllers/AuctionsController.scala b/app/controllers/AuctionsController.scala index 69d77b4..8e79f99 100644 --- a/app/controllers/AuctionsController.scala +++ b/app/controllers/AuctionsController.scala @@ -3,13 +3,13 @@ package controllers import actors.auctions.AuctionPublisher import controllers.authentication.AuthenticatedAction import dao.{AuctionsDAO, AuthTokensDAO} -import models.Auction +import models.AuctionStatus.Ready +import models.{Auction, User} import org.apache.pekko.actor.typed.ActorRef import play.api.libs.functional.syntax.toFunctionalBuilderOps -import play.api.libs.json.{JsError, JsPath, JsValue, Json, Reads, Writes} +import play.api.libs.json.* import play.api.mvc.{BaseController, ControllerComponents} -import java.security.SecureRandom import javax.inject.{Inject, Singleton} import scala.concurrent.{ExecutionContext, Future} @@ -21,6 +21,8 @@ class AuctionsController @Inject()(val controllerComponents: ControllerComponent val auctionPublisher: ActorRef[AuctionPublisher.Command], implicit val ec: ExecutionContext) extends BaseController { def index = authenticatedAction.async { implicit request => + given Writes[Auction] = auctionWrites(request.user) + for { auctions <- auctionsDAO.list_available(request.user) json = Json.toJson(auctions) @@ -35,15 +37,28 @@ class AuctionsController @Inject()(val controllerComponents: ControllerComponent for { auction <- auctionsDAO.create(auctionCreateData.name, auctionCreateData.startingPrice, request.user) json = Json.toJson(auction) - response = Created(json) _ = auctionPublisher ! AuctionPublisher.Publish(auction, request.user) - } yield response + } yield Created(json) } ) } private case class AuctionCreateData(name: String, startingPrice: BigDecimal) - private implicit val auctionCreateDataReads: Reads[AuctionCreateData] = ( - (JsPath \ "name").read[String] and (JsPath \ "starting_price").read[BigDecimal] - )(AuctionCreateData.apply) + + private given Reads[AuctionCreateData] = Json.reads[AuctionCreateData] + + private def auctionWrites(user: User): OWrites[Auction] = (o: Auction) => { + Json.toJsObject(o)(using Auction.writes) ++ Json.obj( + "actions" -> Json.obj( + "bid" -> ( + (o.authorId != user.id.get) && + (o.currentBidderId match { + case None => true // If there's no bidder, we can bid + case Some(bidderId) => bidderId != user.id.get + }) && + (o.status == Ready) + ) + ) + ) + } } diff --git a/app/models/models.scala b/app/models/models.scala index 85d8d27..6a5c429 100644 --- a/app/models/models.scala +++ b/app/models/models.scala @@ -1,6 +1,6 @@ package models -import play.api.libs.json.{JsValue, Json, Writes} +import play.api.libs.json.{JsString, JsValue, Json, OWrites, Writes} import java.time.Instant @@ -24,6 +24,8 @@ enum AuctionStatus(val value: Short) { object AuctionStatus { lazy val byValue: Map[Short, AuctionStatus] = Map.from(AuctionStatus.values.map{it => (it.value, it)}) + + implicit val writes: Writes[AuctionStatus] = (o: AuctionStatus) => JsString(o.toString) } case class Auction(id: Option[Int], name: String, status: AuctionStatus, gid: String, authorId: Int, @@ -32,14 +34,5 @@ case class Auction(id: Option[Int], name: String, status: AuctionStatus, gid: St createdAt: Instant) object Auction { - implicit val writes: Writes[Auction] = (a: Auction) => Json.obj( - "id" -> a.id, - "name" -> a.name, - "gid" -> a.gid, - "status" -> a.status.toString, - "starting_price" -> a.startingPrice, - "current_bid" -> a.currentBid, - "current_bidder_id" -> a.currentBidderId, - "current_bid_at" -> a.currentBidAt - ) + implicit val writes: OWrites[Auction] = Json.writes[Auction] } \ No newline at end of file