Updated Rake tasks and test, spec to reflect change in how Merb environments
[merb_mart.git] / app / models / promotion.rb
blob896c195a1b9aa03dde832e6c6518e0d776aec0cb
1 # Promotions allow discounts to be applied to orders, and
2 # have the ability to add items to an order as well.
5 class Promotion
6   
7   include DataMapper::Persistable
9   TYPES = {
10     'Dollars' => 0,
11     'Percent of total order' => 1,
12     'Buy [n] get 1 free' => 2
13   }
14   # Associations
15   has_many :orders
16   belongs_to :item
17   
18   # Properties
19   property :code,            :string,   :length => 15, :default => "",  :nullable => false
20   property :discount_type,   :integer,                 :default => 0,   :nullable => false
21   property :discount_amount, :float,                   :default => 0.0, :nullable => false
22   property :start,           :datetime,                                 :nullable => false
23   property :end,             :datetime,                                 :nullable => false
24   property :minimum_cart_value, :float
25   property :description,      :string,                  :default => "", :nullable => false
26   
27   # Validation
28   #validates_presence_of :code, :discount_amount, :discount_type, :description
29   validates_uniqueness_of :code
30   validates_numericality_of :discount_amount
31   
32   before_save :clean_code
33   
34   def clean_code
35     self.code.gsub!(' ', '')
36   end
37   
38   # Makes sure if 'buy n get one free' discount type that
39   # a product is selected.
40   def validate
41     if self.discount_type == 2 && self.item_id.nil?
42       errors.add(:item_id, "Please add an item for the 'Buy [n] get 1 free' promotion")
43     end
44   end
45   
46   # Generates a 15 character alphanumeric code
47   # that we use to track affiliates and promotions.
48   #
49   def self.generate_code(size=15)
50     # characters used to generate affiliate code
51     chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" 
52     # create a new record object to satisfy while loop initially
53     record = Promotion.new
54     # loop through, creating random affiliate codes until
55     # we create one that doesn't exist in the db
56     while record        
57       test_code = "" 
58       srand
59       size.times do
60         pos = rand(chars.length)
61         test_code += chars[pos..pos]
62       end
63       # find any affiliates with this same code string
64       # if none are found the while loop exits
65       record = first(:code => test_code)
66     end
67     # return our random code
68     return test_code
69   end
70   
71   # Lets us know if any promotions are active.
72   #
73   def self.any_active?
74     !Promotion.find(
75       :first, 
76       :conditions => "NOW() BETWEEN start AND end"
77     ).nil?
78   end
79   
80   def is_active?
81     Time.now.between?(self.start, self.end)
82   end
83   
84   # Setter for product name. Uses suggestion JS and pop-up.
85   #
86   # We only really use the first item, which is the ID to look
87   # up the product.
88   def product_name=(name)
89     item = StoreItem.find_by_code(name.split(':')[0])
90     if !item
91       self.item_id = nil
92     else
93       self.item_id = item.id
94     end
95   end
96   
97 end