-
Notifications
You must be signed in to change notification settings - Fork 1
/
models.rb
114 lines (88 loc) · 2.84 KB
/
models.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
require 'active_record'
require 'logger'
require_relative 'exceptions'
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => "db/tradethem.sqlite3"
)
ActiveRecord::Base.logger = Logger.new("log/db.txt")
class Player < ActiveRecord::Base
has_many :portfolio_items
has_many :companies, :through => :portfolio_items
validates_presence_of :username, :cash
validates_numericality_of :cash
def buy!(tx)
self.cash -= tx.amount
raise InsufficentCashError.new(self, tx) if self.cash < 0 #custom exception
stock = self.portfolio_items.select {|i| i.company_id == tx.company_id}.first
if stock.nil?
#new stock in portfolio
self.portfolio_items.create!(:company_id => tx.company_id, :quantity => tx.quantity)
else
#add to portfolio
stock.quantity += tx.quantity
stock.save!
end
self.save!
end
def sell!(tx)
#remove from portfolio
stock = self.portfolio_items.select {|i| i.company_id == tx.company_id}.first
#can't sell what you don't have
raise InsufficientStockError.new(self, tx) if stock.nil?
raise InsufficientStockError.new(self, tx) if stock.quantity < tx.quantity
stock.quantity -= tx.quantity
stock.save!
self.cash += tx.amount
self.save!
end
def shares_in(symbol)
company = Company.find_by_symbol(symbol)
return nil if company.nil?
self.portfolio_items.find_by_company_id(company.id)
end
end
class Company < ActiveRecord::Base
validates_presence_of :symbol, :price
validates_uniqueness_of :symbol
validates_numericality_of :price
end
#purchase_price doesn't work for multiple purchases!!!
class PortfolioItem < ActiveRecord::Base
belongs_to :player
belongs_to :company
validates_presence_of :player_id, :company_id, :quantity
validates_uniqueness_of :company_id, :scope => :player_id
end
class Transaction < ActiveRecord::Base
belongs_to :company
belongs_to :buyer, :class_name => 'Player'
belongs_to :seller, :class_name => 'Player'
validates_presence_of :company, :price, :quantity
scope :completed, where(:completed => true)
scope :not_completed, where(:completed => false)
scope :active, where("expiration_date > ?", Time.now)
def amount
self.price * self.quantity
end
def complete!(player)
#already have half the transaction - update tx
if self.type == "BuyTransaction"
self.seller = player
else
self.buyer = player
end
ActiveRecord::Base.transaction do
#Update portfolios of buyer AND seller
self.buyer.buy!(self)
self.seller.sell!(self)
#update company price
self.company.update_attributes! :price => self.price
#mark transaction as executed
self.update_attributes! :completed => true
end
end
end
class BuyTransaction < Transaction; end
class SellTransaction < Transaction; end
#ADD Company total_shares (?)