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 Schedulable
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 ⇒ Object readonly
- #customer_id ⇒ Object readonly
- #expiration_date ⇒ Object readonly
- #state_code ⇒ Object readonly
- #tax_type ⇒ Object readonly
- #valid_from_date ⇒ Object 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 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.
43 44 45 |
# File 'app/models/tax_exemption.rb', line 43 def @attachment_file end |
#certificate_number ⇒ Object (readonly)
50 |
# File 'app/models/tax_exemption.rb', line 50 validates :customer_id, :certificate_number, :expiration_date, :valid_from_date, :state_code, :tax_type, presence: true |
#customer_id ⇒ Object (readonly)
50 |
# File 'app/models/tax_exemption.rb', line 50 validates :customer_id, :certificate_number, :expiration_date, :valid_from_date, :state_code, :tax_type, presence: true |
#expiration_date ⇒ Object (readonly)
50 |
# File 'app/models/tax_exemption.rb', line 50 validates :customer_id, :certificate_number, :expiration_date, :valid_from_date, :state_code, :tax_type, presence: true |
#state_code ⇒ Object (readonly)
50 |
# File 'app/models/tax_exemption.rb', line 50 validates :customer_id, :certificate_number, :expiration_date, :valid_from_date, :state_code, :tax_type, presence: true |
#tax_type ⇒ Object (readonly)
50 |
# File 'app/models/tax_exemption.rb', line 50 validates :customer_id, :certificate_number, :expiration_date, :valid_from_date, :state_code, :tax_type, presence: true |
#valid_from_date ⇒ Object (readonly)
50 |
# File 'app/models/tax_exemption.rb', line 50 validates :customer_id, :certificate_number, :expiration_date, :valid_from_date, :state_code, :tax_type, presence: true |
Class Method Details
.effective_now ⇒ ActiveRecord::Relation<TaxExemption>
A relation of TaxExemptions that are effective now. Active Record Scope
64 |
# File 'app/models/tax_exemption.rb', line 64 scope :effective_now, -> { effective_on } |
.effective_on ⇒ ActiveRecord::Relation<TaxExemption>
A relation of TaxExemptions that are effective on. Active Record Scope
63 |
# File 'app/models/tax_exemption.rb', line 63 scope :effective_on, ->(date = Date.current) { where(':date BETWEEN valid_from_date AND expiration_date', date:) } |
Instance Method Details
#customer ⇒ Customer
36 |
# File 'app/models/tax_exemption.rb', line 36 belongs_to :customer, optional: true |
#description ⇒ String
Human-readable label used in CRM cards and emails.
82 83 84 |
# File 'app/models/tax_exemption.rb', line 82 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.
89 90 91 92 93 94 95 |
# File 'app/models/tax_exemption.rb', line 89 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.
76 77 78 |
# File 'app/models/tax_exemption.rb', line 76 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.
143 144 145 |
# File 'app/models/tax_exemption.rb', line 143 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
133 134 135 136 137 138 139 |
# File 'app/models/tax_exemption.rb', line 133 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.
150 151 152 153 |
# File 'app/models/tax_exemption.rb', line 150 def notify_expiration FinancialsMailer.tax_exemption_expired(self).deliver_later update(expiration_notified: true) end |
#orders ⇒ ActiveRecord::Relation<Order>
39 |
# File 'app/models/tax_exemption.rb', line 39 has_many :orders |
#period ⇒ Range<Date>
Inclusive range over which the certificate is valid.
70 71 72 |
# File 'app/models/tax_exemption.rb', line 70 def period valid_from_date..expiration_date end |
#state ⇒ State
37 |
# File 'app/models/tax_exemption.rb', line 37 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.
102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'app/models/tax_exemption.rb', line 102 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.
58 59 60 |
# File 'app/models/tax_exemption.rb', line 58 def to_s "Tax Exemption (#{[state_code, certificate_number].compact.join(' - ')})" end |
#update_open_orders ⇒ void
121 122 123 124 125 |
# File 'app/models/tax_exemption.rb', line 121 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 |