From: Neil Smith <neil.git@njae.me.uk>
Date: Sat, 7 Mar 2009 00:20:39 +0000 (+0000)
Subject: End chapter 10
X-Git-Url: https://git.njae.me.uk/?a=commitdiff_plain;h=951fe14acc706a4c5ec043e20b3cbfee2b9754d6;p=depot.git

End chapter 10
---

diff --git a/app/controllers/store_controller.rb b/app/controllers/store_controller.rb
index 3b2e6b8..de9e160 100644
--- a/app/controllers/store_controller.rb
+++ b/app/controllers/store_controller.rb
@@ -21,7 +21,33 @@ class StoreController < ApplicationController
     session[:cart] = nil
     redirect_to_index unless request.xhr?
   end
+
+  def checkout
+    @cart = find_cart
+    if @cart.items.empty?
+      redirect_to_index("Your cart is empty" )
+    else
+      @order = Order.new
+      respond_to do |format|
+        format.js if request.xhr?
+        format.html
+      end
+    end
+  end
+
+  def save_order
+    @cart = find_cart
+    @order = Order.new(params[:order])
+    @order.add_line_items_from_cart(@cart)
+    if @order.save
+      session[:cart] = nil
+      redirect_to_index("Thank you for your order")
+    else
+      render :action => 'checkout'
+    end
+  end
   
+
  private
  
   def find_cart
diff --git a/app/models/line_item.rb b/app/models/line_item.rb
index 988324c..61161a0 100644
--- a/app/models/line_item.rb
+++ b/app/models/line_item.rb
@@ -1,2 +1,12 @@
 class LineItem < ActiveRecord::Base
+  belongs_to :order
+  belongs_to :product
+
+  def self.from_cart_item(cart_item)
+    li = self.new
+    li.product      = cart_item.product
+    li.quantity     = cart_item.quantity
+    li.total_price  = cart_item.price
+    li
+  end
 end
diff --git a/app/models/order.rb b/app/models/order.rb
index 0bcb158..bea4da6 100644
--- a/app/models/order.rb
+++ b/app/models/order.rb
@@ -1,2 +1,20 @@
 class Order < ActiveRecord::Base
+  has_many :line_items
+
+  PAYMENT_TYPES = [
+    ["Cheque",          "cheque"],
+    ["Credit card",     "cc"],
+    ["Purchase order",  "po"]
+  ]
+
+  validates_presence_of :name, :address, :email, :pay_type
+  validates_inclusion_of :pay_type, :in =>
+    PAYMENT_TYPES.map {|disp, value| value}
+
+  def add_line_items_from_cart(cart)
+    cart.items.each do |item|
+      li = LineItem.from_cart_item(item)
+      line_items << li
+    end
+  end
 end
diff --git a/app/views/layouts/line_items.html.erb b/app/views/layouts/line_items.html.erb
new file mode 100644
index 0000000..78d24cc
--- /dev/null
+++ b/app/views/layouts/line_items.html.erb
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
+  <title>LineItems: <%= controller.action_name %></title>
+  <%= stylesheet_link_tag 'scaffold' %>
+</head>
+<body>
+
+<p style="color: green"><%= flash[:notice] %></p>
+
+<%= yield  %>
+
+</body>
+</html>
diff --git a/app/views/layouts/orders.html.erb b/app/views/layouts/orders.html.erb
new file mode 100644
index 0000000..ee970df
--- /dev/null
+++ b/app/views/layouts/orders.html.erb
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
+  <title>Orders: <%= controller.action_name %></title>
+  <%= stylesheet_link_tag 'scaffold' %>
+</head>
+<body>
+
+<p style="color: green"><%= flash[:notice] %></p>
+
+<%= yield  %>
+
+</body>
+</html>
diff --git a/app/views/layouts/store.html.erb b/app/views/layouts/store.html.erb
index e55726c..63c7dd9 100644
--- a/app/views/layouts/store.html.erb
+++ b/app/views/layouts/store.html.erb
@@ -17,7 +17,7 @@
         <% hidden_div_if(@cart.items.empty?, :id => "cart") do %>
             <%= render(:partial => "cart" , :object => @cart) %>
         <% end %>
-        <a href="http://www....">Home</a><br />
+        <a href="/">Home</a><br />
         <a href="http://www..../faq">Questions</a><br />
         <a href="http://www..../news">News</a><br />
         <a href="http://www..../contact">Contact</a><br />
diff --git a/app/views/store/_cart.html.erb b/app/views/store/_cart.html.erb
index cc84043..43e9a16 100644
--- a/app/views/store/_cart.html.erb
+++ b/app/views/store/_cart.html.erb
@@ -8,6 +8,10 @@
   </tr>
 </table>
 
+<% form_remote_tag :url => {:action => 'checkout'} do %>
+    <%= submit_tag "Checkout" %>
+<% end %>
+
 <% form_remote_tag :url => {:action => 'empty_cart'} do %>
     <%= submit_tag "Empty cart" %>
 <% end %>
diff --git a/app/views/store/_checkout.html.erb b/app/views/store/_checkout.html.erb
new file mode 100644
index 0000000..f5cd24f
--- /dev/null
+++ b/app/views/store/_checkout.html.erb
@@ -0,0 +1,29 @@
+<div class="depot-form">
+  <%= error_messages_for 'order' %>
+  <% form_for :order, :url => { :action => :save_order } do |form| %>
+    <fieldset>
+      <legend>Please Enter Your Details</legend>
+      <div>
+        <%= form.label :name, "Name:" %>
+        <%= form.text_field :name, :size => 40 %>
+      </div>
+      <div>
+        <%= form.label :address, "Address:" %>
+        <%= form.text_area :address, :rows => 3, :cols => 40 %>
+      </div>
+      <div>
+        <%= form.label :email, "E-Mail:" %>
+        <%= form.text_field :email, :size => 40 %>
+      </div>
+      <div>
+        <%= form.label :pay_type, "Pay by:" %>
+        <%=
+        form.select :pay_type,
+          Order::PAYMENT_TYPES,
+          :prompt => "Select a payment method"
+        %>
+      </div>
+      <%= submit_tag "Place Order" , :class => "submit" %>
+    </fieldset>
+  <% end %>
+</div>
\ No newline at end of file
diff --git a/app/views/store/add_to_cart.js.rjs b/app/views/store/add_to_cart.js.rjs
index 2ef0a83..25dc8ca 100644
--- a/app/views/store/add_to_cart.js.rjs
+++ b/app/views/store/add_to_cart.js.rjs
@@ -1,3 +1,5 @@
+page.select("div#notice").each {|div| div.hide}
+
 page.replace_html("cart", :partial => 'cart', :object => @cart)
 
 page[:cart].visual_effect :blind_down if @cart.total_items == 1
@@ -5,3 +7,4 @@ page[:cart].visual_effect :blind_down if @cart.total_items == 1
 page[:current_item].visual_effect :highlight,
                                   :startcolor => "#88ff88" ,
                                   :endcolor => "#114411"
+
diff --git a/app/views/store/checkout.html.erb b/app/views/store/checkout.html.erb
new file mode 100644
index 0000000..e41398d
--- /dev/null
+++ b/app/views/store/checkout.html.erb
@@ -0,0 +1 @@
+<%= render(:partial => "checkout", :object => @order) %>
diff --git a/app/views/store/checkout.js.rjs b/app/views/store/checkout.js.rjs
new file mode 100644
index 0000000..d819e16
--- /dev/null
+++ b/app/views/store/checkout.js.rjs
@@ -0,0 +1 @@
+page.replace_html("main_panel", :partial => "checkout", :object => @order)
diff --git a/app/views/store/index.html.erb b/app/views/store/index.html.erb
index f3e7ebe..63c12da 100644
--- a/app/views/store/index.html.erb
+++ b/app/views/store/index.html.erb
@@ -1,3 +1,4 @@
+<div id="main_panel">
 <h1>Neil's Whimsical Store Catalogue</h1>
 
 <% for product in @products -%>
@@ -15,3 +16,4 @@
     </div>
   </div>
 <% end %>
+</div>
diff --git a/db/migrate/20090304153209_create_orders.rb b/db/migrate/20090304153209_create_orders.rb
index a0a1598..3852118 100644
--- a/db/migrate/20090304153209_create_orders.rb
+++ b/db/migrate/20090304153209_create_orders.rb
@@ -4,7 +4,7 @@ class CreateOrders < ActiveRecord::Migration
       t.string :name
       t.text :address
       t.string :email
-      t.string :pay_type
+      t.string :pay_type, :limit => 10
 
       t.timestamps
     end
diff --git a/db/migrate/20090304153613_create_line_items.rb b/db/migrate/20090304153613_create_line_items.rb
index 6870a05..fcd4625 100644
--- a/db/migrate/20090304153613_create_line_items.rb
+++ b/db/migrate/20090304153613_create_line_items.rb
@@ -1,13 +1,20 @@
 class CreateLineItems < ActiveRecord::Migration
   def self.up
     create_table :line_items do |t|
-      t.integer :product_id
-      t.integer :order_id
-      t.integer :quantity
-      t.decimal :total_price
+      t.integer :product_id,  :null => false
+      t.integer :order_id,    :null => false
+      t.integer :quantity,    :null => false
+      t.decimal :total_price, :null => false, :precision => 8, :scale => 2
 
       t.timestamps
     end
+
+    execute "alter table line_items add constraint fk_line_item_products
+                foreign key (product_id) references products(id)"
+
+    execute "alter table line_items add constraint fk_line_item_orders
+                foreign key (order_id) references orders(id)"
+    
   end
 
   def self.down
diff --git a/db/schema.rb b/db/schema.rb
index d08e763..d017a09 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -9,7 +9,28 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20090226212307) do
+ActiveRecord::Schema.define(:version => 20090304153613) do
+
+  create_table "line_items", :force => true do |t|
+    t.integer  "product_id",                                :null => false
+    t.integer  "order_id",                                  :null => false
+    t.integer  "quantity",                                  :null => false
+    t.decimal  "total_price", :precision => 8, :scale => 2, :null => false
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  add_index "line_items", ["order_id"], :name => "fk_line_item_orders"
+  add_index "line_items", ["product_id"], :name => "fk_line_item_products"
+
+  create_table "orders", :force => true do |t|
+    t.string   "name"
+    t.text     "address"
+    t.string   "email"
+    t.string   "pay_type",   :limit => 10
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
 
   create_table "products", :force => true do |t|
     t.string   "title"
diff --git a/public/stylesheets/depot.css b/public/stylesheets/depot.css
index bb4934d..5579185 100644
--- a/public/stylesheets/depot.css
+++ b/public/stylesheets/depot.css
@@ -199,7 +199,41 @@ h1 {
 }
 /* END:cartside */
 
+/* START:form */
+/* Styles for order form */
 
+.depot-form fieldset {
+  background: #efe;
+}
+
+.depot-form legend {
+  color: #dfd;
+  background: #141;
+  font-family: sans-serif;
+  padding: 0.2em 1em;
+}
+
+.depot-form label {
+  width: 5em;
+  float: left;
+  text-align: right;
+  padding-top: 0.2em;
+  margin-right: 0.1em;
+  display: block;
+}
+
+.depot-form select, .depot-form textarea, .depot-form input {
+  margin-left: 0.5em;
+}
+
+.depot-form .submit {
+  margin-left: 4em;
+}
+
+.depot-form div {
+  margin: 0.5em 0;
+}
+/* END:form */
 
 /* The error box */