Add Income tracking to the Purchase System
[cs356-p2-videostore.git] / app / controllers / purchase_controller.rb
1 class PurchaseController < ApplicationController
2   layout "admin"
3
4   # Make sure that a user logs in before doing any action here
5   before_filter :authorize, :except => [:filter, :filterbycust, :filterbydate, :filterbytype, :list, :index, :income]
6   before_filter :manager, :only => [:filter, :filterbycust, :filterbydate, :filterbytype, :list, :index, :income]
7
8   def index
9     render :action => 'index'
10   end
11
12   def list
13     @purchase_pages, @purchases = paginate :purchases, :per_page => 100
14   end
15
16   def filter
17     if request.post?
18       type = params[:type]
19       id = params[:id]
20
21       case type
22         when :customer, "customer"
23           redirect_to :action => 'filterbycust', :id => id
24         when :date, "date"
25           date = Date.new id['(1i)'].to_i, id['(2i)'].to_i, id['(3i)'].to_i
26           redirect_to :action => 'filterbydate', :id => date.to_s
27       end
28     else
29       @type = params[:type]
30       if @type.nil?
31         @type = "all"
32       end
33       render :action => 'filter'
34     end
35   end
36
37   def filterbycust
38     @purchase_pages, @purchases = paginate :purchases, :per_page => 100, :conditions => ["customer_id = ?", params[:id]]
39     render :action => 'list'
40   end
41
42   def filterbydate
43     @purchase_pages, @purchases = paginate :purchases, :per_page => 100, :conditions => ["date = ?", params[:id]]
44     render :action => 'list'
45   end
46
47   def filterbytype
48     @purchase_pages, @purchases = paginate :purchases, :per_page => 100, :conditions => ["type = ?", params[:id]]
49     render :action => 'list'
50   end
51
52   def income
53     if request.post?
54       # Find all purchases between :begin_date, and :end_date and sum up the total income
55       # from RentablePurchases, MerchandisePurchases. Print both sums, and the total sum.
56       @begin_date = Date.new params[:begin_date]['(1i)'].to_i, params[:begin_date]['(2i)'].to_i, params[:begin_date]['(3i)'].to_i
57       @end_date = Date.new params[:end_date]['(1i)'].to_i, params[:end_date]['(2i)'].to_i, params[:end_date]['(3i)'].to_i
58       merchandises = MerchandisePurchase.find(:all, :conditions => ['date >= ? AND date <= ?', @begin_date, @end_date])
59       rentables = RentablePurchase.find(:all, :conditions => ['date >= ? AND date <= ?', @begin_date, @end_date])
60       late_fees = LateFeePurchase.find(:all, :conditions => ['date >= ? AND date <= ?', @begin_date, @end_date])
61
62       @merch_count = merchandises.length
63       @rent_count = rentables.length
64       @late_count = late_fees.length
65       @merch_sum = merchandises.sum(&:price)
66       @rent_sum = rentables.sum(&:price)
67       @late_sum = late_fees.sum(&:price)
68       @total = @merch_sum + @rent_sum + @late_sum
69       render :action => 'income_results'
70     else
71       render :action => 'income'
72     end
73   end
74
75   def begin
76     # enter a customer id here
77     render :action => 'begin'
78     session[:total] = 0.00
79     session[:items] = []
80   end
81
82   def reciept
83     # Save important data, since we're gonna wipe it out now
84     @customer = Customer.find_by_id(session[:customer_id])
85     @debt = @customer.debt
86     @total = session[:total] + @debt
87     @items = session[:items]
88     @time = Time.now
89
90     # Record a Late Fee Payment if we need to
91     if @debt
92       purchase = LateFeePurchase.new
93       purchase.customer = @customer
94       purchase.date = Time.now.to_date
95       purchase.price = @debt
96       purchase.save
97     end
98
99     # Set the customer's debt to $0.00, she paid us
100     @customer = Customer.find_by_id(session[:customer_id])
101     @customer.debt = 0.00
102     @customer.save
103
104     # Wipe session data
105     session[:customer_id] = nil
106     session[:total] = nil
107     session[:items] = nil
108
109     # Show the reciept
110     render :action => 'reciept'
111   end
112
113   def customer_ok
114     if Customer.find_by_id(params[:customer_id])
115       session[:customer_id] = params[:customer_id]
116       redirect_to :action => :menu
117     else
118       flash[:notice] = "Customer ID is invalid"
119       redirect_to :action => :begin
120     end
121   end
122
123   def menu
124     @customer = Customer.find_by_id(session[:customer_id])
125     @total_price = session[:total]
126     @items = session[:items]
127     render :action => 'menu'
128   end
129
130   def rent
131     if request.post?
132       @customer = Customer.find_by_id(session[:customer_id])
133       @rentable = Rentable.find_by_id(params[:rentable_id])
134
135       if @customer.nil?
136         flash[:notice] = "Customer ID is invalid"
137         redirect_to :action => :begin
138         return
139       end
140
141       if @rentable.nil?
142         flash[:notice] = "Rentable ID is invalid"
143         redirect_to :action => :rent
144         return
145       end
146
147       if @rentable.checkedout?
148         flash[:notice] = "This #{@rentable.type} is already checked out!"
149         redirect_to :action => :rent
150         return
151       end
152
153       # Check Rentable Policies
154       @maxvideos = RentablePolicy.find_by_name("MaxVideos")
155       if @rentable.class == Video and @customer.checked_out_videos >= @maxvideos.value
156         flash[:notice] = "#{@maxvideos.description} LIMIT REACHED"
157         redirect_to :action => :rent
158         return
159       end
160
161       @maxgames = RentablePolicy.find_by_name("MaxGames")
162       if @rentable.class == Game and @customer.checked_out_games >= @maxgames.value
163         flash[:notice] = "#{@maxgames.description} LIMIT REACHED"
164         redirect_to :action => :rent
165         return
166       end
167
168       @maxoverduevideos = RentablePolicy.find_by_name("MaxOverdueVideos")
169       if @rentable.class == Video and @customer.overdue_videos >= @maxoverduevideos.value
170         flash[:notice] = "#{@maxoverduevideos.description} LIMIT REACHED"
171         redirect_to :action => :rent
172         return
173       end
174
175       @maxoverduegames = RentablePolicy.find_by_name("MaxOverdueGames")
176       if @rentable.class == Game and @customer.overdue_games >= @maxoverduegames.value
177         flash[:notice] = "#{@maxoverduegames.description} LIMIT REACHED"
178         redirect_to :action => :rent
179         return
180       end
181
182       # Check out the item
183       checkout = Coitem.new
184       checkout.customer = @customer
185       checkout.rentable = @rentable
186       checkout.out_date = Time.now.to_date
187       checkout.due_date = @rentable.due_date
188       checkout.save!
189
190       # Actually record the purchase
191       purchase = RentablePurchase.new
192       purchase.customer = @customer
193       purchase.date = Time.now.to_date
194       purchase.price = @rentable.calculated_price
195       purchase.rentable = @rentable
196       purchase.save!
197
198       # Add to session variables
199       session[:total] += @rentable.calculated_price
200       session[:items].push @rentable
201
202       flash[:notice] = "Successfully made purchase"
203       redirect_to :action => :menu
204     else
205       render :action => 'rent'
206     end
207   end
208
209   def buy_merch
210     if request.post?
211       @customer = Customer.find_by_id(session[:customer_id])
212       @merchandise = Merchandise.find_by_id(params[:merchandise_id])
213     
214       if @customer.nil?
215         flash[:notice] = "Customer ID is invalid"
216         redirect_to :action => :begin
217         return
218       end
219
220       if @merchandise.nil?
221         flash[:notice] = "Merchandise ID is invalid"
222         redirect_to :action => :buy_merch
223         return
224       end
225
226       if @merchandise.quantity < 1
227         flash[:notice] = "The system thinks we are out of this merchandise item!"
228         redirect_to :action => :buy_merch
229         return
230       end
231
232       # Actually record the purchase
233       purchase = MerchandisePurchase.new
234       purchase.customer = @customer
235       purchase.date = Time.now.to_date
236       purchase.price = @merchandise.price
237       purchase.merchandise = @merchandise
238       purchase.quantity = 1
239       @merchandise.quantity -= 1
240
241       # Add to session variables
242       session[:total] += @merchandise.price
243       session[:items].push @merchandise
244
245       # Save both the merchandise (we changed the quantity) and the purchase to the log
246       @merchandise.save!
247       purchase.save!
248
249       flash[:notice] = "Successfully made purchase"
250       redirect_to :action => :menu
251     else
252       render :action => 'buy_merch'
253     end
254   end
255
256 end