Class: TaxExemption
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- TaxExemption
- Includes:
- Models::Auditable
- Defined in:
- app/models/tax_exemption.rb
Overview
== Schema Information
Table name: tax_exemptions
Database name: primary
id :integer not null, primary key
attachment_name :string
attachment_uid :string
certificate_number :string(255)
expiration_date :date
expiration_notified :boolean default(FALSE)
migrated :boolean default(FALSE)
state_code :string(20)
tax_type :string(255)
valid_from_date :date
created_at :datetime
updated_at :datetime
creator_id :integer
customer_id :integer
updater_id :integer
upload_id :integer
Indexes
by_vfd_expd_cid (valid_from_date,expiration_date,customer_id)
c_id_sc_ed_vfd (customer_id,state_code,expiration_date,valid_from_date)
cust_id_valid_date (customer_id,valid_from_date)
index_tax_exemptions_on_upload_id (upload_id)
Constant Summary
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
Constants included from Models::Schedulable
Models::Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
-
#attachment_file ⇒ Object
Virtual attribute: assign an uploaded file (ActionDispatch::Http::UploadedFile or any IO-like object).
- #certificate_number ⇒ String(255) readonly
- #customer_id ⇒ Integer readonly
- #expiration_date ⇒ Date readonly
- #state_code ⇒ String(20) readonly
- #tax_type ⇒ String(255) readonly
- #valid_from_date ⇒ Date readonly
Belongs to collapse
Methods included from Models::Auditable
Has many collapse
Class Method Summary collapse
-
.effective_now ⇒ ActiveRecord::Relation<TaxExemption>
A relation of TaxExemptions that are effective now.
-
.effective_on ⇒ ActiveRecord::Relation<TaxExemption>
A relation of TaxExemptions that are effective on.
Instance Method Summary collapse
-
#description ⇒ String
Human-readable label used in CRM cards and emails.
-
#has_valid_date_range ⇒ void
Validation:
valid_from_datemust not fall afterexpiration_date. -
#is_valid? ⇒ Boolean
Whether today falls inside #period.
-
#notify_creation ⇒ void
Email AR / sales-rep that a new exemption has been uploaded.
-
#notify_emails ⇒ String
Who gets notified about expiration / upload activity: primary sales rep for trade customers, AR ops mailbox for e-commerce.
-
#notify_expiration ⇒ void
Email AR / sales-rep that the exemption has lapsed and flag the row so we don't re-send.
-
#period ⇒ Range<Date>
Inclusive range over which the certificate is valid.
-
#tax_exemption_overlap ⇒ void
Validation: prevent two exemptions for the same
(customer, state, tax_type)from covering overlapping dates. -
#to_s ⇒ String
"Tax Exemption (<STATE> - <CERT#>)". - #update_open_orders ⇒ void
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
#attachment_file ⇒ Object
Virtual attribute: assign an uploaded file (ActionDispatch::Http::UploadedFile
or any IO-like object). Saved to Upload (secure bucket) in after_save.
46 47 48 |
# File 'app/models/tax_exemption.rb', line 46 def @attachment_file end |
#certificate_number ⇒ String(255) (readonly)
56 |
# File 'app/models/tax_exemption.rb', line 56 validates :certificate_number, presence: true |
#customer_id ⇒ Integer (readonly)
54 |
# File 'app/models/tax_exemption.rb', line 54 validates :customer_id, presence: true |
#expiration_date ⇒ Date (readonly)
58 |
# File 'app/models/tax_exemption.rb', line 58 validates :expiration_date, presence: true |
#state_code ⇒ String(20) (readonly)
62 |
# File 'app/models/tax_exemption.rb', line 62 validates :state_code, presence: true |
#tax_type ⇒ String(255) (readonly)
64 |
# File 'app/models/tax_exemption.rb', line 64 validates :tax_type, presence: true |
#valid_from_date ⇒ Date (readonly)
60 |
# File 'app/models/tax_exemption.rb', line 60 validates :valid_from_date, presence: true |
Class Method Details
.effective_now ⇒ ActiveRecord::Relation<TaxExemption>
A relation of TaxExemptions that are effective now. Active Record Scope
78 |
# File 'app/models/tax_exemption.rb', line 78 scope :effective_now, -> { effective_on } |
.effective_on ⇒ ActiveRecord::Relation<TaxExemption>
A relation of TaxExemptions that are effective on. Active Record Scope
77 |
# File 'app/models/tax_exemption.rb', line 77 scope :effective_on, ->(date = Date.current) { where(':date BETWEEN valid_from_date AND expiration_date', date:) } |
Instance Method Details
#customer ⇒ Customer?
37 |
# File 'app/models/tax_exemption.rb', line 37 belongs_to :customer, optional: true |
#description ⇒ String
Human-readable label used in CRM cards and emails.
96 97 98 |
# File 'app/models/tax_exemption.rb', line 96 def description "#{state_code} (#{certificate_number}), expires #{expiration_date}" end |
#has_valid_date_range ⇒ void
This method returns an undefined value.
Validation: valid_from_date must not fall after
expiration_date.
103 104 105 106 107 108 109 |
# File 'app/models/tax_exemption.rb', line 103 def has_valid_date_range # Check dates are in order return unless valid_from_date && expiration_date return unless valid_from_date > expiration_date errors.add(:base, 'date range is invalid') end |
#is_valid? ⇒ Boolean
Whether today falls inside #period.
90 91 92 |
# File 'app/models/tax_exemption.rb', line 90 def is_valid? period === Date.current end |
#notify_creation ⇒ void
This method returns an undefined value.
Email AR / sales-rep that a new exemption has been uploaded.
157 158 159 |
# File 'app/models/tax_exemption.rb', line 157 def notify_creation FinancialsMailer.tax_exemption_uploaded(self).deliver_later end |
#notify_emails ⇒ String
Who gets notified about expiration / upload activity:
primary sales rep for trade customers, AR ops mailbox for
e-commerce.
who will get notifications of tax exemption expiration and uploads activities
147 148 149 150 151 152 153 |
# File 'app/models/tax_exemption.rb', line 147 def notify_emails if !customer.is_e_commerce_misc? && (sales_rep_email = customer.primary_sales_rep.try(:email)) sales_rep_email else 'ar@warmlyyours.com' end end |
#notify_expiration ⇒ void
This method returns an undefined value.
Email AR / sales-rep that the exemption has lapsed and flag
the row so we don't re-send.
164 165 166 167 |
# File 'app/models/tax_exemption.rb', line 164 def notify_expiration FinancialsMailer.tax_exemption_expired(self).deliver_later update(expiration_notified: true) end |
#orders ⇒ ActiveRecord::Relation<Order>
42 |
# File 'app/models/tax_exemption.rb', line 42 has_many :orders |
#period ⇒ Range<Date>
Inclusive range over which the certificate is valid.
84 85 86 |
# File 'app/models/tax_exemption.rb', line 84 def period valid_from_date..expiration_date end |
#state ⇒ State?
39 |
# File 'app/models/tax_exemption.rb', line 39 belongs_to :state, foreign_key: :state_code, primary_key: :code, optional: true |
#tax_exemption_overlap ⇒ void
This method returns an undefined value.
Validation: prevent two exemptions for the same
(customer, state, tax_type) from covering overlapping dates.
Uses Postgres OVERLAPS.
116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'app/models/tax_exemption.rb', line 116 def tax_exemption_overlap return unless customer && valid_from_date.present? && expiration_date.present? && state_code.present? && tax_type.present? # Check we don't have overlapping dates sql = '(valid_from_date, expiration_date) OVERLAPS (:valid_from_date, :expiration_date)' te = customer.tax_exemptions.where(state_code:, tax_type:) .where.not(id: id.to_i) .where(sql, valid_from_date:, expiration_date:).first return unless te # all valid no overlapping tax exemption detected errors.add(:base, "date overlap with another tax exemption (id: #{te.id}).") end |
#to_s ⇒ String
"Tax Exemption (<STATE> - <CERT#>)". Either component may be
absent during validation.
72 73 74 |
# File 'app/models/tax_exemption.rb', line 72 def to_s "Tax Exemption (#{[state_code, certificate_number].compact.join(' - ')})" end |
#update_open_orders ⇒ void
135 136 137 138 139 |
# File 'app/models/tax_exemption.rb', line 135 def update_open_orders logger.info "Updating open order for tax exemption id #{id} customer #{customer.id} - #{customer.name}" customer.orders.open_for_change.not_cancelled.each(&:refresh_tax_rate) # light touch here is to ignore cancelled order but perhaps we should remove it from OPEN_FOR_CHANGE_STATES in order since it is simultaneously in LOCKED_STATES which is a contradiction and you can have all kind of junk in cancelled orders, plus 100s of these. Also quote's open_quotes excludes cancelled state as well. customer.quotes.open_quotes.each(&:refresh_tax_rate) end |
#upload ⇒ Upload?
35 |
# File 'app/models/tax_exemption.rb', line 35 belongs_to :upload, optional: true |