infopark-crm-helpers
Infopark WebCRM is a cloud-based CRM. This gem infopark-crm-helpers
addresses two "annoying" things when you have your own classes and want to use the WebCRM as a data store.
-
Crm::Contact
and its friends don't provide setters for attributes and if you build your own classes around them, you will find that collecting all the relevant attributes with which to call#update
(or#create
) can be a bit tedious. - There is no easy way to validate your objects against the type definitions set up in the WebCRM. You however want to validate your entire object before you try to write your data to the WebCRM, because not doing so can cause an awkward user experience: You validate the object to match your expectations of what a valid object is and the user works on fixing their input to match your expectations. Then, you send your data to the WebCRM and... it tells you your data is invalid. The user will have to deal with another round of fixing their input, which can end up in nasty tableflips.
infopark-crm-helpers
attempts to address these things in a convenient way.
Installation
Add 'infopark-crm-helpers' into your Gemfile
.
gem 'infopark-crm-helpers`
Install the gem with Bundler.
bundle install
Configuration
No direct configuration of infopark-crm-helpers
is required. Refer to infopark/webcrm_sdk for instructions on setting up your installation of infopark_webcrm_sdk
.
Run specs
Add your CRM credentials to /spec/config/crm.yml
.
test:
tenant: your-tenant-here
login: john.smith@example.org
api_key: 1234567890abcdefghijklmnopqrstuvwxyz
Then invoke:
bundle exec rake spec
Examples
Create your own class
Let's build a class Customer
which is based on WebCRM contacts.
class Customer
include Crm::Helpers::Attributes
represents_crm_type :contact
end
Customer.mandatory_crm_attributes
# => [:language, :last_name]
Customer.crm_attributes[:language]
# => {"attribute_type"=>"enum", "create"=>true, "mandatory"=>true, "read"=>true,
# "title"=>"Language", "update"=>true, "valid_values"=>["de", "en"]}
Customer.crm_attributes[:last_name]
# => {"attribute_type"=>"string", "create"=>true, "mandatory"=>true,
# "read"=>true, "title"=>"Last Name", "update"=>true}
Use attributes from the CRM contact
class Customer
include Crm::Helpers::Attributes
represents_crm_type :contact
crm_attr_accessor :first_name, :last_name, :email
end
customer = Customer.new
# => #<Customer>
customer.first_name = 'Huy'
# => "Huy"
customer.last_name = 'Dinh'
# => "Dinh"
customer.email = 'huy.dinh@infopark.de'
# => "huy.dinh@infopark.de"
customer.crm_attributes
# => {:first_name=>"Huy", :last_name=>"Dinh", :email=>"huy.dinh@infopark.de"}
Validate an object
class Customer
include ActiveModel::Validations
include Crm::Helpers::Attributes
represents_crm_type :contact
crm_attr_accessor :first_name, :last_name, :email
validates_with Crm::Helpers::Validators::CrmTypeValidator
end
customer = Customer.new
# => #<Customer>
customer.valid?
# => false
customer.errors
# => #<ActiveModel::Errors @base=#<Customer:0x007feb8f3b3d00
# @validation_context=nil, @errors=#<ActiveModel::Errors:0x007feb8f381dc8 ...>,
# @crm_attributes={}>, @messages={:language=>["can't be blank"],
# :last_name=>["can't be blank"]}>```
Fetch and update an object
class Customer
include ActiveModel::Validations
include Crm::Helpers::Attributes
represents_crm_type :contact
crm_attr_accessor :first_name, :last_name, :email
validates_with Crm::Helpers::Validators::CrmTypeValidator
def self.find(crm_id)
crm_contact = Crm::Contact.find(crm_id)
return nil if crm_contact.nil?
new(crm_contact.attributes)
end
def initialize(attributes = {})
@crm_attributes = attributes.dup
end
def save
return false if invalid?
crm_contact = Crm::Contact.find(crm_id)
crm_contact.update(crm_attributes)
@crm_attributes = crm_contact.attributes
true
end
end
customer = Customer.find('fc851ba935f8420824498aee739ac897')
# => #<Customer>
customer.last_name
# => "Dinh"
customer.first_name
# => "Huy"
customer.last_name = 'Smith'
# => "Smith"
customer.first_name = 'John'
# => "John"
customer.save
# true
same_customer = Customer.find('fc851ba935f8420824498aee739ac897')
# => #<Customer>
same_customer.last_name
# => "Smith"
same_customer.first_name
# => "John"
Validators
Each CRM attribute type has its own validator:
Crm::Helpers::Validators::CrmBooleanValidator
Crm::Helpers::Validators::CrmDatetimeValidator
Crm::Helpers::Validators::CrmEnumValidator
Crm::Helpers::Validators::CrmIntegerValidator
Crm::Helpers::Validators::CrmListValidator
Crm::Helpers::Validators::CrmMultienumValidator
Crm::Helpers::Validators::CrmStringValidator
Crm::Helpers::Validators::CrmTextValidator
You can use those to explicitly validate attributes for a certain format.
validates_with Crm::Helpers::Validators::CrmBooleanValidator,
attributes: [:custom_has_ps4, :custom_has_xbox_one]
Finders
class Customer
include ActiveModel::Validations
include Crm::Helpers::Attributes
include Crm::Helpers::Finders
represents_crm_type :contact
crm_attr_accessor :first_name, :last_name, :email
validates_with Crm::Helpers::Validators::CrmTypeValidator
def initialize(attributes = {})
@crm_attributes = attributes.dup
end
end
customer = Customer.find('fc851ba935f8420824498aee739ac897')
# => #<Customer>
Persistence
class Customer
include ActiveModel::Validations
include Crm::Helpers::Attributes
include Crm::Helpers::Persistence
represents_crm_type :contact
crm_attr_accessor :first_name, :last_name, :email
validates_with Crm::Helpers::Validators::CrmTypeValidator
def initialize(attributes = {})
@crm_attributes = attributes.dup
end
end
customer = Customer.create(language: 'en', last_name: 'Dinh')
# => #<Customer>
customer.language = 'de'
# => 'de'
customer.save
# => true
customer.update(language: 'en')
# => true
customer.destroy
# => #<Customer>