aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPacien TRAN-GIRARD2015-02-09 00:14:18 +0100
committerPacien TRAN-GIRARD2015-02-09 00:14:18 +0100
commitd79239a89c795035ea8d8a971aa9953d9e9a8e48 (patch)
tree0f910aeaafa3781cd436c0af130ef93379afda0a
parent330d7a719800cded4385c633370f782571891f49 (diff)
downloadminibay-d79239a89c795035ea8d8a971aa9953d9e9a8e48.tar.gz
Implement item pages and bids
-rw-r--r--app/controllers/Sale.scala81
-rw-r--r--app/views/pages/sales/itemPage.scala.html120
-rw-r--r--conf/routes51
3 files changed, 223 insertions, 29 deletions
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 @@
1package controllers 1package controllers
2 2
3import org.omg.CosNaming._BindingIteratorImplBase
3import play.api._ 4import play.api._
4import play.api.data._ 5import play.api.data._
5import play.api.data.Forms._ 6import play.api.data.Forms._
@@ -20,6 +21,8 @@ case class SaleData(endDate: java.sql.Date,
20 longDescription: String, 21 longDescription: String,
21 initialPrice: BigDecimal) 22 initialPrice: BigDecimal)
22 23
24case class BidData(offer: BigDecimal)
25
23object Sale extends Controller { 26object Sale extends Controller {
24 27
25 def sales = Auth { implicit request => 28 def sales = Auth { implicit request =>
@@ -82,11 +85,83 @@ object Sale extends Controller {
82 } 85 }
83 } 86 }
84 87
88 val bidForm = Form(
89 mapping(
90 "offer" -> bigDecimal(precision = 8, scale = 2)
91 )(BidData.apply)(BidData.unapply)
92 )
85 93
86 def item(itemUuid: String) = TODO 94 def item(itemUuid: String) = Auth { implicit request =>
95 DB.withSession { implicit session =>
96 val item = Some(Tables.Items.filter(_.uuid === itemUuid).first)
97
98 if (item.isEmpty) {
99 Redirect(routes.Sale.sales())
100 .flashing("error" -> "Item not found")
101 } else {
102 val seller = Tables.Users.filter(_.uuid === item.get.userUuid).first
103 val bids = Tables.Bids.filter(_.itemUuid === item.get.uuid).sortBy(_.bidDate.desc)
104 val bidders = Tables.Users
105 val bidsWithBidders = (bids join bidders on (_.userUuid === _.uuid)).run
106 Ok(views.html.pages.sales.itemPage(item.get, seller, bidsWithBidders, bidForm))
107 }
108 }
109 }
87 110
88 def bids(itemUuid: String) = TODO 111 def bidSubmit(itemUuid: String) = Auth { implicit request =>
112 if (request.account.isEmpty) {
113 Redirect(routes.Authentication.login())
114 .flashing("error" -> "Authentication required")
115 } else {
116 DB.withSession { implicit session =>
117 val item = Some(Tables.Items.filter(_.uuid === itemUuid).first)
118 val currentTimestamp = new java.sql.Timestamp((new java.util.Date).getTime)
119
120 if (item.isEmpty) {
121 Redirect(routes.Sale.sales())
122 .flashing("error" -> "Item not found")
123 } else if (item.get.endDate before currentTimestamp) {
124 Redirect(routes.Sale.item(itemUuid))
125 .flashing("error" -> "This sale has already ended")
126 } else {
127
128 bidForm.bindFromRequest.fold(
129 formsWithErrors => {
130 Redirect(routes.Sale.item(itemUuid))
131 .flashing("error" -> "Invalid bid")
132 },
133 validForm => {
134
135 val bids = Tables.Bids.filter(_.itemUuid === itemUuid).sortBy(_.bidDate.desc).run
136 val offersEnough = validForm.offer > item.get.initialPrice && (bids.isEmpty || validForm.offer > bids.head.offer)
137
138 val userEquity = Views.Accounts.filter(_.userUuid === request.account.get.userUuid).map(_.equity).first.get
139 val enoughFunds = validForm.offer < userEquity
140
141 if (!enoughFunds) {
142 Redirect(routes.Sale.item(itemUuid))
143 .flashing("error" -> "You are too poor!")
144 } else if (!offersEnough) {
145 Redirect(routes.Sale.item(itemUuid))
146 .flashing("error" -> "Please offer more.")
147 } else {
148 Tables.Bids += new Tables.Bid(
149 itemUuid = itemUuid,
150 userUuid = request.account.get.userUuid.get,
151 bidDate = currentTimestamp,
152 offer = validForm.offer
153 )
154
155 Redirect(routes.Sale.item(itemUuid))
156 .flashing("success" -> "Thanks!")
157 }
158 }
159 )
160
161 }
89 162
90 def bidSubmit(itemUuid: String) = TODO 163 }
164 }
165 }
91 166
92} 167}
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 @@
1@(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)
2
3@templates.ebe("Item page")(request.account) {
4
5 <h2>Item summary: @item.itemName</h2>
6
7 <div class="pure-g">
8 <div class="pure-u-1 pure-u-lg-3-4">
9 <div class="l-box">
10 <table class="pure-table pure-table-horizontal">
11 <thead>
12 <tr>
13 <td colspan="2">Item summary</td>
14 </tr>
15 </thead>
16
17 <tbody>
18 <tr>
19 <td>Item name</td>
20 <td class="align-right">@item.itemName</td>
21 </tr>
22
23 <tr>
24 <td>Short description</td>
25 <td class="align-right">@item.shortDesc</td>
26 </tr>
27 </tbody>
28 </table>
29 </div>
30
31 <div class="l-box">
32 <table class="pure-table pure-table-horizontal">
33 <thead>
34 <tr>
35 <td>Detailed description</td>
36 </tr>
37 </thead>
38
39 <tbody>
40 <tr>
41 <td>@item.longDesc</td>
42 </tr>
43 </tbody>
44
45 </table>
46 </div>
47 </div>
48
49 <div class="pure-u-1 pure-u-lg-1-4">
50 <div class="l-box">
51 <table class="pure-table pure-table-horizontal">
52 <thead>
53 <tr>
54 <td colspan="2">Bid</td>
55 </tr>
56 </thead>
57
58 <tbody>
59 <tr>
60 <td>Current price</td>
61 <td class="align-right">
62 @if(bids.nonEmpty) {
63 @bids.head._1.offer
64 } else {
65 @item.initialPrice
66 } €
67 </td>
68 </tr>
69
70 <tr>
71 <td colspan="2">
72 @helper.form(action = routes.Sale.bidSubmit(item.uuid), 'class -> "pure-form") {
73
74 @helper.CSRF.formField
75
76 <div class="pure-g">
77 <div class="pure-u-1 pure-u-lg-1-2">
78 @views.html.fragments.forms.inputField(bidForm("offer"), "number", "Offer")
79 </div>
80
81 <div class="pure-u-1 pure-u-lg-1-2">
82 <button type="submit" class="pure-button pure-input-1 pure-button-primary">Bid</button>
83 </div>
84 </div>
85 }
86 </td>
87 </tr>
88 </tbody>
89 </table>
90 </div>
91
92 <div class="l-box">
93 <table class="pure-table pure-table-horizontal">
94 <thead>
95 <tr>
96 <td colspan="2">Bid history</td>
97 </tr>
98 </thead>
99
100 <tbody>
101 @if(bids.isEmpty) {
102 <tr>
103 <td colspan="2">No bid</td>
104 </tr>
105 }
106
107 @for(bid <- bids) {
108 <tr></