From d79239a89c795035ea8d8a971aa9953d9e9a8e48 Mon Sep 17 00:00:00 2001 From: Pacien TRAN-GIRARD Date: Mon, 9 Feb 2015 00:14:18 +0100 Subject: Implement item pages and bids --- app/controllers/Sale.scala | 81 +++++++++++++++++++- app/views/pages/sales/itemPage.scala.html | 120 ++++++++++++++++++++++++++++++ conf/routes | 51 +++++++------ 3 files changed, 223 insertions(+), 29 deletions(-) create mode 100644 app/views/pages/sales/itemPage.scala.html diff --git a/app/controllers/Sale.scala b/app/controllers/Sale.scala index e6244c3..d6dab2d 100644 --- a/app/controllers/Sale.scala +++ b/app/controllers/Sale.scala @@ -1,5 +1,6 @@ package controllers +import org.omg.CosNaming._BindingIteratorImplBase import play.api._ import play.api.data._ import play.api.data.Forms._ @@ -20,6 +21,8 @@ case class SaleData(endDate: java.sql.Date, longDescription: String, initialPrice: BigDecimal) +case class BidData(offer: BigDecimal) + object Sale extends Controller { def sales = Auth { implicit request => @@ -82,11 +85,83 @@ object Sale extends Controller { } } + val bidForm = Form( + mapping( + "offer" -> bigDecimal(precision = 8, scale = 2) + )(BidData.apply)(BidData.unapply) + ) - def item(itemUuid: String) = TODO + def item(itemUuid: String) = Auth { implicit request => + DB.withSession { implicit session => + val item = Some(Tables.Items.filter(_.uuid === itemUuid).first) + + if (item.isEmpty) { + Redirect(routes.Sale.sales()) + .flashing("error" -> "Item not found") + } else { + val seller = Tables.Users.filter(_.uuid === item.get.userUuid).first + val bids = Tables.Bids.filter(_.itemUuid === item.get.uuid).sortBy(_.bidDate.desc) + val bidders = Tables.Users + val bidsWithBidders = (bids join bidders on (_.userUuid === _.uuid)).run + Ok(views.html.pages.sales.itemPage(item.get, seller, bidsWithBidders, bidForm)) + } + } + } - def bids(itemUuid: String) = TODO + def bidSubmit(itemUuid: String) = Auth { implicit request => + if (request.account.isEmpty) { + Redirect(routes.Authentication.login()) + .flashing("error" -> "Authentication required") + } else { + DB.withSession { implicit session => + val item = Some(Tables.Items.filter(_.uuid === itemUuid).first) + val currentTimestamp = new java.sql.Timestamp((new java.util.Date).getTime) + + if (item.isEmpty) { + Redirect(routes.Sale.sales()) + .flashing("error" -> "Item not found") + } else if (item.get.endDate before currentTimestamp) { + Redirect(routes.Sale.item(itemUuid)) + .flashing("error" -> "This sale has already ended") + } else { + + bidForm.bindFromRequest.fold( + formsWithErrors => { + Redirect(routes.Sale.item(itemUuid)) + .flashing("error" -> "Invalid bid") + }, + validForm => { + + val bids = Tables.Bids.filter(_.itemUuid === itemUuid).sortBy(_.bidDate.desc).run + val offersEnough = validForm.offer > item.get.initialPrice && (bids.isEmpty || validForm.offer > bids.head.offer) + + val userEquity = Views.Accounts.filter(_.userUuid === request.account.get.userUuid).map(_.equity).first.get + val enoughFunds = validForm.offer < userEquity + + if (!enoughFunds) { + Redirect(routes.Sale.item(itemUuid)) + .flashing("error" -> "You are too poor!") + } else if (!offersEnough) { + Redirect(routes.Sale.item(itemUuid)) + .flashing("error" -> "Please offer more.") + } else { + Tables.Bids += new Tables.Bid( + itemUuid = itemUuid, + userUuid = request.account.get.userUuid.get, + bidDate = currentTimestamp, + offer = validForm.offer + ) + + Redirect(routes.Sale.item(itemUuid)) + .flashing("success" -> "Thanks!") + } + } + ) + + } - def bidSubmit(itemUuid: String) = TODO + } + } + } } diff --git a/app/views/pages/sales/itemPage.scala.html b/app/views/pages/sales/itemPage.scala.html new file mode 100644 index 0000000..adfd5da --- /dev/null +++ b/app/views/pages/sales/itemPage.scala.html @@ -0,0 +1,120 @@ +@(item: Tables.Item, seller: Tables.User, bids: Seq[(Tables.Bid, Tables.User)], bidForm: Form[BidData])(implicit request: AuthRequest[AnyContent], flash: Flash, token: play.filters.csrf.CSRF.Token) + +@templates.ebe("Item page")(request.account) { + +
Item summary | +|
Item name | +@item.itemName | +
Short description | +@item.shortDesc | +
Detailed description | +
@item.longDesc | +
Bid | +|
Current price | ++ @if(bids.nonEmpty) { + @bids.head._1.offer + } else { + @item.initialPrice + } € + | +
+ @helper.form(action = routes.Sale.bidSubmit(item.uuid), 'class -> "pure-form") {
+
+ @helper.CSRF.formField
+
+
+
+ }
+
+ @views.html.fragments.forms.inputField(bidForm("offer"), "number", "Offer")
+
+
+
+
+
+ |
+
Bid history | +|
No bid | +|
@bid._2.username | +@bid._1.offer | +