Module: SalesforceArSync::SalesforceSync

Extended by:
ActiveSupport::Concern
Defined in:
lib/salesforce_ar_sync/salesforce_sync.rb

Defined Under Namespace

Modules: ClassMethods

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#salesforce_skip_syncObject

if this instance variable is set to true, the salesforce_sync method will return without attempting to sync data to Salesforce



97
98
99
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 97

def salesforce_skip_sync
  @salesforce_skip_sync
end

Instance Method Details

#ar_sync_inbound_delete?Boolean

Check to see if the user passed in a true/false, if so return that, if not then they passed int a symbol to a method We then call the method and use its value instead

Returns:

  • (Boolean)


198
199
200
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 198

def ar_sync_inbound_delete?
  [true, false].include?(self.class.sync_inbound_delete) ? self.class.sync_inbound_delete : send(self.class.sync_inbound_delete)
end

#ar_sync_outbound_delete?Boolean

Returns:

  • (Boolean)


202
203
204
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 202

def ar_sync_outbound_delete?
  [true, false].include?(self.class.sync_outbound_delete) ? self.class.sync_outbound_delete : send(self.class.sync_outbound_delete)
end

#get_activerecord_web_idObject



242
243
244
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 242

def get_activerecord_web_id
  send(self.class.activerecord_web_id_attribute_name)
end

#is_boolean?(attribute) ⇒ Boolean

Returns:

  • (Boolean)


173
174
175
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 173

def is_boolean?(attribute)
  column_for_attribute(attribute) && column_for_attribute(attribute).type == :boolean
end

#salesforce_attributes_to_set(attributes = {}) ⇒ Object

An internal method used to get a hash of values that we are going to set from a Salesforce outbound message hash



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 110

def salesforce_attributes_to_set(attributes = {})
  {}.tap do |hash|
    # loop through the hash of attributes from the outbound message, and compare to our sf mappings and
    # create a reversed hash of value's and key's to pass to update_attributes
    attributes.each do |key, value|
      # make sure our sync_mapping contains the salesforce attribute AND that our object has a setter for it
      hash[self.class.salesforce_sync_attribute_mapping[key.to_s].to_sym] = value if self.class.salesforce_sync_attribute_mapping.include?(key.to_s) && respond_to?("#{self.class.salesforce_sync_attribute_mapping[key.to_s]}=")
    end

    # remove the web_id from hash if it exists, as we don't want to modify a web_id
    hash.delete(:id) if hash[:id]

    # update the sf_updated_at field with the system mod stamp from sf
    hash[:salesforce_updated_at] = attributes[:SystemModstamp]

    # incase we looked up via the WebId__c, we should set the salesforce_id
    hash[:salesforce_id] = attributes[self.class.salesforce_id_attribute_name]
  end
end

#salesforce_attributes_to_update(include_all = false, attrs = []) ⇒ Object

create a hash of updates to send to salesforce



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 159

def salesforce_attributes_to_update(include_all = false, attrs = [])
  {}.tap do |hash|
    self.class.salesforce_sync_attribute_mapping.each do |key, value|
      next if (attrs.any? && attrs.exclude?(value.to_sym)) || !respond_to?(value)

      # Checkboxes in SFDC Cannot be nil.  Here we check for boolean field type and set nil values to be false
      attribute_value = send(value)
      attribute_value = false if is_boolean?(value) && attribute_value.nil?

      hash[key] = attribute_value if !self.class.readonly_fields&.include?(key.to_sym) && (include_all || salesforce_should_update_attribute?(value))
    end
  end
end

#salesforce_create_object(attributes) ⇒ Object



177
178
179
180
181
182
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 177

def salesforce_create_object(attributes)
  attributes[self.class.salesforce_web_id_attribute_name.to_s] = id if self.class.salesforce_sync_web_id? && !new_record?
  salesforce_id = SF_CLIENT.create(salesforce_object_name, format_attributes(attributes))
  self.salesforce_id = salesforce_id
  @exists_in_salesforce = true
end

#salesforce_delete_objectObject



190
191
192
193
194
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 190

def salesforce_delete_object
  if ar_sync_outbound_delete?
    SF_CLIENT.destroy(salesforce_object_name, salesforce_id)
  end
end

#salesforce_empty_attributesObject

Salesforce completely excludes any empty/null fields from Outbound Messages We initialize all declared attributes as nil before mapping the values from the message



101
102
103
104
105
106
107
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 101

def salesforce_empty_attributes
  {}.tap do |hash|
    self.class.salesforce_sync_attribute_mapping.each do |key, _value|
      hash[key] = nil
    end
  end
end

#salesforce_object_exists?Boolean

Returns:

  • (Boolean)


148
149
150
151
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 148

def salesforce_object_exists?
  return @exists_in_salesforce if @exists_in_salesforce
  @exists_in_salesforce = !system_mod_stamp.nil?
end

#salesforce_perform_async_call?(attributes_to_update) ⇒ Boolean

if attributes specified in the async_attributes array are the only attributes being modified, then sync the data via delayed_job

Returns:

  • (Boolean)


208
209
210
211
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 208

def salesforce_perform_async_call?(attributes_to_update)
  return false if attributes_to_update.empty? || self.class.salesforce_async_attributes.empty?
  attributes_to_update.keys.all? { |key| self.class.salesforce_async_attributes.include?(key) } && salesforce_id.present?
end

#salesforce_process_update(attributes = {}) ⇒ Object

Gets passed the Salesforce outbound message hash of changed values and updates the corresponding model



131
132
133
134
135
136
137
138
139
140
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 131

def salesforce_process_update(attributes = {})
  attributes_to_update = salesforce_attributes_to_set(new_record? ? attributes : salesforce_empty_attributes.merge(attributes)) # only merge empty attributes for updates, so we don't overwrite the default create attributes
  attributes_to_update.each_pair do |k, v|
    send("#{k}=", v)
  end

  # we don't want to keep going in a endless loop.  SF has just updated these values.
  self.salesforce_skip_sync = true
  self.send(self.class.salesforce_save_method)
end

#salesforce_should_update_attribute?(attribute) ⇒ Boolean

Checks if the passed in attribute should be updated in Salesforce.com

Returns:

  • (Boolean)


154
155
156
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 154

def salesforce_should_update_attribute?(attribute)
  !respond_to?("#{attribute}_changed?") || (respond_to?("#{attribute}_changed?") && send("#{attribute}_changed?"))
end

#salesforce_sync(*attrs) ⇒ Object

sync model data to Salesforce, adding any Salesforce validation errors to the models errors



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 214

def salesforce_sync(*attrs)
  return if salesforce_skip_sync?

  attributes_to_update = salesforce_attributes_to_update(attrs.any?, attrs)

  if salesforce_perform_async_call?(attributes_to_update)
    SalesforceArSync::SalesforceObjectSyncJob.set(priority: 50).perform_later(
      self.class.salesforce_web_class_name, salesforce_id,
      attributes_to_update.to_json
    )
  else
    if salesforce_object_exists?
      salesforce_update_object(attributes_to_update) if attributes_to_update.present?
    else
      salesforce_create_object(attributes_to_update(!new_record?)) if salesforce_id.nil?
    end
  end
rescue Exception => ex
  errors.add(:base, ex.message)
  false
end

#salesforce_update_object(attributes) ⇒ Object



184
185
186
187
188
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 184

def salesforce_update_object(attributes)
  attributes[self.class.salesforce_web_id_attribute_name.to_s] = id if self.class.salesforce_sync_web_id? && !new_record?

  SF_CLIENT.update(salesforce_object_name, format_attributes(attributes).merge(Id: salesforce_id))
end

#sync_web_idObject



236
237
238
239
240
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 236

def sync_web_id
  return false if !self.class.salesforce_sync_web_id? || SalesforceArSync.config['SYNC_ENABLED'] == false

  SF_CLIENT.update(salesforce_object_name, Id: salesforce_id, self.class.salesforce_web_id_attribute_name.to_s => get_activerecord_web_id) if salesforce_id
end

#system_mod_stampObject

Finds a salesforce record by its Id and returns nil or its SystemModstamp



143
144
145
146
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 143

def system_mod_stamp
  sobject = SF_CLIENT.find(salesforce_object_name, salesforce_id)
  sobject.SystemModstamp
end