Class: Gemgento::PriceRule
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Gemgento::PriceRule
- Defined in:
- app/models/gemgento/price_rule.rb
Overview
Class Method Summary collapse
-
.calculate_price(product, user_group = nil, store = nil) ⇒ Float
Calculate a product price based on PriceRules.
-
.first_to_expire(product, user_group, store) ⇒ DateTime?
Get the earliest date and time that a price rule will expire for a given product.
-
.meets_attribute_condition?(condition, product, store) ⇒ Boolean
Determines if a product meets an attribute based condition.
-
.meets_attribute_set_condition?(condition, product) ⇒ Boolean
Determines if a product meets an attribute set based condition.
-
.meets_category_condition?(condition, product, store) ⇒ Boolean
Determines if a product meets a category based condition.
-
.meets_condition?(condition, product, store) ⇒ Boolean
Determines if the condition is met.
-
.meets_condition_combine?(condition, product, store) ⇒ Boolean
Determines if the combined child conditions are met.
-
.meets_condition_product?(condition, product, store) ⇒ Boolean
Determines if the product conditions are met.
Instance Method Summary collapse
-
#calculate(price) ⇒ Object
Calculate the discount based on rule actions.
-
#is_valid?(product, user_group, store) ⇒ Boolean
Determines if the rule is valid for a product.
Class Method Details
.calculate_price(product, user_group = nil, store = nil) ⇒ Float
Calculate a product price based on PriceRules.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'app/models/gemgento/price_rule.rb', line 21 def self.calculate_price(product, user_group = nil, store = nil) store ||= Store.current price = product.attribute_value('price', store).to_f user_group ||= UserGroup.find_by(magento_id: 0) PriceRule.active.each do |price_rule| if price_rule.is_valid?(product, user_group, store) price = price_rule.calculate(price) return price if price_rule.stop_rules_processing? end end return price end |
.first_to_expire(product, user_group, store) ⇒ DateTime?
Get the earliest date and time that a price rule will expire for a given product.
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'app/models/gemgento/price_rule.rb', line 232 def self.first_to_expire(product, user_group, store) expires_at = nil PriceRule.active.each do |price_rule| next if price_rule.to_date.nil? if price_rule.is_valid?(product, user_group, store) if expires_at.nil? || price_rule.to_date.end_of_day < expires_at expires_at = price_rule.to_date.end_of_day end end end return expires_at end |
.meets_attribute_condition?(condition, product, store) ⇒ Boolean
Determines if a product meets an attribute based condition.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'app/models/gemgento/price_rule.rb', line 188 def self.meets_attribute_condition?(condition, product, store) return false unless attribute = ProductAttribute.find_by(code: condition['attribute']) product_value = product.attribute_value(attribute.code, store).to_s.downcase if attribute.frontend_input == 'select' return false unless option = attribute..find_by(value: condition['value'], store: store) condition_value = option.label.downcase else condition_value = condition['value'].downcase end case condition['operator'] when '==' # is return product_value == condition_value when '!=' # is not return product_value != condition_value when '>=' # equals or greater than return product_value >= condition_value when '<=' # equals or less than return product_value <= condition_value when '>' # greater than return product_value > condition_value when '<' # less than return product_value < condition_value when '{}' # contains return product_value.include?(condition_value) when '!{}' # does not contain return !product_value.include?(condition_value) when '()' # is one of return condition_value.split(',').map(&:strip).include?(product_value) when '!()' # is not one of return !condition_value.split(',').map(&:strip).include?(product_value) else return false end end |
.meets_attribute_set_condition?(condition, product) ⇒ Boolean
Determines if a product meets an attribute set based condition.
168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'app/models/gemgento/price_rule.rb', line 168 def self.meets_attribute_set_condition?(condition, product) magento_attribute_set_id = product.product_attribute_set.magento_id condition_attribute_set_id = condition['value'].to_i case condition['operator'] when *%w[== {} ()] return magento_attribute_set_id == condition_attribute_set_id when *%w[!= !{} !()] return magento_attribute_set_id != condition_attribute_set_id else return false end end |
.meets_category_condition?(condition, product, store) ⇒ Boolean
Determines if a product meets a category based condition.
149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'app/models/gemgento/price_rule.rb', line 149 def self.meets_category_condition?(condition, product, store) magento_category_ids = ProductCategory.where(product: product, store: store).includes(:category).map{ |pc| pc.category.magento_id unless pc.category.nil? }.uniq condition_category_ids = condition['value'].split(',').map(&:to_i) case condition['operator'] when *%w[== {} ()] return (magento_category_ids & condition_category_ids).any? when *%w[!= !{} !()] return (magento_category_ids & condition_category_ids).empty? else return false end end |
.meets_condition?(condition, product, store) ⇒ Boolean
Determines if the condition is met.
83 84 85 86 87 88 89 90 91 |
# File 'app/models/gemgento/price_rule.rb', line 83 def self.meets_condition?(condition, product, store) if condition['type'] == 'catalogrule/rule_condition_combine' return meets_condition_combine?(condition, product, store) elsif condition['type'] == 'catalogrule/rule_condition_product' return meets_condition_product?(condition, product, store) else return false # non-determinable condition type end end |
.meets_condition_combine?(condition, product, store) ⇒ Boolean
Determines if the combined child conditions are met.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'app/models/gemgento/price_rule.rb', line 99 def self.meets_condition_combine?(condition, product, store) return true if condition['conditions'].nil? condition['conditions'].each do |child_condition| if meets_condition?(child_condition, product, store) # the condition has been met if condition['aggregator'] == 'all' && condition['value'] == '0' # all conditions not met return false elsif condition['aggregator'] == 'any' && condition['value'] == '1' # any condition met return true end else # the condition has not be met if condition['aggregator'] == 'all' && condition['value'] == '1' # all conditions met return false elsif condition['aggregator'] == 'any' && condition['value'] == '0' # any condition not be met return true end end end if condition['aggregator'] == 'all' # all conditions evaluated and all met return true else # all conditions evaluated and none met return false end end |
.meets_condition_product?(condition, product, store) ⇒ Boolean
Determines if the product conditions are met.
133 134 135 136 137 138 139 140 141 |
# File 'app/models/gemgento/price_rule.rb', line 133 def self.meets_condition_product?(condition, product, store) if condition['attribute'] == 'category_ids' return meets_category_condition?(condition, product, store) elsif condition['attribute'] == 'attribute_set_id' return meets_attribute_set_condition?(condition, product) else return meets_attribute_condition?(condition, product, store) end end |
Instance Method Details
#calculate(price) ⇒ Object
Calculate the discount based on rule actions.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'app/models/gemgento/price_rule.rb', line 62 def calculate(price) case self.simple_action when 'to_fixed' return [self.discount_amount.to_f, price].min when 'to_percent' return price * self.discount_amount.to_f / 100 when 'by_fixed' return [0, price - self.discount_amount.to_f].max when 'by_percent' return price * (1 - self.discount_amount.to_f / 100) else return price end end |
#is_valid?(product, user_group, store) ⇒ Boolean
Determines if the rule is valid for a product.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'app/models/gemgento/price_rule.rb', line 42 def is_valid?(product, user_group, store) if !self.is_active? return false elsif !self.stores.include?(store) return false elsif !self.user_groups.include?(user_group) return false elsif !self.from_date.nil? && Date.today < from_date return false elsif !self.to_date.nil? && Date.today > to_date return false else return PriceRule.meets_condition?(self.conditions, product, store) end end |