Skip to content

Instantly share code, notes, and snippets.

@xenda
Created January 12, 2010 23:43
Show Gist options
  • Save xenda/275765 to your computer and use it in GitHub Desktop.
Save xenda/275765 to your computer and use it in GitHub Desktop.
class Customer < ActiveRecord::Base
attr_accessible :name, :customer_code
has_many :payments
has_many :orders
def place_order(line_items = [])
self.orders.create.fill_with_products(line_items)
end
def process_order(order,employee)
employee.process(order)
end
def pay_bill(employee,payment,amount)
employee.process_payment(payment,amount)
end
end
class Payment < ActiveRecord::Base
attr_accessible :customer_id, :order_id, :employee_id :amount
belongs_to :order
belongs_to :customer
belongs_to :employee
def pay(amount)
#PROCESS PAYMENT (Payment Gateway?)
if self.order.completely_paid?
self.order.mark_as_paid
self.order.ship_to(customer)
self.order.save
end
end
end
class Employee < ActiveRecord::Base
attr_accessible :name, :store_credentials, :company_id
belongs_to :company
has_many :orders
def process(order)
#HANDLES SETTING IT UP, ADDING ADDITIONAL INFORMATION, ETC
end
def process_payment(payment, amount)
payment.pay(amount)
end
def delivers_to(customer)
# HANDLES SENDING THE GOOD (tangible or intangible)
# Though on a real life example I'd set up this to a queue
end
end
class Order < ActiveRecord::Base
attr_accessible :customer_id, :employee_id, :total, :status, :order_details_count, :code, :active
has_many :line_items
has_many :products, :through => :line_items
has_many :payments
belongs_to :employee
belongs_to :customer
# Active is not an state since you could have something like an active order which have been revoked, or returned
ORDER_STATES = %w(unpaid paid revoked cancelled)
named_scope :unpaid, :conditions=>[:status=>ORDER_STATES[0]]
named_scope :active, :conditions=>[:active=>true]
def initialize
self.status = ORDER_STATES[0]
end
# Assumption: Orders are created after checking out some kind of shopping cart
def fill_with_products(line_items)
line_items.each do |line_item|
self.create_items.build(line_item)
end
self.total = self.line_items.inject(0){|sum,q| sum + (q*price + q.quantity)}
save
end
def mark_as_paid(customer_id)
self.status = ORDER_STATES[1]
self.mark_as_active
end
def mark_as_active
#extracted since it could have more logic here
self.active = true
end
def completely_paid?
total == self.payments.inject(0)(&:amount)
end
def ship_to(customer)
employee.delivers_to(customer)
end
end
class LineItem < ActiveRecord::Base
attr_accessible :order_id, :product_id
belongs_to :order
belongs_to :product
end
# Separating the model in two helps us setting up different product stocks for different stores, for example
class Item < ActiveRecord::Base
attr_accessible :product_id,:quantity, :store_id
belongs_to :product
end
class Product < ActiveRecord::Base
attr_accessible :name, :code, :description, :type, :size
validate :correct_size_for_type
PRODUCT_TYPES = ['iced drink', 'hot drink', 'beer']
PRODUCT_SIZES = %w(small medium large pitcher)
def beer?
self.type == PRODUCT_TYPES[2]
end
def pitcher?
self.size == PRODUCT_SIZES[3]
end
def correct_size_for_type
errors.add_to_base("For beer only") if self.pitcher? and not self.beer?
end
end
class Company < ActiveRecord::Base
attr_accessible :name, :size
attr_accessor :total_revenue
has_many :employees
has_many :orders, :through => :employees
def total_revenue
@total_revenue ||= self.orders.sum(&:total)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment