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
-
#salesforce_skip_sync ⇒ Object
if this instance variable is set to true, the salesforce_sync method will return without attempting to sync data to Salesforce.
Instance Method Summary collapse
-
#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.
- #ar_sync_outbound_delete? ⇒ Boolean
- #get_activerecord_web_id ⇒ Object
- #is_boolean?(attribute) ⇒ Boolean
-
#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.
-
#salesforce_attributes_to_update(include_all = false) ⇒ Object
create a hash of updates to send to salesforce.
- #salesforce_create_object(attributes) ⇒ Object
- #salesforce_delete_object ⇒ Object
-
#salesforce_empty_attributes ⇒ Object
Salesforce completely excludes any empty/null fields from Outbound Messages We initialize all declared attributes as nil before mapping the values from the message.
- #salesforce_object_exists? ⇒ Boolean
-
#salesforce_perform_async_call? ⇒ Boolean
if attributes specified in the async_attributes array are the only attributes being modified, then sync the data via delayed_job.
-
#salesforce_process_update(attributes = {}) ⇒ Object
Gets passed the Salesforce outbound message hash of changed values and updates the corresponding model.
-
#salesforce_should_update_attribute?(attribute) ⇒ Boolean
Checks if the passed in attribute should be updated in Salesforce.com.
-
#salesforce_sync ⇒ Object
sync model data to Salesforce, adding any Salesforce validation errors to the models errors.
- #salesforce_update_object(attributes) ⇒ Object
- #sync_web_id ⇒ Object
-
#system_mod_stamp ⇒ Object
Finds a salesforce record by its Id and returns nil or its SystemModstamp.
Instance Attribute Details
#salesforce_skip_sync ⇒ Object
if this instance variable is set to true, the salesforce_sync method will return without attempting to sync data to Salesforce
79 80 81 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 79 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
189 190 191 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 189 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
193 194 195 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 193 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_id ⇒ Object
226 227 228 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 226 def get_activerecord_web_id self.send(self.class.activerecord_web_id_attribute_name) end |
#is_boolean?(attribute) ⇒ Boolean
165 166 167 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 165 def is_boolean?(attribute) self.column_for_attribute(attribute) && self.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
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 92 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) && self.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) ⇒ Object
create a hash of updates to send to salesforce
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 148 def salesforce_attributes_to_update(include_all = false) {}.tap do |hash| self.class.salesforce_sync_attribute_mapping.each do |key, value| if self.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 = self.send(value) if is_boolean?(value) && attribute_value.nil? attribute_value = false end hash[key] = attribute_value if include_all || salesforce_should_update_attribute?(value) end end end end |
#salesforce_create_object(attributes) ⇒ Object
169 170 171 172 173 174 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 169 def salesforce_create_object(attributes) attributes.merge!(self.class.salesforce_web_id_attribute_name.to_s => id) if self.class.salesforce_sync_web_id? && !new_record? result = SF_CLIENT.http_post("/services/data/v#{SF_CLIENT.version}/sobjects/#{salesforce_object_name}", format_attributes(attributes).to_json) self.salesforce_id = JSON.parse(result.body)["id"] @exists_in_salesforce = true end |
#salesforce_delete_object ⇒ Object
181 182 183 184 185 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 181 def salesforce_delete_object if self.ar_sync_outbound_delete? SF_CLIENT.http_delete("/services/data/v#{SF_CLIENT.version}/sobjects/#{salesforce_object_name}/#{salesforce_id}") end end |
#salesforce_empty_attributes ⇒ Object
Salesforce completely excludes any empty/null fields from Outbound Messages We initialize all declared attributes as nil before mapping the values from the message
83 84 85 86 87 88 89 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 83 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
137 138 139 140 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 137 def salesforce_object_exists? return @exists_in_salesforce if @exists_in_salesforce @exists_in_salesforce = !system_mod_stamp.nil? end |
#salesforce_perform_async_call? ⇒ Boolean
if attributes specified in the async_attributes array are the only attributes being modified, then sync the data via delayed_job
199 200 201 202 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 199 def salesforce_perform_async_call? return false if salesforce_attributes_to_update.empty? || self.class.salesforce_async_attributes.empty? salesforce_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
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 113 def salesforce_process_update(attributes = {}) attributes_to_update = salesforce_attributes_to_set(self.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| self.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.save! end |
#salesforce_should_update_attribute?(attribute) ⇒ Boolean
Checks if the passed in attribute should be updated in Salesforce.com
143 144 145 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 143 def salesforce_should_update_attribute?(attribute) !self.respond_to?("#{attribute}_changed?") || (self.respond_to?("#{attribute}_changed?") && self.send("#{attribute}_changed?")) end |
#salesforce_sync ⇒ Object
sync model data to Salesforce, adding any Salesforce validation errors to the models errors
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 205 def salesforce_sync return if self.salesforce_skip_sync? if salesforce_perform_async_call? Delayed::Job.enqueue(SalesforceArSync::SalesforceObjectSync.new(self.class.salesforce_web_class_name, salesforce_id, salesforce_attributes_to_update), :priority => 50) else if salesforce_object_exists? salesforce_update_object(salesforce_attributes_to_update) if salesforce_attributes_to_update.present? else salesforce_create_object(salesforce_attributes_to_update(!new_record?)) if salesforce_id.nil? end end rescue Exception => ex self.errors[:base] << ex. return false end |
#salesforce_update_object(attributes) ⇒ Object
176 177 178 179 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 176 def salesforce_update_object(attributes) attributes.merge!(self.class.salesforce_web_id_attribute_name.to_s => id) if self.class.salesforce_sync_web_id? && !new_record? SF_CLIENT.http_patch("/services/data/v#{SF_CLIENT.version}/sobjects/#{salesforce_object_name}/#{salesforce_id}", format_attributes(attributes).to_json) end |
#sync_web_id ⇒ Object
221 222 223 224 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 221 def sync_web_id return false if !self.class.salesforce_sync_web_id? || self.salesforce_skip_sync? SF_CLIENT.http_patch("/services/data/v#{SF_CLIENT.version}/sobjects/#{salesforce_object_name}/#{salesforce_id}", { self.class.salesforce_web_id_attribute_name.to_s => get_activerecord_web_id }.to_json) if salesforce_id end |
#system_mod_stamp ⇒ Object
Finds a salesforce record by its Id and returns nil or its SystemModstamp
131 132 133 134 |
# File 'lib/salesforce_ar_sync/salesforce_sync.rb', line 131 def system_mod_stamp hash = JSON.parse(SF_CLIENT.http_get("/services/data/v#{SF_CLIENT.version}/query", :q => "SELECT SystemModstamp FROM #{salesforce_object_name} WHERE Id = '#{salesforce_id}'").body) hash["records"].first.try(:[], "SystemModstamp") end |