Class: Coupon
Overview
== Schema Information
Table name: coupons
Database name: primary
id :integer not null, primary key
allow_non_domestic_shipping :boolean
allow_oversized_items :boolean default(FALSE), not null
amount_goods :decimal(10, 2)
amount_services :decimal(10, 2)
amount_services_ar :float is an Array
amount_shipping :decimal(10, 2)
auto_apply :boolean default(FALSE), not null
auto_buying_group_exclude :boolean
buying_group_ids_exclude :boolean default(FALSE), not null
calculation_type_goods :string(5)
calculation_type_services :string(5)
calculation_type_shipping :string(5)
code :string(255)
description :text
details :text
effective_date :date
exclude_opportunity_reception_types_filters :boolean default(FALSE), not null
exclude_opportunity_types_filters :boolean default(FALSE), not null
exclude_order_reception_types_filters :boolean default(FALSE), not null
exclude_order_types_filters :boolean default(FALSE), not null
exclude_state_codes :boolean default(FALSE), not null
exclusion_level :enum default("not_exclusive"), not null
expiration_date :date
first_time_customers_only :boolean default(FALSE), not null
is_inactive :boolean default(FALSE), not null
last_used_at :datetime
legacy_amount_goods :string(100)
legacy_amount_services :string(100)
legacy_amount_shipping :string(100)
opportunity_reception_types_filter :string default([]), is an Array
opportunity_types_filter :string default([]), is an Array
order_reception_types_filter :string(255) default([]), is an Array
order_types_filter :string(255) default([]), is an Array
p5 :string(100)
p6 :string(100)
position :integer
profile_ids_exclude :boolean
promo_page_content_html :text
promo_tracking :boolean default(FALSE), not null
role_ids_restriction :integer default([]), is an Array
sale_page_position :integer default(0), not null
serial_numbers_only :boolean default(FALSE), not null
ships_economy_only :boolean default(FALSE), not null
single_use_per_customer :boolean default(FALSE), not null
state_codes :string(255) default([]), is an Array
store_id_restriction :integer
tier :integer default(3), not null
title :text
type :string(50)
created_at :datetime
updated_at :datetime
auto_apply_customer_filter_id :integer
creator_id :integer
customer_filter_id :integer
image_id :integer
publication_id :integer
source_id :integer
updater_id :integer
Indexes
by_auto_ap_st_codes (auto_apply,state_codes)
idx_code (code)
idx_type_is_inactive (type,is_inactive)
index_coupons_on_auto_apply_customer_filter_id (auto_apply_customer_filter_id)
index_coupons_on_customer_filter_id (customer_filter_id)
index_coupons_on_image_id (image_id)
index_coupons_on_position (position)
index_coupons_on_single_use_per_customer (single_use_per_customer)
index_coupons_on_type_and_id (type,id)
Foreign Keys
coupons_auto_apply_customer_filter_id_fk (auto_apply_customer_filter_id => customer_filters.id)
coupons_customer_filter_id_fk (customer_filter_id => customer_filters.id)
fk_rails_... (image_id => digital_assets.id)
Defined Under Namespace
Classes: ApplyCoupon, CatalogItemPricing, DeleteDiscount, ItemizableDiscountCalculator, LineItemDiscountAllocator, MsrpAllocator, OverlappingPromoValidator, PromoItemSync, Qualifier, QueryBuilder, Tier1BaseItemPricing, Tier2ProgramPricing, Tier3PromotionalPricing
Constant Summary
collapse
- INSTRUCTIONS =
'Placeholder'.freeze
- VALID_PRICE_MATRIX_CALCULATIONS =
Valid price matrix calculations.
['%', '$', 'DP', 'MP'].freeze
- FIXED_DOLLAR_CALCULATIONS =
Fixed dollar calculations.
{
'Flat Amount Off' => '$',
'Adjustable (+ or -)' => '?',
'Adjustable (Discount Only)' => '-?',
'Adjustable (Charge Only)' => '+?'
}.freeze
- FIXED_DOLLAR_CALCULATIONS_TYPES =
Recognised fixed dollar calculations types.
FIXED_DOLLAR_CALCULATIONS.map { |_k, v| v }
- CORE_CALCULATIONS =
FIXED_DOLLAR_CALCULATIONS.merge({
'Percentage Off' => '%',
'Flat Amount Off Per Unit' => '$1',
'Percentage Off MSRP' => '%M',
'Percentage Off Catalog Price with VAT' => '%V',
'Percentage Off per Min Qty Met' => '%1',
'Force Discount Unit Price' => 'DP',
'Force MSRP' => 'MP',
'Promo Matrix' => 'MX'
})
- CALCULATION_TYPES_GOODS =
CORE_CALCULATIONS.merge({
'Sq.Ft Multiplier for MSRP' => 'SF',
'Linear Ft Multiplier for MSRP' => 'LF',
'Sq.Ft Multiplier after base discount' => 'SD',
'Linear Ft Multiplier after base discount' => 'LD'
})
- CALCULATION_TYPES_SERVICES =
Calculation types services.
CORE_CALCULATIONS
- CALCULATION_TYPES_SHIPPING =
Calculation types shipping.
{ 'Percentage Off' => '%', 'Flat Amount Off' => '$',
'Flat Rate Shipping' => '_R', 'Adjustable (Discount or Charge)' => '?',
'Adjustable (Discount Only)' => '-?', 'Adjustable (Charge Only)' => '+?' }.freeze
- ADJUSTABLE_CALCULATIONS =
['?', '-?', '+?'].freeze
- FREE_ONLINE_SHIPPING_COUPON_CODES =
Free online shipping coupon codes.
%w[FREEGNDONLINE FREEGNDONLINECA FREE_ECONOMY_ONLINE_USA FREE_ECONOMY_ONLINE_CAN].freeze
- FREE_ECONOMY_SHIPPING_ONLINE_COUPON_CODES_BY_COUNTRY =
Free economy shipping online coupon codes by country.
{ USA: 'FREE_ECONOMY_ONLINE_USA', CAN: 'FREE_ECONOMY_ONLINE_CAN' }.freeze
- ECONOMY_SHIPPING_MATCH_CRM_COUPON_CODE =
Economy shipping match crm coupon code.
'ECONOMY_SHIPPING_MATCH_CRM'.freeze
- SKIP_BLACKLISTING_COUPON_CODES =
this blacklisting just breaks things when holding/release. Just skip for these codes!
[ECONOMY_SHIPPING_MATCH_CRM_COUPON_CODE] + FREE_ECONOMY_SHIPPING_ONLINE_COUPON_CODES_BY_COUNTRY.values
Models::Auditable::ALWAYS_IGNORED
Constants included
from Schedulable
Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
#creator, #updater
Delegated Instance Attributes
collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#sanitize_html_fragment
#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
config
#after_commit
#publish_event
Instance Attribute Details
#amount_goods_override ⇒ Object
Returns the value of attribute amount_goods_override.
145
146
147
|
# File 'app/models/coupon.rb', line 145
def amount_goods_override
@amount_goods_override
end
|
#amount_services_override ⇒ Object
Returns the value of attribute amount_services_override.
145
146
147
|
# File 'app/models/coupon.rb', line 145
def amount_services_override
@amount_services_override
end
|
#amount_shipping_override ⇒ Object
Returns the value of attribute amount_shipping_override.
145
146
147
|
# File 'app/models/coupon.rb', line 145
def amount_shipping_override
@amount_shipping_override
end
|
#serial_number ⇒ Object
Returns the value of attribute serial_number.
145
146
147
|
# File 'app/models/coupon.rb', line 145
def serial_number
@serial_number
end
|
#ship_to_continental_regions ⇒ Object
Returns the value of attribute ship_to_continental_regions.
145
146
147
|
# File 'app/models/coupon.rb', line 145
def ship_to_continental_regions
@ship_to_continental_regions
end
|
Class Method Details
.active ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are active. Active Record Scope
172
|
# File 'app/models/coupon.rb', line 172
scope :active, -> { where.not(is_inactive: true) }
|
.active_and_future ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are active and future. Active Record Scope
190
|
# File 'app/models/coupon.rb', line 190
scope :active_and_future, -> { active.where.not(effective_date: nil).where(Coupon[:effective_date].gt(Date.current)) }
|
.affect_goods ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are affect goods. Active Record Scope
194
|
# File 'app/models/coupon.rb', line 194
scope :affect_goods, -> { where.not(calculation_type_goods: nil) }
|
.affect_services ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are affect services. Active Record Scope
195
|
# File 'app/models/coupon.rb', line 195
scope :affect_services, -> { where.not(calculation_type_services: nil) }
|
.affect_shipping ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are affect shipping. Active Record Scope
196
|
# File 'app/models/coupon.rb', line 196
scope :affect_shipping, -> { where.not(calculation_type_shipping: nil) }
|
.auto_applied ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are auto applied. Active Record Scope
174
|
# File 'app/models/coupon.rb', line 174
scope :auto_applied, -> { where(auto_apply: true) }
|
.by_code ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are by code. Active Record Scope
171
|
# File 'app/models/coupon.rb', line 171
scope :by_code, -> { order(:code) }
|
.calculation_types_for_goods_select ⇒ Object
294
295
296
|
# File 'app/models/coupon.rb', line 294
def self.calculation_types_for_goods_select
CALCULATION_TYPES_GOODS.to_a.sort
end
|
.calculation_types_for_services_select ⇒ Object
298
299
300
|
# File 'app/models/coupon.rb', line 298
def self.calculation_types_for_services_select
CALCULATION_TYPES_SERVICES.to_a.sort
end
|
.calculation_types_for_shipping_select ⇒ Object
302
303
304
|
# File 'app/models/coupon.rb', line 302
def self.calculation_types_for_shipping_select
CALCULATION_TYPES_SHIPPING.to_a.sort
end
|
.coupon_type_for_select ⇒ Object
275
276
277
|
# File 'app/models/coupon.rb', line 275
def self.coupon_type_for_select
coupon_types.invert
end
|
.coupon_types ⇒ Object
271
272
273
|
# File 'app/models/coupon.rb', line 271
def self.coupon_types
['Coupon::Tier1BaseItemPricing', 'Coupon::Tier2ProgramPricing', 'Coupon::Tier3PromotionalPricing'].index_with { |t| t.constantize.friendly_type_name }
end
|
.customer_accessible ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are customer accessible. Active Record Scope
189
|
# File 'app/models/coupon.rb', line 189
scope :customer_accessible, -> { tier3.active.non_auto_applied }
|
.customer_filters_for_select ⇒ Object
314
315
316
|
# File 'app/models/coupon.rb', line 314
def self.customer_filters_for_select
CustomerFilter.joins(:coupons).order(CustomerFilter[:name]).distinct.pluck(:name, :id)
end
|
.discounted_price ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are discounted price. Active Record Scope
177
|
# File 'app/models/coupon.rb', line 177
scope :discounted_price, -> { where(amount_goods: 'DP') }
|
.exclude_ships_economy_only ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are exclude ships economy only. Active Record Scope
200
|
# File 'app/models/coupon.rb', line 200
scope :exclude_ships_economy_only, -> { where.not(ships_economy_only: true) }
|
.exclusion_level_for_select ⇒ Object
279
280
281
|
# File 'app/models/coupon.rb', line 279
def self.exclusion_level_for_select
exclusion_levels.map { |k, _v| [k.humanize, k] }
end
|
.expired ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are expired. Active Record Scope
181
|
# File 'app/models/coupon.rb', line 181
scope :expired, ->(date = Date.current) { where.not(expiration_date: nil).where(Coupon[:expiration_date].lteq(date)) }
|
.fixed_dollar ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are fixed dollar. Active Record Scope
.for_public ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are for public. Active Record Scope
183
|
# File 'app/models/coupon.rb', line 183
scope :for_public, -> { tier3.where(Coupon[:role_ids_restriction].contains([Role.find_by(name: 'customer').id]).or(Coupon[:role_ids_restriction].eq([])).or(Coupon[:role_ids_restriction].eq(nil))) }
|
.free_online_shipping ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are free online shipping. Active Record Scope
.friendly_calculation_name(calculation_type) ⇒ Object
.friendly_price_matrix_calculation_names ⇒ Object
.in_effect_on ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are in effect on. Active Record Scope
179
|
# File 'app/models/coupon.rb', line 179
scope :in_effect_on, ->(date = Date.current) { active.where(Coupon[:effective_date].eq(nil).or(Coupon[:effective_date].lteq(date))).where(Coupon[:expiration_date].eq(nil).or(Coupon[:expiration_date].gteq(date))) }
|
.inactive ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are inactive. Active Record Scope
173
|
# File 'app/models/coupon.rb', line 173
scope :inactive, -> { where(is_inactive: true) }
|
.instantiate_by_type(type) ⇒ Object
263
264
265
|
# File 'app/models/coupon.rb', line 263
def self.instantiate_by_type(type)
(coupon_types.keys & [type])[0].constantize
end
|
.msrp_price ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are msrp price. Active Record Scope
178
|
# File 'app/models/coupon.rb', line 178
scope :msrp_price, -> { where(amount_goods: %w[MP SF LF]) }
|
.non_auto_applied ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are non auto applied. Active Record Scope
175
|
# File 'app/models/coupon.rb', line 175
scope :non_auto_applied, -> { where(auto_apply: false) }
|
.not_expired ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are not expired. Active Record Scope
182
|
# File 'app/models/coupon.rb', line 182
scope :not_expired, ->(date = Date.current) { where.not(expiration_date: nil).where(Coupon[:expiration_date].gt(date)) }
|
.not_in_effect_on ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are not in effect on. Active Record Scope
180
|
# File 'app/models/coupon.rb', line 180
scope :not_in_effect_on, ->(date = Date.current) { where(Coupon[:effective_date].eq(nil).or(Coupon[:effective_date].gt(date))).where(Coupon[:expiration_date].eq(nil).or(Coupon[:expiration_date].lt(date))) }
|
.order_types_for_select ⇒ Object
267
268
269
|
# File 'app/models/coupon.rb', line 267
def self.order_types_for_select
%w[SO CO ST]
end
|
A relation of Coupons that are promo. Active Record Scope
201
|
# File 'app/models/coupon.rb', line 201
scope :promo, -> { where(promo_tracking: true) }
|
.promo_for_sale_page ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are promo for sale page. Active Record Scope
202
203
204
205
206
207
208
|
# File 'app/models/coupon.rb', line 202
scope :promo_for_sale_page, -> {
excluded_codes = []
excluded_codes << 'FREE_ECONOMY_ONLINE_USA' unless I18n.locale == :'en-US'
excluded_codes << 'FREE_ECONOMY_ONLINE_CAN' unless I18n.locale.in?(%i[en-CA fr-CA])
active.in_effect_on.where.not(code: excluded_codes).where(Coupon[:sale_page_position].gt(0)).order(sale_page_position: :asc, created_at: :desc)
}
|
A relation of Coupons that are promo matrix. Active Record Scope
187
|
# File 'app/models/coupon.rb', line 187
scope :promo_matrix, -> { where(calculation_type_goods: 'MX').or(where(calculation_type_services: 'MX')).or(where(calculation_type_shipping: 'MX')) }
|
.select_options ⇒ Object
306
307
308
|
# File 'app/models/coupon.rb', line 306
def self.select_options
order(:code).pluck(:code, :id)
end
|
.ships_economy_only ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are ships economy only. Active Record Scope
199
|
# File 'app/models/coupon.rb', line 199
scope :ships_economy_only, -> { where(ships_economy_only: true) }
|
.sorted ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are sorted. Active Record Scope
170
|
# File 'app/models/coupon.rb', line 170
scope :sorted, -> { order(Coupon[:type], Coupon[:position]) }
|
.tier1 ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are tier1. Active Record Scope
184
|
# File 'app/models/coupon.rb', line 184
scope :tier1, -> { where(type: 'Coupon::Tier1BaseItemPricing') }
|
.tier1and3 ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are tier1and3. Active Record Scope
188
|
# File 'app/models/coupon.rb', line 188
scope :tier1and3, -> { where(type: ['Coupon::Tier1BaseItemPricing', 'Coupon::Tier3PromotionalPricing']) }
|
.tier2 ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are tier2. Active Record Scope
185
|
# File 'app/models/coupon.rb', line 185
scope :tier2, -> { where(type: 'Coupon::Tier2ProgramPricing') }
|
.tier2_select_options ⇒ Object
310
311
312
|
# File 'app/models/coupon.rb', line 310
def self.tier2_select_options
tier2.order(:title).pluck(:title, :id)
end
|
.tier3 ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are tier3. Active Record Scope
186
|
# File 'app/models/coupon.rb', line 186
scope :tier3, -> { where(type: 'Coupon::Tier3PromotionalPricing') }
|
.with_economy_shipping_match_crm ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are with economy shipping match crm. Active Record Scope
.with_publication ⇒ ActiveRecord::Relation<Coupon>
A relation of Coupons that are with publication. Active Record Scope
176
|
# File 'app/models/coupon.rb', line 176
scope :with_publication, -> { where.not(publication_id: nil) }
|
Instance Method Details
#adjustable ⇒ Object
420
421
422
|
# File 'app/models/coupon.rb', line 420
def adjustable
goods_adjustable or services_adjustable or shipping_adjustable
end
|
#all_applicable_catalog_items ⇒ Object
451
452
453
454
455
456
457
458
|
# File 'app/models/coupon.rb', line 451
def all_applicable_catalog_items
item_ids = all_applicable_item_ids
catalog_ids = all_catalog_ids || []
CatalogItem.joins(:item).where(items: { id: item_ids }, catalog_id: catalog_ids).available_for_edi_feeds
end
|
#all_applicable_item_ids ⇒ Object
Returns all applicable item IDs using real-time ltree queries.
No caching needed - ltree queries are fast (~1-2ms per filter).
438
439
440
|
# File 'app/models/coupon.rb', line 438
def all_applicable_item_ids
product_filters.where(apply_discount: true).flat_map { |pf| pf.applicable_item_ids_set.to_a }.uniq
end
|
#all_catalog_ids ⇒ Object
Alias for Customer_filter#all_catalog_ids
245
|
# File 'app/models/coupon.rb', line 245
delegate :all_catalog_ids, to: :customer_filter, allow_nil: true
|
#apply_source_to_customer(customer) ⇒ Object
578
579
580
581
582
583
|
# File 'app/models/coupon.rb', line 578
def apply_source_to_customer(customer)
return unless source
customer.update_attribute!(:source_id, source_id)
end
|
#apply_source_to_opportunity(opportunity) ⇒ Object
595
596
597
598
599
|
# File 'app/models/coupon.rb', line 595
def apply_source_to_opportunity(opportunity)
return unless source && opportunity.sales_opportunity?
opportunity.update_column(:source_id, source_id)
end
|
#apply_source_to_order(order) ⇒ Object
585
586
587
588
589
590
591
592
593
|
# File 'app/models/coupon.rb', line 585
def apply_source_to_order(order)
return unless source && order&.is_sales_order?
if order.persisted?
order.update_column(:source_id, source_id)
else
order.source_id = source_id
end
end
|
#auto_apply_customer_filter ⇒ CustomerFilter
154
|
# File 'app/models/coupon.rb', line 154
belongs_to :auto_apply_customer_filter, inverse_of: :auto_apply_coupons, class_name: 'CustomerFilter', optional: true
|
#blacklistable? ⇒ Boolean
Every coupon by default is blacklistable if they are auto apply
This behavior can be overriden in each class of coupon
e.g. tier2 coupon is always true
412
413
414
415
416
417
418
|
# File 'app/models/coupon.rb', line 412
def blacklistable?
if SKIP_BLACKLISTING_COUPON_CODES.include?(code)
false
else
auto_apply
end
end
|
#coupon_active? ⇒ Boolean
354
355
356
|
# File 'app/models/coupon.rb', line 354
def coupon_active?
status == :active
end
|
#coupon_expired? ⇒ Boolean
346
347
348
|
# File 'app/models/coupon.rb', line 346
def coupon_expired?
status == :expired
end
|
#coupon_inactive? ⇒ Boolean
342
343
344
|
# File 'app/models/coupon.rb', line 342
def coupon_inactive?
status == :inactive
end
|
#coupon_not_yet_in_effect? ⇒ Boolean
350
351
352
|
# File 'app/models/coupon.rb', line 350
def coupon_not_yet_in_effect?
status == :not_yet_in_effect
end
|
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
|
# File 'app/models/coupon.rb', line 358
def coupon_promo_sync_alert
msg = nil
if coupon_active? || coupon_not_yet_in_effect?
if (missing_catalog_items = missing_catalog_items_not_in_promotion_product_filter).present?
msg = %(There are potentially #{missing_catalog_items.size} catalog items in your product filter that need to be synchronized,
run Synchronize Promo Items to correct)
elsif (missing_items = promotional_item_ids_not_in_product_filter).present?
msg = %(There are #{missing_items.size} items in your promotional catalog that are not part of your filter,
run Synchronize Promo Items to correct)
end
elsif (coupon_expired? || coupon_inactive?) && promotional_view_product_catalog_items.present?
msg = %(Coupon is inactive or expired, synchronize promo items to cleanup catalog item references)
end
msg
end
|
#coupon_serial_numbers ⇒ ActiveRecord::Relation<CouponSerialNumber>
161
|
# File 'app/models/coupon.rb', line 161
has_many :coupon_serial_numbers, dependent: :destroy, inverse_of: :coupon
|
#customer_can_apply? ⇒ Boolean
574
575
576
|
# File 'app/models/coupon.rb', line 574
def customer_can_apply?
(is_inactive != true) and (auto_apply != true) and public? and tier3?
end
|
153
|
# File 'app/models/coupon.rb', line 153
belongs_to :customer_filter, inverse_of: :coupons, optional: true
|
#customer_ids_txt ⇒ Object
566
567
568
|
# File 'app/models/coupon.rb', line 566
def customer_ids_txt
(customer_ids || []).join(',')
end
|
#customer_ids_txt=(val) ⇒ Object
562
563
564
|
# File 'app/models/coupon.rb', line 562
def customer_ids_txt=(val)
self.customer_ids = val end
|
#deactivate ⇒ Object
488
489
490
|
# File 'app/models/coupon.rb', line 488
def deactivate
update({ is_inactive: true })
end
|
#deep_dup ⇒ Object
251
252
253
254
255
256
257
258
259
260
261
|
# File 'app/models/coupon.rb', line 251
def deep_dup
deep_clone(
include: :product_filters,
except: %i[effective_date expiration_date]
) do |_original, copy|
if copy.is_a?(Coupon)
copy.code = "#{code}_COPY"
copy.is_inactive = true
end
end
end
|
#discounts ⇒ ActiveRecord::Relation<Discount>
158
|
# File 'app/models/coupon.rb', line 158
has_many :discounts, inverse_of: :coupon
|
#exclusive? ⇒ Boolean
247
248
249
|
# File 'app/models/coupon.rb', line 247
def exclusive?
!not_exclusive?
end
|
#flat_amount_goods ⇒ Object
538
539
540
|
# File 'app/models/coupon.rb', line 538
def flat_amount_goods
(amount_goods_override || amount_goods).to_f.round(2)
end
|
#flat_amount_services ⇒ Object
546
547
548
|
# File 'app/models/coupon.rb', line 546
def flat_amount_services
(amount_services_override || amount_services).to_f.round(2)
end
|
#flat_amount_shipping ⇒ Object
542
543
544
|
# File 'app/models/coupon.rb', line 542
def flat_amount_shipping
(amount_shipping_override || amount_shipping).to_f.round(2)
end
|
163
|
# File 'app/models/coupon.rb', line 163
has_many :future_promotional_catalog_items, class_name: 'CatalogItem', foreign_key: :new_coupon_id, dependent: :nullify, inverse_of: :new_coupon
|
#goods_adjustable ⇒ Object
424
425
426
|
# File 'app/models/coupon.rb', line 424
def goods_adjustable
ADJUSTABLE_CALCULATIONS.include? calculation_type_goods
end
|
156
|
# File 'app/models/coupon.rb', line 156
belongs_to :image, optional: true
|
#instructions ⇒ Object
484
485
486
|
# File 'app/models/coupon.rb', line 484
def instructions
self.class::INSTRUCTIONS
end
|
#is_goods_price_forcing? ⇒ Boolean
526
527
528
|
# File 'app/models/coupon.rb', line 526
def is_goods_price_forcing?
%w[DP MP].include? calculation_type_goods
end
|
#is_msrp_goods_based? ⇒ Boolean
534
535
536
|
# File 'app/models/coupon.rb', line 534
def is_msrp_goods_based?
%w[SF LF].include? calculation_type_goods
end
|
#is_price_forcing? ⇒ Boolean
522
523
524
|
# File 'app/models/coupon.rb', line 522
def is_price_forcing?
is_goods_price_forcing? or is_services_price_forcing?
end
|
#is_services_price_forcing? ⇒ Boolean
530
531
532
|
# File 'app/models/coupon.rb', line 530
def is_services_price_forcing?
%w[DP MP].include? calculation_type_services
end
|
#label_for(n) ⇒ Object
478
479
480
481
482
|
# File 'app/models/coupon.rb', line 478
def label_for(n)
self.class.const_get("LABEL_P#{n}")
rescue NameError
nil
end
|
#line_discounts ⇒ ActiveRecord::Relation<LineDiscount>
159
|
# File 'app/models/coupon.rb', line 159
has_many :line_discounts, inverse_of: :coupon
|
#localized_promo_page_content_html(locale = nil, preview_mode: false) ⇒ Object
386
387
388
389
390
391
392
393
394
395
396
|
# File 'app/models/coupon.rb', line 386
def localized_promo_page_content_html(locale = nil, preview_mode: false)
return if promo_page_content_html.blank?
locale ||= I18n.locale
Liquid::ParseEnvironment.parse(promo_page_content_html).render(
'preview_mode' => preview_mode,
'locale' => locale.to_s,
'canada' => %i[en-CA fr-CA].include?(locale.to_sym),
'usa' => locale.to_sym == :'en-US'
)
end
|
460
461
462
|
# File 'app/models/coupon.rb', line 460
def missing_catalog_items_not_in_promotion_product_filter
all_applicable_catalog_items.where.not(id: promotional_view_product_catalog_items.pluck(:id))
end
|
#percentage_off_goods ⇒ Object
550
551
552
|
# File 'app/models/coupon.rb', line 550
def percentage_off_goods
(amount_goods_override || amount_goods).to_f / 100
end
|
#percentage_off_services ⇒ Object
558
559
560
|
# File 'app/models/coupon.rb', line 558
def percentage_off_services
(amount_services_override || amount_services).to_f / 100
end
|
#percentage_off_shipping ⇒ Object
554
555
556
|
# File 'app/models/coupon.rb', line 554
def percentage_off_shipping
(amount_shipping_override || amount_shipping).to_f / 100
end
|
#product_filter_item_ids_not_in_catalog_items ⇒ Object
464
465
466
|
# File 'app/models/coupon.rb', line 464
def product_filter_item_ids_not_in_catalog_items
all_applicable_item_ids - promotional_view_product_catalog_items.pluck(:item_id)
end
|
#product_filters ⇒ ActiveRecord::Relation<ProductFilter>
160
|
# File 'app/models/coupon.rb', line 160
has_many :product_filters, as: :resource
|
518
519
520
|
# File 'app/models/coupon.rb', line 518
def promotion_matrix_calculation?
[calculation_type_goods, calculation_type_services, calculation_type_shipping].include?('MX')
end
|
162
|
# File 'app/models/coupon.rb', line 162
has_many :promotional_catalog_items, class_name: 'CatalogItem', dependent: :nullify, inverse_of: :coupon
|
468
469
470
|
# File 'app/models/coupon.rb', line 468
def promotional_item_ids_not_in_product_filter
promotional_view_product_catalog_items.pluck(:item_id) - all_applicable_item_ids
end
|
Returns the view product catalog items applicable for this coupon
#public? ⇒ Boolean
570
571
572
|
# File 'app/models/coupon.rb', line 570
def public?
role_ids_restriction.empty? or role_ids_restriction.include?(Role.find_by(name: 'customer').id)
end
|
#publication ⇒ Item
152
|
# File 'app/models/coupon.rb', line 152
belongs_to :publication, class_name: 'Item', optional: true
|
#qualifying_line_items?(itemizable) ⇒ Boolean
501
502
503
504
505
506
507
508
509
510
511
512
|
# File 'app/models/coupon.rb', line 501
def qualifying_line_items?(itemizable)
lines = itemizable.line_items.with_discount_preloads.active_parent_lines
ProductFilter::LineQualifier.new(lines, product_filters,
{
code:,
coupon_tier: tier,
allow_non_domestic_shipping: allow_non_domestic_shipping?,
exclusion_level:
}).qualifying_line_items?
end
|
#reactivate ⇒ Object
492
493
494
|
# File 'app/models/coupon.rb', line 492
def reactivate
update({ is_inactive: false })
end
|
#require_amount_goods? ⇒ Boolean
601
602
603
|
# File 'app/models/coupon.rb', line 601
def require_amount_goods?
calculation_type_goods.present? && !goods_adjustable && !calculation_type_goods == 'MX'
end
|
#require_amount_services? ⇒ Boolean
605
606
607
|
# File 'app/models/coupon.rb', line 605
def require_amount_services?
calculation_type_services.present? && !services_adjustable && !calculation_type_services == 'MX'
end
|
#require_amount_shipping? ⇒ Boolean
609
610
611
|
# File 'app/models/coupon.rb', line 609
def require_amount_shipping?
calculation_type_shipping.present? && !shipping_adjustable && !calculation_type_shipping == 'MX'
end
|
#require_product_filter? ⇒ Boolean
514
515
516
|
# File 'app/models/coupon.rb', line 514
def require_product_filter?
is_price_forcing? and code != 'SMARTPRESETFREEBG'
end
|
#select_options_for(n) ⇒ Object
472
473
474
475
476
|
# File 'app/models/coupon.rb', line 472
def select_options_for(n)
self.class.const_get("OPTIONS_P#{n}")
rescue NameError
nil
end
|
#services_adjustable ⇒ Object
428
429
430
|
# File 'app/models/coupon.rb', line 428
def services_adjustable
ADJUSTABLE_CALCULATIONS.include? calculation_type_services
end
|
#shipping_adjustable ⇒ Object
432
433
434
|
# File 'app/models/coupon.rb', line 432
def shipping_adjustable
ADJUSTABLE_CALCULATIONS.include? calculation_type_shipping
end
|
155
|
# File 'app/models/coupon.rb', line 155
belongs_to :source, optional: true
|
#status ⇒ Object
330
331
332
333
334
335
336
337
338
339
340
|
# File 'app/models/coupon.rb', line 330
def status
if is_inactive
:inactive
elsif expiration_date && Date.current > expiration_date
:expired
elsif effective_date && Date.current < effective_date
:not_yet_in_effect
else
:active
end
end
|
#sticky? ⇒ Boolean
Sticky coupons remain even when $0
497
498
499
|
# File 'app/models/coupon.rb', line 497
def sticky?
is_price_forcing?
end
|
#tier1? ⇒ Boolean
318
319
320
|
# File 'app/models/coupon.rb', line 318
def tier1?
type == 'Coupon::Tier1BaseItemPricing'
end
|
#tier2? ⇒ Boolean
322
323
324
|
# File 'app/models/coupon.rb', line 322
def tier2?
type == 'Coupon::Tier2ProgramPricing'
end
|
#tier3? ⇒ Boolean
326
327
328
|
# File 'app/models/coupon.rb', line 326
def tier3?
type == 'Coupon::Tier3PromotionalPricing'
end
|
#to_s ⇒ Object
374
375
376
377
378
379
380
381
382
383
384
|
# File 'app/models/coupon.rb', line 374
def to_s
[
code,
("G(#{amount_goods}#{calculation_type_goods})" if calculation_type_goods),
("SV(#{amount_services}#{calculation_type_services})" if calculation_type_services),
("SH(#{amount_shipping}#{calculation_type_shipping})" if calculation_type_shipping),
("From #{effective_date || 'Anytime'}" if effective_date),
("Until #{expiration_date}" if expiration_date),
title
].compact.join(' - ')
end
|
#versions_for_audit_trail(_params = {}) ⇒ Object
398
399
400
401
402
403
404
405
406
407
|
# File 'app/models/coupon.rb', line 398
def versions_for_audit_trail(_params = {})
query_sql = %q{
(item_type = 'Coupon' AND item_id = :id)
OR
(item_type = 'ProductFilter'
AND reference_data @> '{"resource_type": "Coupon"}'
AND reference_data @> :resource_id_json)
}
RecordVersion.where(query_sql, id:, resource_id_json: { resource_id: id }.to_json)
end
|