--- /dev/null
+class PurchaseController < ApplicationController
+
+ def index
+ redirect_to :action => :begin
+ end
+
+ def list
+ @purchase_pages, @purchase = paginate :purchases, :per_page => 100
+ end
+
+ def begin
+ # enter a customer id here
+ render :action => 'begin'
+ session[:total] = 0.00
+ end
+
+ def customer_ok
+ if Customer.find_by_id(params[:customer_id])
+ session[:customer_id] = params[:customer_id]
+ redirect_to :action => :menu
+ else
+ flash[:error] = "Customer ID is invalid"
+ redirect_to :action => :begin
+ end
+ end
+
+ def menu
+ @customer = Customer.find_by_id(session[:customer_id])
+ @total_price = session[:total]
+ render :action => 'menu'
+ end
+
+ def rent_begin
+ render :action => 'rent_begin'
+ end
+
+ def rent_validate
+ @customer = Customer.find_by_id(session[:customer_id])
+ @rentable = Rentable.find_by_id(params[:rentable_id])
+
+ if @customer.nil?
+ flash[:error] = "Customer ID is invalid"
+ redirect_to :action => :begin
+ return
+ end
+
+ if @rentable.nil?
+ flash[:error] = "Rentable ID is invalid"
+ redirect_to :action => :rent_begin
+ return
+ end
+
+ # Actually record the purchase
+ purchase = RentablePurchase.new
+ purchase.customer_id = session[:customer_id]
+ purchase.date = Time.now.to_date
+ purchase.price = @rentable.calculated_price
+ session[:total] += @rentable.calculated_price
+ purchase.rentable = @rentable
+ purchase.save!
+
+ flash[:notice] = "Successfully made purchase"
+ redirect_to :action => :menu
+ end
+
+ def buy_begin
+ render :action => 'buy_begin'
+ end
+
+ def buy_validate
+ @customer = Customer.find_by_id(session[:customer_id])
+ @merchandise = Merchandise.find_by_id(params[:merchandise_id])
+
+ if @customer.nil?
+ flash[:error] = "Customer ID is invalid"
+ redirect_to :action => :begin
+ return
+ end
+
+ if @merchandise.nil?
+ flash[:error] = "Merchandise ID is invalid"
+ redirect_to :action => :buy_begin
+ return
+ end
+
+ if @merchandise.quantity < 1
+ flash[:error] = "The system thinks we are out of this merchandise item!"
+ redirect_to :action => :buy_begin
+ return
+ end
+
+ # Actually record the purchase
+ purchase = MerchandisePurchase.new
+ purchase.customer_id = session[:customer_id]
+ purchase.date = Time.now.to_date
+ purchase.price = @merchandise.price
+ session[:total] += @merchandise.price
+ purchase.merchandise = @merchandise
+ purchase.quantity = 1
+ @merchandise.quantity -= 1
+
+ # Save both the merchandise (we changed the quantity) and the purchase to the log
+ @merchandise.save!
+ purchase.save!
+
+ flash[:notice] = "Successfully made purchase"
+ redirect_to :action => :menu
+ end
+end
--- /dev/null
+module PurchaseHelper
+end
class Customer < ActiveRecord::Base
has_many :coitems
has_many :bitems
+ has_many :merchandise_purchases
+ has_many :rentable_purchases
validates_presence_of :name, :email, :phone, :address
validates_numericality_of :debt
validates_presence_of :game_genre
validates_presence_of :platform
+ def calculated_price
+ # FIXME: generate this based on day of week, newrelase
+ return 11
+ end
end
class Merchandise < ActiveRecord::Base
+ has_many :merchandise_purchases
+
validates_presence_of :name
validates_numericality_of :quantity
validates_numericality_of :price
--- /dev/null
+class MerchandisePurchase < Purchase
+ belongs_to :merchandise
+ belongs_to :customer
+
+ validates_presence_of :merchandise_id
+ validates_presence_of :quantity
+
+ validates_numericality_of :merchandise_id
+ validates_numericality_of :quantity
+
+ protected
+ def validate
+ errors.add(:merchandise_id, "does not exist in the database") if merchandise.nil?
+ #errors.add(:quantity, "must be 1 or greater") if quantity < 1
+ end
+end
class Purchase < ActiveRecord::Base
+ belongs_to :customer
+
+ validates_presence_of :customer_id
+ validates_presence_of :date
+ validates_presence_of :price
+ validates_numericality_of :price
+
+ protected
+ def validate
+ errors.add(:price, "cannot be negative") if price < 0
+ errors.add(:price, "cannot be less than $0.01") if price < 0.01
+ errors.add(:customer_id, "does not exist in the database") if customer.nil?
+ end
end
class Rentable < ActiveRecord::Base
- has_many :coitem
+ has_many :coitems
+ has_many :rentable_purchases
validates_presence_of :title
# don't validate newrelease, false is ok
--- /dev/null
+class RentablePurchase < Purchase
+ belongs_to :rentable
+ belongs_to :customer
+
+ validates_presence_of :rentable_id
+ validates_numericality_of :rentable_id
+
+ protected
+ def validate
+ errors.add(:rentable_id, "is not in the database") if rentable.nil?
+ end
+end
validates_presence_of :video_genre
validates_presence_of :media
+ def calculated_price
+ # FIXME: generate this based on day of week, newrelase
+ return 11
+ end
+
protected
def validate
errors.add(:video_genre, "does not exist in the database") if video_genre.nil?
--- /dev/null
+<!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>Bitem: <%= controller.action_name %></title>
+ <%= stylesheet_link_tag 'scaffold' %>
+</head>
+<body>
+
+<p style="color: green"><%= flash[:notice] %></p>
+<p style="color: red"><%= flash[:error] %></p>
+
+<%= yield %>
+
+</body>
+</html>
--- /dev/null
+<h1>Start a Purchase</h1>
+
+<p>Please read the customer's ID number off of their card and enter
+it in the box below.</p>
+
+<%= start_form_tag :action => 'customer_ok'%>
+<%= text_field 'customer_id', nil %>
+ <%= submit_tag 'Ok' %></form>
+<%= end_form_tag %>
+
--- /dev/null
+<h1>Purchase#buy</h1>
+<p>Find me in app/views/purchase/buy.rhtml</p>
--- /dev/null
+<h1>Purchase some Merchandise</h1>
+
+<p>Please read the item's ID number off of the bar code, and type it into
+the box below.</p>
+
+<%= start_form_tag :action => 'buy_validate'%>
+<%= text_field 'merchandise_id', nil %>
+ <%= submit_tag 'Ok' %></form>
+<%= end_form_tag %>
+
+
--- /dev/null
+<h1>Listing purchases</h1>
+
+<table>
+ <tr>
+ <% for column in Purchase.content_columns %>
+ <th><%= column.human_name %></th>
+ <% end %>
+ </tr>
+
+<% for purchase in @purchases %>
+ <tr>
+ <% for column in Purchase.content_columns %>
+ <td><%=h purchase.send(column.name) %></td>
+ <% end %>
+ <td><%= link_to 'Show', :action => 'show', :id => purchase %></td>
+ <td><%= link_to 'Edit', :action => 'edit', :id => purchase %></td>
+ <td><%= link_to 'Destroy', { :action => 'destroy', :id => purchase }, :confirm => 'Are you sure?', :method => :post %></td>
+ </tr>
+<% end %>
+</table>
+
+<%= link_to 'Previous page', { :page => @purchase_pages.current.previous } if @purchase_pages.current.previous %>
+<%= link_to 'Next page', { :page => @purchase_pages.current.next } if @purchase_pages.current.next %>
+
+<br />
+
+<%= link_to 'New purchase', :action => 'new' %>
--- /dev/null
+<h1>Purchase Menu</h1>
+
+<ul>
+ <li>Customer ID: <%= @customer.id %></li>
+ <li>Customer Name: <%= @customer.name %></li>
+ <li>Total Price: <%= @total_price %></li>
+</ul>
+
+<ul>
+ <li><%=link_to 'Rent an Item', :action => 'rent_begin' %></li>
+ <li><%=link_to 'Buy Merchandise', :action => 'buy_begin' %></li>
+</ul>
+
+<%=link_to 'End Purchase', :action => 'index' %>
--- /dev/null
+<h1>Purchase#rent</h1>
+<p>Find me in app/views/purchase/rent.rhtml</p>
--- /dev/null
+<h1>Check out a Rentable Item</h1>
+
+<p>Please read the item's ID number off of the bar code, and type it into
+the box below.</p>
+
+<%= start_form_tag :action => 'rent_validate'%>
+<%= text_field 'rentable_id', nil %>
+ <%= submit_tag 'Ok' %></form>
+<%= end_form_tag %>
+
--- /dev/null
+class CreateRentablePurchases < ActiveRecord::Migration
+ def self.up
+ end
+
+ def self.down
+ end
+end
--- /dev/null
+class CreateMerchandisePurchases < ActiveRecord::Migration
+ def self.up
+ end
+
+ def self.down
+ end
+end
--- /dev/null
+class RemovePurchaseDueDate < ActiveRecord::Migration
+ def self.up
+ remove_column :purchases, :due_date
+ end
+
+ def self.down
+ add_column :purchases, :due_date, :date
+ end
+end
# migrations feature of ActiveRecord to incrementally modify your database, and
# then regenerate this schema definition.
-ActiveRecord::Schema.define(:version => 16) do
+ActiveRecord::Schema.define(:version => 19) do
create_table "bitems", :force => true do |t|
t.column "customer_id", :integer, :null => false
t.column "name", :string, :null => false
end
+ create_table "merchandise_purchases", :force => true do |t|
+ end
+
create_table "merchandises", :force => true do |t|
t.column "name", :string, :null => false
t.column "quantity", :integer, :default => 0, :null => false
t.column "type", :string
t.column "customer_id", :integer
t.column "date", :date
- t.column "price", :decimal, :precision => 8, :scale => 2, :default => 0.0
+ t.column "price", :decimal, :default => 0.0
t.column "rentable_id", :integer
- t.column "due_date", :date
t.column "merchandise_id", :integer
t.column "quantity", :integer
end
t.column "platform", :integer
end
+# Could not dump table "sqlite_sequence" because of following StandardError
+# Unknown type '' for column 'name'
+
create_table "videogenres", :force => true do |t|
t.column "name", :string, :null => false
end
--- /dev/null
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
--- /dev/null
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+one:
+ id: 1
+two:
+ id: 2
--- /dev/null
+require File.dirname(__FILE__) + '/../test_helper'
+require 'purchase_controller'
+
+# Re-raise errors caught by the controller.
+class PurchaseController; def rescue_action(e) raise e end; end
+
+class PurchaseControllerTest < Test::Unit::TestCase
+ def setup
+ @controller = PurchaseController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
--- /dev/null
+require File.dirname(__FILE__) + '/../test_helper'
+
+class MerchandisePurchaseTest < Test::Unit::TestCase
+ fixtures :merchandise_purchases
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
--- /dev/null
+require File.dirname(__FILE__) + '/../test_helper'
+
+class RentablePurchaseTest < Test::Unit::TestCase
+ fixtures :rentable_purchases
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end