Module: Models::SourceAttributable
- Extended by:
- ActiveSupport::Concern
- Included in:
- Customer, Opportunity, Order
- Defined in:
- app/concerns/models/source_attributable.rb
Overview
Concern for models that have source attribution via visits with Google click IDs.
Provides methods to check if source attribution should be protected from manual changes.
Used by: Opportunity, Order, Customer
A source is considered "locked" when the record or its associated visit has a Google
click identifier (gclid, gbraid, or wbraid), indicating paid traffic attribution
that should not be overwritten by manual source selection.
Instance Method Summary collapse
-
#has_google_ads_attribution? ⇒ Boolean
Returns true if this record has Google Ads attribution that should be protected.
-
#source_event_window_respected ⇒ void
Rejects tagging a record with a trade show it cannot have come from.
-
#source_locked? ⇒ Boolean
Returns true if source should be locked from manual editing in UI.
-
#source_locked_reason ⇒ String?
Human-readable message explaining why source is locked.
-
#visit_with_google_click_id? ⇒ Boolean
Check if the associated visit has a Google click identifier.
Instance Method Details
#has_google_ads_attribution? ⇒ Boolean
Returns true if this record has Google Ads attribution that should be protected.
Override in models that have different visit relationships.
54 55 56 57 58 59 60 |
# File 'app/concerns/models/source_attributable.rb', line 54 def has_google_ads_attribution? return true if respond_to?(:gclid) && gclid.present? return true if respond_to?(:gbraid) && gbraid.present? return true if respond_to?(:wbraid) && wbraid.present? visit_with_google_click_id? end |
#source_event_window_respected ⇒ void
This method returns an undefined value.
Rejects tagging a record with a trade show it cannot have come from.
An event attributes across its whole commercial arc — lead-in, show,
follow-up — so a record must date from inside that span. What this refuses
is a show stamped onto business it has nothing to do with, which is how a
2011 Toronto show ended up on 20k Costco orders.
The lead-in is not a loophole, it is the point: an order written the week
before a show the rep is about to attend is the same sale as one taken at
the booth. See Source#attribution_window.
Deliberately permissive in three places: an undated event (all 340 legacy
ones) cannot be judged and is allowed; only a CHANGE to source_id is
checked, so existing records stay editable for every other reason; and an
order inheriting its opportunity's source is not re-attributed on the later
order date. A bad inherited pairing must be corrected on the opportunity.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'app/concerns/models/source_attributable.rb', line 36 def source_event_window_respected return if respond_to?(:opportunity) && opportunity&.source_id == source_id event = Source.find_by(id: source_id) return if event.nil? || !event.event? at = created_at || Time.current return if event.attributable_at?(at) window = event.attribution_window errors.add(:source_id, "#{event.full_name} ran #{event.starts_on} to #{event.ends_on} and attributes from " \ "#{window.first} to #{window.last} (#{event.pre_attribution_window_days} days lead-in, " \ "#{event.attribution_window_days} days follow-up); this record dates from #{at.to_date}") end |
#source_locked? ⇒ Boolean
Returns true if source should be locked from manual editing in UI
70 71 72 |
# File 'app/concerns/models/source_attributable.rb', line 70 def source_locked? has_google_ads_attribution? end |
#source_locked_reason ⇒ String?
Human-readable message explaining why source is locked
77 78 79 80 81 82 83 84 85 86 87 |
# File 'app/concerns/models/source_attributable.rb', line 77 def source_locked_reason return nil unless source_locked? if respond_to?(:visit) && visit.present? && (visit..present? || visit..present? || visit..present?) "Source is locked: attributed to Google Ads via visit on #{visit.started_at&.to_date}" elsif respond_to?(:gclid) && gclid.present? 'Source is locked: customer has Google Click ID (gclid)' else 'Source is locked: has Google Ads attribution' end end |
#visit_with_google_click_id? ⇒ Boolean
Check if the associated visit has a Google click identifier
63 64 65 66 67 |
# File 'app/concerns/models/source_attributable.rb', line 63 def visit_with_google_click_id? return false unless respond_to?(:visit) && visit.present? visit..present? || visit..present? || visit..present? end |