Class: Account::Inviter
- Inherits:
-
BaseService
- Object
- BaseService
- Account::Inviter
- Defined in:
- app/services/account/inviter.rb
Overview
Service object: inviter.
Defined Under Namespace
Classes: Result
Instance Attribute Summary collapse
-
#account ⇒ Object
readonly
Returns the value of attribute account.
-
#party ⇒ Object
readonly
Returns the value of attribute party.
Attributes inherited from BaseService
Class Method Summary collapse
-
.determine_login(email) ⇒ String
Picks an unused login derived from the email, suffixing
-1,-2, … on collision.
Instance Method Summary collapse
-
#destroy_existing_account!(party, existing_account, _email) ⇒ void
protected
Destroys the party's existing account before a forced re-invite.
-
#existing_account_result(existing_account) ⇒ Result
protected
Failure result when the party already has an online account.
-
#login_in_use_result(login) ⇒ Result
protected
Failure result when the requested login is already taken.
-
#missing_email_result(party) ⇒ Result
protected
Failure result when the party has no usable email.
-
#process(party:, email: nil, login: nil, skip_invitation_delivery: false, return_path: nil, force_reinvite: false) ⇒ Result
Invites the party to create an online account, publishing an
Events::AccountInvitedevent for async email delivery.
Methods inherited from BaseService
#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #tagged_logger
Constructor Details
This class inherits a constructor from BaseService
Instance Attribute Details
#account ⇒ Object (readonly)
Returns the value of attribute account.
18 19 20 |
# File 'app/services/account/inviter.rb', line 18 def account @account end |
#party ⇒ Object (readonly)
Returns the value of attribute party.
18 19 20 |
# File 'app/services/account/inviter.rb', line 18 def party @party end |
Class Method Details
.determine_login(email) ⇒ String
Picks an unused login derived from the email, suffixing -1, -2, … on collision.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'app/services/account/inviter.rb', line 74 def self.determine_login(email) login = email if Account.where(login: login).exists? name_part, = email.split('@') base_login = name_part counter = 0 login = base_login while Account.where(login: login).exists? counter += 1 login = "#{base_login}-#{counter}" end end login end |
Instance Method Details
#destroy_existing_account!(party, existing_account, _email) ⇒ void (protected)
This method returns an undefined value.
Destroys the party's existing account before a forced re-invite.
96 97 98 99 100 101 102 103 |
# File 'app/services/account/inviter.rb', line 96 def destroy_existing_account!(party, existing_account, _email) ErrorReporting.warning( "[Account::Inviter] destroying existing account #{existing_account.id} on party #{party.id} before re-inviting", party_id: party.id, account_id: existing_account.id, account_email: existing_account.email ) existing_account.destroy party.reset_account end |
#existing_account_result(existing_account) ⇒ Result (protected)
Failure result when the party already has an online account.
122 123 124 |
# File 'app/services/account/inviter.rb', line 122 def existing_account_result(existing_account) Result.new(invited: false, account: existing_account, messages: ["This customer already has an online account (#{existing_account.login}). Use the existing account page to resend the invitation or reset their password."]) end |
#login_in_use_result(login) ⇒ Result (protected)
Failure result when the requested login is already taken.
115 116 117 |
# File 'app/services/account/inviter.rb', line 115 def login_in_use_result(login) Result.new(invited: false, messages: ["The login you requested #{login} is already in use."]) end |
#missing_email_result(party) ⇒ Result (protected)
Failure result when the party has no usable email.
108 109 110 |
# File 'app/services/account/inviter.rb', line 108 def missing_email_result(party) Result.new(invited: false, messages: ["No Email for party #{party.id}"]) end |
#process(party:, email: nil, login: nil, skip_invitation_delivery: false, return_path: nil, force_reinvite: false) ⇒ Result
Invites the party to create an online account, publishing an
Events::AccountInvited event for async email delivery.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'app/services/account/inviter.rb', line 29 def process(party:, email: nil, login: nil, skip_invitation_delivery: false, return_path: nil, force_reinvite: false) email ||= party.email return missing_email_result(party) unless email existing = Account.find_by(party_id: party.id) if existing return existing_account_result(existing) unless force_reinvite destroy_existing_account!(party, existing, email) end login ||= self.class.determine_login(email) return login_in_use_result(login) if Account.where(login: login).exists? # `name` intentionally omitted: the account's `name` column was retired # (redundant with `party.full_name`, which the invited account reaches via # `party_id` below). Passing it here raised UnknownAttributeError once the # column became `ignored_columns` — AppSignal #6286. account = Account.invite!(login: login, email: email) do |a| a.party_id = party.id a.return_path_for_invite = return_path a.skip_invitation = true a.set_default_marketing_preferences(I18n.locale) end # Send the invitation email off the request path: announce the invite and # let AccountInvitedHandler deliver it async (Sidekiq :mailers). The invite # token's digest is already persisted by `invite!` above (skip_invitation), # and `deliver_invitation` regenerates the raw token in the handler process, # so the emailed link stays valid. unless skip_invitation_delivery Rails.configuration.event_store.publish( Events::AccountInvited.new(data: { account_id: account.id }), stream_name: "Account-#{account.id}" ) end Result.new(invited: account.persisted?, email: email, account: account, messages: account.errors.) end |