class Promo::Promocode
Constants
- STATUS
- TYPE
Public Class Methods
generate(options={})
click to toggle source
Objects must always be created through generate method instead using new. here you may define some options:
options.multiple: false options.quantity: 1 options.type: :percentage options.status: :valid options.expires: 4.weeks options.code: SecureRandom.hex(4) options.product: Some model with has_many :promocodes, as: :product options.product_type: Associate the promocode with a class of product (any product of that class)
# File lib/promo/promocode.rb, line 33 def self.generate(options={}) options[:multiple] ||= false options[:quantity] ||= 1 options[:quantity] = 1 if options[:quantity].to_i <= 0 options[:promo_type] ||= TYPE[:percentage] options[:status] ||= STATUS[:valid] options[:expires] ||= Time.now + 4.weeks if options[:code].blank? options[:code] = generate_code generated_code = true else generated_code = false options[:code] = generate_code(0,options[:code]) end multiple = options[:multiple] options.delete(:multiple) if multiple ret = [] many = options[:quantity].to_i options[:quantity] = 1 many.times do |item| opt = options.dup opt[:code] = generate_code if generated_code opt[:code] = generate_code(0,options[:code]+item.to_s) if !generated_code ret << create!(opt) end return ret end create!(options) end
generate_code(size=4,code="")
click to toggle source
Generate random codes
# File lib/promo/promocode.rb, line 140 def self.generate_code(size=4,code="") code = SecureRandom.hex(size) if code.empty? code = code+SecureRandom.hex(size) unless code.empty? # Validates if the code is already created, then add something to the name if Promo::Promocode.where(code: code).first code = code+SecureRandom.hex(1) end code end
Public Instance Methods
has_product?()
click to toggle source
# File lib/promo/promocode.rb, line 85 def has_product? !self.product.nil? end
invalidate!()
click to toggle source
# File lib/promo/promocode.rb, line 79 def invalidate! update_attributes(status: STATUS[:invalid], used_at: Time.now) end
is_expired?()
click to toggle source
# File lib/promo/promocode.rb, line 97 def is_expired? return true if self.status == STATUS[:expired] return false if self.expires > Time.now update_attribute(:status, STATUS[:expired]) true end
is_fixed_value?()
click to toggle source
# File lib/promo/promocode.rb, line 93 def is_fixed_value? self.promo_type == TYPE[:fixed_value] end
is_percentage?()
click to toggle source
# File lib/promo/promocode.rb, line 89 def is_percentage? self.promo_type == TYPE[:percentage] end
is_valid?(options={})
click to toggle source
Validates the use of this promocode Options:
product_list: Array with products, mandatory when the promocode is associated with a specific product or a specific category of products
# File lib/promo/promocode.rb, line 110 def is_valid?(options={}) raise UsedPromocode.new 'promocode.messages.already_used' if self.status == STATUS[:used] raise InvalidPromocode.new 'promocode.messages.invalid' if self.status != STATUS[:valid] raise ExpiredPromocode.new 'promocode.messages.expired' if is_expired? # Validating use with a specific product associated if self.has_product? logger.debug "#------------ Promocode associated with a product" raise InvalidPromocode.new 'promocode.messages.invalid_use' if options[:product_list].nil? if self.product && !options[:product_list].include?(self.product) logger.debug "#--------------- Product associated not found on the list" raise InvalidPromoProduct.new 'promocode.messages.not_valid_for' end end # Validating use with when a class of product is associated with the promocode # not a specific product (no product_id defined) if self.product_id.nil? && !self.product_type.nil? logger.debug "#------------ Promocode associated with a class" raise InvalidPromocode.new 'promocode.messages.invalid_use' if options[:product_list].nil? if options[:product_list].none? { |p| p.class.to_s == self.product_type } logger.debug "#--------------- Class associated not found on the list" raise InvalidPromoProduct.new 'promocode.messages.must_have_course' end end # Returns the promocode if it's valid self end
use(options={})
click to toggle source
# File lib/promo/promocode.rb, line 69 def use (options={}) is_valid? options self.used += 1 self.status = STATUS[:used] if self.quantity == self.used self.used_at = Time.now save self end