Class: Discount
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Discount
- Includes:
- Models::Auditable
- Defined in:
- app/models/discount.rb
Overview
== Schema Information
Table name: discounts
Database name: primary
id :integer not null, primary key
amount :decimal(10, 2)
blacklisted :boolean
effective_date :datetime
itemizable_type :string(50)
notes :text
user_amount :decimal(10, 2)
created_at :datetime
updated_at :datetime
coupon_id :integer not null
coupon_serial_number_id :uuid
itemizable_id :integer not null
legacy_coupon_id :integer
Indexes
by_itid_itt_csnid (itemizable_id,itemizable_type,coupon_serial_number_id)
idx_coupon_id (coupon_id)
index_discounts_unique_per_itemizable (itemizable_type,itemizable_id,coupon_id) UNIQUE
Foreign Keys
fk_rails_... (coupon_serial_number_id => coupon_serial_numbers.id)
Constant Summary collapse
- ITEMIZABLE_TYPES =
Polymorphic owner allow-list.
discounts.(itemizable_type, itemizable_id)
has no database FK, so pin the type here — a mistyped or injected
itemizable_typewould corrupt order/quote money math
(see doc/tasks/202607041714_POLYMORPHIC_FK_INTEGRITY_AUDIT.md). %w[Order Quote Invoice CreditMemo].freeze
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
Constants included from Models::Schedulable
Models::Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
-
#amount ⇒ Object
readonly
Validates amount.
-
#coupon_description ⇒ Object
Returns the value of attribute coupon_description.
-
#coupon_id ⇒ Object
readonly
Validates coupon id, itemizable id.
-
#coupon_serial_number_id ⇒ Object
readonly
Validates coupon serial number id, itemizable requires unique coupon serial.
-
#itemizable_type ⇒ Object
readonly
Validates itemizable type.
-
#user_amount ⇒ Object
readonly
Validates user amount.
Belongs to collapse
-
#coupon ⇒ Coupon
The coupon this record belongs to.
-
#coupon_serial_number ⇒ CouponSerialNumber?
The coupon serial number this record belongs to.
-
#itemizable ⇒ Itemizable
The itemizable this record belongs to.
Methods included from Models::Auditable
Has many collapse
-
#line_discounts ⇒ ActiveRecord::Relation<LineDiscount>
The associated line discounts.
Delegated Instance Attributes collapse
-
#auto_apply ⇒ Object
Alias for Coupon#auto_apply.
-
#blacklistable? ⇒ Object
Alias for Coupon#blacklistable?.
-
#code ⇒ Object
Alias for Coupon#code.
Class Method Summary collapse
-
.active ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are active.
-
.auto_applied ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are auto applied.
-
.excluding_shipping ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are excluding shipping.
-
.fixed_dollar ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are fixed dollar.
-
.free_online_shipping ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are free online shipping.
-
.manually_applied ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are manually applied.
-
.non_blacklisted ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are non blacklisted.
-
.non_zero_value ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are non zero value.
-
.sorted ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are sorted.
-
.tier1 ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are tier1.
-
.tier1and3 ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are tier1and3.
-
.tier2 ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are tier2.
-
.tier3 ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are tier3.
-
.visible ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are visible.
-
.with_economy_shipping_match_crm ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are with economy shipping match crm.
-
.zero_value ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are zero value.
Instance Method Summary collapse
-
#apply_source ⇒ Object
Apply the source specified in the coupon if applicable.
-
#discount_sum_by_tax_class(tax_class) ⇒ Object
Discount sum by tax class.
-
#goods ⇒ Object
Goods.
-
#invisible? ⇒ Boolean
Whether the record invisible.
-
#mark_as_blacklisted ⇒ Object
Mark as blacklisted.
-
#preserve_amount? ⇒ Boolean
Whether the record preserve amount.
-
#services ⇒ Object
Services.
-
#shipping ⇒ Object
Shipping.
-
#sticky? ⇒ Boolean
Whether the record sticky.
Methods included from Models::Auditable
#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
Methods included from Models::Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Instance Attribute Details
#amount ⇒ Object (readonly)
Validates amount.
Validations:
58 |
# File 'app/models/discount.rb', line 58 validates :amount, numericality: true |
#coupon_description ⇒ Object
Returns the value of attribute coupon_description.
53 54 55 |
# File 'app/models/discount.rb', line 53 def coupon_description @coupon_description end |
#coupon_id ⇒ Object (readonly)
Validates coupon id, itemizable id.
Validations:
- Uniqueness ({ scope: %i[itemizable_type itemizable_id], if: :itemizable_id })
65 |
# File 'app/models/discount.rb', line 65 validates :coupon_id, uniqueness: { scope: %i[itemizable_type itemizable_id], if: :itemizable_id } |
#coupon_serial_number_id ⇒ Object (readonly)
Validates coupon serial number id, itemizable requires unique coupon serial.
Validations:
- Uniqueness ({ allow_nil: true, if: :itemizable_requires_unique_coupon_serial? })
67 |
# File 'app/models/discount.rb', line 67 validates :coupon_serial_number_id, uniqueness: { allow_nil: true, if: :itemizable_requires_unique_coupon_serial? } |
#itemizable_type ⇒ Object (readonly)
Validates itemizable type.
Validations:
- Inclusion ({ in: ITEMIZABLE_TYPES })
60 |
# File 'app/models/discount.rb', line 60 validates :itemizable_type, inclusion: { in: ITEMIZABLE_TYPES } |
#user_amount ⇒ Object (readonly)
Validates user amount.
Validations:
- Presence ({ if: ->(_d) { coupon&.adjustable } })
63 |
# File 'app/models/discount.rb', line 63 validates :user_amount, presence: { if: ->(_d) { coupon&.adjustable } } |
Class Method Details
.active ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are active. Active Record Scope
71 |
# File 'app/models/discount.rb', line 71 scope :active, -> { joins(:coupon).merge(Coupon.active) } |
.auto_applied ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are auto applied. Active Record Scope
76 |
# File 'app/models/discount.rb', line 76 scope :auto_applied, -> { where(auto_apply: true) } |
.excluding_shipping ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are excluding shipping. Active Record Scope
84 |
# File 'app/models/discount.rb', line 84 scope :excluding_shipping, -> { joins(line_discounts: :line_item).where.not(line_item: { tax_class: 'shp' }) } |
.fixed_dollar ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are fixed dollar. Active Record Scope
83 |
# File 'app/models/discount.rb', line 83 scope :fixed_dollar, -> { joins(:coupon).merge(Coupon.fixed_dollar) } |
.free_online_shipping ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are free online shipping. Active Record Scope
85 |
# File 'app/models/discount.rb', line 85 scope :free_online_shipping, -> { joins(:coupon).merge(Coupon.free_online_shipping) } |
.manually_applied ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are manually applied. Active Record Scope
75 |
# File 'app/models/discount.rb', line 75 scope :manually_applied, -> { where.not(auto_apply: true) } |
.non_blacklisted ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are non blacklisted. Active Record Scope
77 |
# File 'app/models/discount.rb', line 77 scope :non_blacklisted, -> { where(blacklisted: [nil, false]) } |
.non_zero_value ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are non zero value. Active Record Scope
74 |
# File 'app/models/discount.rb', line 74 scope :non_zero_value, -> { where.not(amount: 0) } |
.sorted ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are sorted. Active Record Scope
78 |
# File 'app/models/discount.rb', line 78 scope :sorted, -> { joins(:coupon).merge(Coupon.sorted) } |
.tier1 ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are tier1. Active Record Scope
79 |
# File 'app/models/discount.rb', line 79 scope :tier1, -> { sorted.merge(Coupon.tier1) } |
.tier1and3 ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are tier1and3. Active Record Scope
82 |
# File 'app/models/discount.rb', line 82 scope :tier1and3, -> { sorted.merge(Coupon.tier1and3) } |
.tier2 ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are tier2. Active Record Scope
80 |
# File 'app/models/discount.rb', line 80 scope :tier2, -> { sorted.merge(Coupon.tier2) } |
.tier3 ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are tier3. Active Record Scope
81 |
# File 'app/models/discount.rb', line 81 scope :tier3, -> { sorted.merge(Coupon.tier3) } |
.visible ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are visible. Active Record Scope
72 |
# File 'app/models/discount.rb', line 72 scope :visible, -> { where(Discount[:amount].lt(0)) } |
.with_economy_shipping_match_crm ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are with economy shipping match crm. Active Record Scope
86 |
# File 'app/models/discount.rb', line 86 scope :with_economy_shipping_match_crm, -> { joins(:coupon).merge(Coupon.with_economy_shipping_match_crm) } |
.zero_value ⇒ ActiveRecord::Relation<Discount>
A relation of Discounts that are zero value. Active Record Scope
73 |
# File 'app/models/discount.rb', line 73 scope :zero_value, -> { where(amount: 0) } |
Instance Method Details
#apply_source ⇒ Object
Apply the source specified in the coupon if applicable.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'app/models/discount.rb', line 136 def apply_source return unless coupon && itemizable && coupon.source case itemizable_type.downcase.to_sym when :order coupon.apply_source_to_order(itemizable) coupon.apply_source_to_opportunity(itemizable.opportunity) if itemizable.opportunity coupon.apply_source_to_customer(itemizable.customer) when :quote return unless itemizable.opportunity coupon.apply_source_to_opportunity(itemizable.opportunity) itemizable.opportunity.orders.each { |order| coupon.apply_source_to_order(order) } coupon.apply_source_to_customer(itemizable.opportunity.customer) end end |
#auto_apply ⇒ Object
Alias for Coupon#auto_apply
88 |
# File 'app/models/discount.rb', line 88 delegate :blacklistable?, :auto_apply, :code, to: :coupon |
#blacklistable? ⇒ Object
Alias for Coupon#blacklistable?
88 |
# File 'app/models/discount.rb', line 88 delegate :blacklistable?, :auto_apply, :code, to: :coupon |
#code ⇒ Object
Alias for Coupon#code
88 |
# File 'app/models/discount.rb', line 88 delegate :blacklistable?, :auto_apply, :code, to: :coupon |
#coupon ⇒ Coupon
Returns the coupon this record belongs to.
44 |
# File 'app/models/discount.rb', line 44 belongs_to :coupon, touch: :last_used_at |
#coupon_serial_number ⇒ CouponSerialNumber?
Returns the coupon serial number this record belongs to.
48 |
# File 'app/models/discount.rb', line 48 belongs_to :coupon_serial_number, optional: true |
#discount_sum_by_tax_class(tax_class) ⇒ Object
Discount sum by tax class.
97 98 99 |
# File 'app/models/discount.rb', line 97 def discount_sum_by_tax_class(tax_class) line_discounts.joins(:line_item).where(LineItem[:tax_class].eq(tax_class)).sum(:amount) end |
#goods ⇒ Object
Goods.
102 103 104 |
# File 'app/models/discount.rb', line 102 def goods discount_sum_by_tax_class 'g' end |
#invisible? ⇒ Boolean
Returns whether the record invisible.
126 127 128 |
# File 'app/models/discount.rb', line 126 def invisible? amount.zero? or blacklisted end |
#itemizable ⇒ Itemizable
Returns the itemizable this record belongs to.
46 |
# File 'app/models/discount.rb', line 46 belongs_to :itemizable, polymorphic: true |
#line_discounts ⇒ ActiveRecord::Relation<LineDiscount>
Returns the associated line discounts.
51 |
# File 'app/models/discount.rb', line 51 has_many :line_discounts, dependent: :destroy, autosave: true |
#mark_as_blacklisted ⇒ Object
Mark as blacklisted.
117 118 119 120 121 122 123 |
# File 'app/models/discount.rb', line 117 def mark_as_blacklisted return if Coupon::SKIP_BLACKLISTING_COUPON_CODES.include?(code) self.amount = 0 line_discounts.each(&:destroy) self.blacklisted = true end |
#preserve_amount? ⇒ Boolean
Returns whether the record preserve amount.
131 132 133 |
# File 'app/models/discount.rb', line 131 def preserve_amount? coupon.adjustable end |
#services ⇒ Object
Services.
107 108 109 |
# File 'app/models/discount.rb', line 107 def services discount_sum_by_tax_class 'svc' end |
#shipping ⇒ Object
Shipping.
112 113 114 |
# File 'app/models/discount.rb', line 112 def shipping discount_sum_by_tax_class 'shp' end |
#sticky? ⇒ Boolean
Returns whether the record sticky.
91 92 93 |
# File 'app/models/discount.rb', line 91 def sticky? blacklisted or coupon.sticky? end |