infopark_crm_connector 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/CHANGELOG.rdoc +87 -0
  2. data/LICENSE +1 -0
  3. data/README.rdoc +59 -0
  4. data/lib/crm_connector.rb +72 -0
  5. data/lib/crm_connector/account.rb +4 -0
  6. data/lib/crm_connector/activity.rb +5 -0
  7. data/lib/crm_connector/base.rb +4 -0
  8. data/lib/crm_connector/configuration.rb +27 -0
  9. data/lib/crm_connector/contact.rb +5 -0
  10. data/lib/crm_connector/core.rb +7 -0
  11. data/lib/crm_connector/core/base.rb +111 -0
  12. data/lib/crm_connector/core/continuation_support.rb +44 -0
  13. data/lib/crm_connector/core/enumerator.rb +50 -0
  14. data/lib/crm_connector/core/known_attributes.rb +8 -0
  15. data/lib/crm_connector/core/resource.rb +44 -0
  16. data/lib/crm_connector/core/search_support.rb +21 -0
  17. data/lib/crm_connector/custom_type.rb +7 -0
  18. data/lib/crm_connector/debugging.rb +21 -0
  19. data/lib/crm_connector/default.rb +7 -0
  20. data/lib/crm_connector/default/account.rb +30 -0
  21. data/lib/crm_connector/default/activity.rb +54 -0
  22. data/lib/crm_connector/default/contact.rb +112 -0
  23. data/lib/crm_connector/default/custom_type.rb +24 -0
  24. data/lib/crm_connector/default/event.rb +23 -0
  25. data/lib/crm_connector/default/event_contact.rb +57 -0
  26. data/lib/crm_connector/default/mailing.rb +33 -0
  27. data/lib/crm_connector/default/resource.rb +10 -0
  28. data/lib/crm_connector/default/role.rb +9 -0
  29. data/lib/crm_connector/event.rb +4 -0
  30. data/lib/crm_connector/event_contact.rb +4 -0
  31. data/lib/crm_connector/inheriting_resource.rb +30 -0
  32. data/lib/crm_connector/mailing.rb +4 -0
  33. data/lib/crm_connector/resource.rb +15 -0
  34. data/lib/crm_connector/role.rb +4 -0
  35. data/lib/crm_connector/system.rb +29 -0
  36. data/lib/infopark_crm_connector.rb +1 -0
  37. metadata +150 -0
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,87 @@
1
+ === Version 0.9.2 - 2012-03-19
2
+ * Security improvement for +Contact.authenticate+, +Contact.password_set+ and +contact.password_request+
3
+
4
+ === Version 0.9.1 - 2012-02-28
5
+ * Removed +Diary+. Please use +Activity+ instead.
6
+ * Added +Mailing+
7
+ * Added +appointment_*+ and +task_*+ fields to +Activity+
8
+ * Added +role_names+ field to +Contact+
9
+ * Added +tags+ field to +Activity+, +Account+ and +Contact+
10
+
11
+ === Version 0.9 - 2012-01-27
12
+ Initial Release of Infopark CRM Connector
13
+
14
+ ==== Changes from OMC Connector to CRM Connector
15
+ * Namespace changed from <tt>OmcConector::</tt> to <tt>Infopark::Crm::</tt>
16
+ * Attribute names may have changed. For new attributes please refer to {Webservice API}[https://www.infopark.de/2486249/70-Webservice-API].
17
+ * Works only with Infopark WebCRM.
18
+
19
+ ===== Changed configuration
20
+ * +live_server_groups_callback+ - replaces +contact_roles_callback+
21
+
22
+ ===== New classes
23
+ * +CustomType+
24
+ * +Role+
25
+ * +System+
26
+
27
+ ===== New methods
28
+ * +Account.search+
29
+ * +Activity.search+
30
+ * +Contact.search+
31
+ * +Event.search+
32
+ * +EventContact.search+
33
+ * +contact.live_server_groups+ - replaces +contact.roles+
34
+
35
+ ===== Removed classes
36
+ * +AccountCollection+
37
+ * +InquiryKind+ - use +CustomType+
38
+ * +InquiryLink+
39
+ * +Inquiry+ - use +Activity+
40
+ * +Location+ - use +contact+ and +account+ properties
41
+ * +Mailing+
42
+ * +RegistrationInquiry+
43
+ * +Session+
44
+
45
+
46
+ ===== Removed methods
47
+ * +account.contacts+ - use <tt>Contact.search(\:params => {\:acount_id => acount_id})</tt>
48
+ * +Account.find_by_name+ - use +Account.search+
49
+ * +account.inquiries+ - use <tt>Activity.search(:params => {:account_id => account_id})</tt>
50
+ * +account.locations+
51
+ * +contact.account_activities+ - use <tt>Activity.search(:query => {:account_id => account_id})</tt>
52
+ * +contact.activities+ - use <tt>Activity.search(:params => {:contact_id => contact_id})</tt>
53
+ * +contact.create_activity+
54
+ * +contact.create_diary+
55
+ * +contact.create_location_with_account_association+
56
+ * +contact.create_location+
57
+ * +contact.create_registration_request+
58
+ * +contact.event_participation+
59
+ * +contact.find_activity+
60
+ * +Contact.find_by_email+ - use <tt>Contact.search(:params => {:email => email})</tt>
61
+ * +Contact.find_by_login+ - use <tt>Contact.search(:params => {:login => login})</tt>
62
+ * +Contact.languages+
63
+ * +contact.location+
64
+ * +Contact.lookup_uptions+
65
+ * +contact.move_location+
66
+ * +contact.roles+ - use +contact.live_server_groups+
67
+ * +contact.serialized_attributes+ - use +contact.attributes+
68
+ * +contact.subscriptions+
69
+ * +Contact.titles+
70
+ * +contact.update_location+
71
+ * +contact.update_subscriptions+
72
+ * +contact.validate_login+ - use <tt>Contact.search(:params => {:login => login})</tt>
73
+ * <tt>event.attend(!)</tt>
74
+ * +event.contacts+ - use <tt>EventContact.search(:event_id => event_id)</tt>
75
+ * +Event.find_by_name+
76
+ * <tt>event.inquire(!)</tt>
77
+ * <tt>event.refuse(!)</tt>
78
+ * <tt>event.register(!)</tt>
79
+ * +event_contact.attend+ - use <tt>event_contact.status = 'attended'</tt>
80
+ * +event_contact.inquire+ - use <tt>event_contact.status = 'unregistered'</tt>
81
+ * +event_contact.refuse+ - use <tt>event_contact.status = 'refused'</tt>
82
+ * +event_contact.register+ - use <tt>event_contact.status = 'registered'</tt>
83
+ * +event_contact.update_details+
84
+ * +inquiry.create_diary+
85
+ * +inquiry.create_link+
86
+ * +inquiry.diaries+
87
+ * +inquiry.links+
data/LICENSE ADDED
@@ -0,0 +1 @@
1
+ Copyright (c) 2009 - 2012 Infopark AG (http://www.infopark.com)
data/README.rdoc ADDED
@@ -0,0 +1,59 @@
1
+
2
+ ==Quick Start
3
+
4
+ gem 'infopark_crm_connector'
5
+
6
+ require 'infopark_crm_connector'
7
+
8
+ Infopark::Crm.configure do |configuration|
9
+ configuration.url = "https://webcrm.server/url"
10
+ configuration.login = "webcrm_user"
11
+ configuration.api_key = "api_key_of_webcrm_user"
12
+ end
13
+
14
+ # Communicate with the WebCRM
15
+ Infopark::Crm::Contact.first.last_name
16
+
17
+ See Infopark::Crm.configure for a complete list of configuration keys.
18
+
19
+ The subclasses of Infopark::Crm::Resource (which itself inherits from
20
+ ActiveResource::Base) represent the WebCRM's domain models (accounts, contacts, events etc.).
21
+
22
+ ==Examples
23
+ ===Contact
24
+ # Retrieve the contact identified by the login 'root'
25
+ contact = Infopark::Crm::Contact.search(:params => {:login => 'root'}).first
26
+
27
+ # Change this contact's mail address
28
+ contact.update_attribute(:email, 'root@example.com')
29
+
30
+ # Send a new password request mail to the contact's address
31
+ contact.password_request
32
+
33
+ ===Activity
34
+
35
+ # Configure a new activity kind
36
+ Infopark::Crm::CustomType.create(:name => 'contact form', :kind => 'Activity',
37
+ :states => ['new'])
38
+
39
+ # Create a new activity
40
+ activity = Infopark::Crm::Activity.new(:kind => 'contact form')
41
+
42
+ # Set properties of this activity
43
+ activity.title = 'Sprechen Sie Deutsch?'
44
+
45
+ # Switch to a different request locale
46
+ Infopark::Crm.configure {|c| c.locale = 'de'}
47
+
48
+ # Post the activity (which is going to fail)
49
+ activity.save
50
+ # => false
51
+
52
+ # Get to know what's missing
53
+ activity.errors.messages
54
+ # => {:state=>["ist kein gültiger Wert"]}
55
+
56
+ For further information on the WebCRM web service, have a look at
57
+ {this documentation}[https://www.infopark.com/2486249/70-Webservice-API].
58
+
59
+ :include: LICENSE
@@ -0,0 +1,72 @@
1
+ require 'active_resource'
2
+ require 'active_support/core_ext/string/conversions'
3
+
4
+ module Infopark; module Crm
5
+ def self.setup_autoload(mod, mod_source)
6
+ dir = File.expand_path(".", mod_source)[0..-4] # - ".rb"
7
+ pattern = "#{dir}/*.rb"
8
+ Dir.glob(pattern).each do |file|
9
+ file = file[0..-4]
10
+ const = "#{file[dir.length..-1]}".gsub(%r{[_/](.)}) {$1.upcase}
11
+ mod.autoload const.to_sym, file
12
+ end
13
+ end
14
+
15
+ setup_autoload(self, __FILE__)
16
+
17
+ # exceptions (defined elsewhere)
18
+ autoload :AuthenticationFailed, File.expand_path('../crm_connector/core/base', __FILE__)
19
+
20
+ end; end
21
+
22
+ module Infopark; module Crm
23
+
24
+ # Configures the web service connection
25
+ #
26
+ # View {README}[link:README_rdoc.html] for a usage example.
27
+ #
28
+ # Supported configuration keys are:
29
+ # [url] the web service server url (schema, host, port, path (up to, but not including /api))
30
+ #
31
+ # [login] the login of a WebCRM user with an API key (web service credential)
32
+ #
33
+ # [api_key] the WebCRM user's valid api key (web service credential)
34
+ #
35
+ # [locale] The locale to use when sending requests to the server. Can be
36
+ # redefined at any time.
37
+ #
38
+ # Example:
39
+ #
40
+ # Infopark::Crm.configure do |configuration|
41
+ # configuration.locale = I18n.locale
42
+ # end
43
+ #
44
+ # Infopark::Crm::Contact.create.errors.full_messages
45
+ #
46
+ # [live_server_groups_callback] A custom definition of what the live_server_groups of
47
+ # a contact is. The provided lambda is called with the contact
48
+ # instance and must return an array of live_server_groups (strings)
49
+ #
50
+ # Example:
51
+ #
52
+ # Infopark::Crm.configure do |configuration|
53
+ # configuration.live_server_groups_callback = lambda {|contact|
54
+ # case contact.account.name
55
+ # when "MyCompany"
56
+ # %w(admin reader writer)
57
+ # else
58
+ # %w(reader)
59
+ # end
60
+ # }
61
+ # end
62
+ #
63
+ # [debug] When set to true, includes the module Debugging into every resource, which
64
+ # provides a logger method. Cannot be reverted by setting to +false+
65
+ #
66
+ def self.configure(&block)
67
+ yield Configuration
68
+
69
+ Core::Base.configure(Configuration)
70
+ end
71
+
72
+ end; end
@@ -0,0 +1,4 @@
1
+ module Infopark; module Crm
2
+ # This is an extendable class. See Default::Account for documentation
3
+ class Account < Default::Account; end
4
+ end; end
@@ -0,0 +1,5 @@
1
+ module Infopark; module Crm
2
+ # This is an extendable class. See Default::Activity for documentation
3
+ class Activity < Default::Activity; end
4
+ end; end
5
+
@@ -0,0 +1,4 @@
1
+ module Infopark; module Crm
2
+ class Base < Core::Base # :nodoc:
3
+ end
4
+ end; end
@@ -0,0 +1,27 @@
1
+ # :stopdoc:
2
+
3
+ require 'active_support/core_ext/class/attribute_accessors'
4
+
5
+ module Infopark; module Crm
6
+ class Configuration
7
+
8
+ cattr_accessor :api_key
9
+
10
+ cattr_accessor :login
11
+
12
+ cattr_accessor :url
13
+
14
+ cattr_accessor :locale
15
+
16
+ cattr_accessor :http_host
17
+
18
+ cattr_accessor :live_server_groups_callback
19
+
20
+ cattr_accessor :debug
21
+
22
+ self.login = "webservice"
23
+
24
+ self.live_server_groups_callback = lambda {|contact| []}
25
+
26
+ end
27
+ end; end
@@ -0,0 +1,5 @@
1
+ module Infopark; module Crm
2
+ # This is an extendable class. See Default::Contact for documentation
3
+ class Contact < Default::Contact; end
4
+ end; end
5
+
@@ -0,0 +1,7 @@
1
+ module Infopark
2
+ module Crm
3
+ module Core
4
+ Infopark::Crm.setup_autoload(self, __FILE__)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,111 @@
1
+ require 'active_support/core_ext/class/attribute_accessors'
2
+
3
+ module Infopark; module Crm
4
+ class ConnectorError < StandardError # :nodoc:
5
+ end
6
+
7
+ # Raised when a contact provides wrong credentials (token/password)
8
+ #
9
+ # This differs from the case when the web service api credentials are not accepted
10
+ # (an ActiveResource error is raised then)
11
+ class AuthenticationFailed < ConnectorError; end
12
+ end; end
13
+
14
+ module Infopark; module Crm; module Core
15
+ class Base < ActiveResource::Base # :nodoc: all
16
+
17
+ self.format = :json
18
+ self.include_root_in_json = true
19
+
20
+ cattr_accessor :locale
21
+ cattr_accessor :http_host
22
+
23
+ #--
24
+ # TBD: drop when ActiveResource 3.0 support is dropped
25
+ #++
26
+ class SchemaSupport
27
+ def self.schema_mapping
28
+ @schema_mapping ||= {}
29
+ end
30
+
31
+ def self.add(mapping)
32
+ schema_mapping.merge!(mapping)
33
+ end
34
+
35
+ def self.schema_type(type)
36
+ default_mapping = ::ActiveResource::Schema::KNOWN_ATTRIBUTE_TYPES
37
+ return type if default_mapping.include?(type.to_s)
38
+ return schema_mapping[type.to_sym]
39
+ end
40
+
41
+ add :text => :string
42
+ add :date => :string
43
+ add :boolean => nil
44
+ end
45
+
46
+ def self.schema=(definition)
47
+ ares_compatible_definition = {}
48
+ definition.each do |k, v|
49
+ ares_compatible_definition[k] = SchemaSupport.schema_type(v)
50
+ end
51
+ super(ares_compatible_definition)
52
+ end
53
+
54
+ #--
55
+ # TBD: remove when https://github.com/rails/rails/issues/2479 is done
56
+ #++
57
+ def self.delete(id, options = {})
58
+ connection.delete(element_path(id, options), headers)
59
+ end
60
+
61
+ def self.headers
62
+ headers = super
63
+ headers.merge!({"Accept-Language" => self.locale}) if self.locale
64
+ headers.merge!({"Host" => self.http_host}) if self.http_host
65
+ headers
66
+ end
67
+
68
+ def self.configure(configuration)
69
+ self.site = configuration.url + '/' if configuration.url
70
+ self.user = configuration.login
71
+ self.password = configuration.api_key
72
+ self.locale = configuration.locale
73
+ self.http_host = configuration.http_host
74
+ include Debugging if configuration.debug
75
+ end
76
+
77
+ # Support for field associatable errors (without humanized name guessing)
78
+ def errors
79
+ @errors ||= Errors.new(self)
80
+ end
81
+
82
+ class Errors < ActiveResource::Errors # :nodoc:
83
+ # TBD temporary patch from https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/5616
84
+ def from_json(json, save_cache = false)
85
+ errors = ActiveSupport::JSON.decode(json)
86
+ clear unless save_cache
87
+ errors.each do |attr_name, messages|
88
+ Array.wrap(messages).each { |message| add(attr_name.to_sym, message) }
89
+ end
90
+ end
91
+
92
+ def from_xml(xml, *args)
93
+ errors = Hash.from_xml(xml)['errors'] rescue {}
94
+ structured_errors = Array.wrap(errors['machine_readables'])
95
+ if structured_errors.first
96
+ clear unless args.first # see ActiveResource::Errors#from_array
97
+ structured_errors.each do |h|
98
+ h.each do |key, value|
99
+ add(key, value)
100
+ end
101
+ end
102
+ else
103
+ # legacy omc and simple rails responses
104
+ from_array(errors['error'] || [], *args)
105
+ end
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ end; end; end
@@ -0,0 +1,44 @@
1
+ # :stopdoc:
2
+ module Infopark; module Crm; module Core
3
+ module ContinuationSupport
4
+ def self.included(klass)
5
+ klass.extend(ClassMethods)
6
+ klass.has_continuation
7
+ end
8
+
9
+ module ClassMethods
10
+ def has_continuation
11
+ class << self
12
+ def find_every(options)
13
+ get_with_continuation(nil, options)
14
+ end
15
+
16
+ private
17
+
18
+ def get_with_continuation(prefix, options)
19
+ prefix_options, query_options = split_options(options[:params])
20
+ path = collection_path(prefix_options, query_options)
21
+ response = prefix ? get(prefix, query_options) : connection.get(path, headers)
22
+ response = format.decode(response.body) unless response.kind_of? Hash # = unless ActiveResource 3.0
23
+ response = {'results' => response} if response.kind_of? Array # fighting ActiveResource 3.1 magic
24
+ collection = instantiate_collection(response['results'] || [], prefix_options)
25
+ result = Core::Enumerator.new(collection, response['continuation_handle'], response['total']) { |yielder|
26
+ loop do
27
+ result.within_limit.each {|entity| yielder.yield entity}
28
+ break if result.continuation_handle.nil?
29
+ # get next page
30
+ query_options[:continuation_handle] = result.continuation_handle
31
+ path = collection_path(prefix_options, query_options)
32
+ response = prefix ? get(prefix, query_options) : connection.get(path, headers)
33
+ response = format.decode(response.body) unless response.kind_of? Hash # = unless ActiveResource 3.0
34
+ response = {'results' => response} if response.kind_of? Array # fighting ActiveResource 3.1 magic
35
+ collection = instantiate_collection(response['results'] || [], prefix_options)
36
+ result.update(collection, response['continuation_handle'], response['total'])
37
+ end
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end; end; end
@@ -0,0 +1,50 @@
1
+ require 'backports'
2
+
3
+ module Infopark; module Crm; module Core
4
+ # Transparent wrapper for the web service's continuation ability
5
+ class Enumerator < Enumerator
6
+ def initialize(collection, continuation_handle, size, &block) #:nodoc:
7
+ update(collection, continuation_handle, size)
8
+ super &block
9
+ end
10
+
11
+ # The +continuation_handle+ parameter to be passed to the next find or search request for
12
+ # programmatic paging
13
+ def continuation_handle
14
+ @continuation_handle
15
+ end
16
+
17
+ # The results of the last response as an array,
18
+ # the array's size is less than or equal to the +limit+ parameter value
19
+ def within_limit
20
+ @collection
21
+ end
22
+
23
+ ##
24
+ # :method: size
25
+ # The total count given by the last search response, if available.
26
+ # #size is undefined otherwise.
27
+ ##
28
+
29
+ #--
30
+ # Note: We don't want size to return nil for compatibility for count's behavior
31
+ #++
32
+ def update(collection, continuation_handle, size) # :nodoc:
33
+ @collection = collection
34
+ @continuation_handle = continuation_handle
35
+ @size = size
36
+ define_singleton_method(:size) {@size} if @size
37
+ end
38
+
39
+ def inspect #:nodoc:
40
+ "#{super.chop}, @within_limit=#{within_limit.inspect}" +
41
+ ", @continuation_handle=#{continuation_handle.inspect}>"
42
+ end
43
+
44
+ private
45
+
46
+ def rewind #:nodoc:
47
+ raise NotImplementedError
48
+ end
49
+ end
50
+ end; end; end
@@ -0,0 +1,8 @@
1
+ # :stopdoc:
2
+ module Infopark; module Crm; module Core
3
+ class KnownAttributes < Array
4
+ def include?(val)
5
+ val.start_with?('custom_') || super(val)
6
+ end
7
+ end
8
+ end; end; end
@@ -0,0 +1,44 @@
1
+ # :stopdoc:
2
+ require 'ostruct'
3
+
4
+ module Infopark; module Crm; module Core
5
+ class Resource < Infopark::Crm::Base
6
+ include Core::ContinuationSupport
7
+ include Core::SearchSupport
8
+
9
+ def self.site
10
+ Infopark::Crm::Base.site + 'api/'
11
+ end
12
+
13
+ @@deprecation_warnings = true
14
+ cattr_writer :deprecation_warnings
15
+
16
+ def self.deprecated(deprecated, hint = nil)
17
+ return unless @@deprecation_warnings
18
+ text = "[WebCrmConnector] #{deprecated} is deprecated."
19
+ text << " #{hint}" if hint
20
+ if defined?(Rails.logger)
21
+ Rails.logger.warn(text)
22
+ else
23
+ $stderr.puts(text)
24
+ end
25
+ end
26
+
27
+ def known_attributes
28
+ KnownAttributes.new(super)
29
+ end
30
+
31
+ # Inheritable Resources
32
+ def self.defines_webservice?
33
+ true
34
+ end
35
+
36
+ def self.inherited(sub)
37
+ super
38
+ sub.__send__(:include, InheritingResource) unless sub.defines_webservice?
39
+ end
40
+
41
+ # /Inheritable Resources
42
+ end
43
+
44
+ end; end; end
@@ -0,0 +1,21 @@
1
+ # :stopdoc:
2
+ module Infopark; module Crm; module Core
3
+ module SearchSupport
4
+ def self.included(klass)
5
+ klass.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ # adds a search method
11
+ def has_search
12
+ class << self
13
+ def search(options)
14
+ get_with_continuation(:search, options)
15
+ end
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end; end; end
@@ -0,0 +1,7 @@
1
+ module Infopark; module Crm
2
+ # This is an extendable class. See Default::CustomType for documentation
3
+ class CustomType < Default::CustomType
4
+ class CustomAttribute < Default::CustomType::CustomAttribute #:nodoc:
5
+ end
6
+ end
7
+ end; end
@@ -0,0 +1,21 @@
1
+ require 'logger'
2
+
3
+ module Infopark; module Crm
4
+ module Debugging
5
+
6
+ def logger
7
+ self.class.logger
8
+ end
9
+
10
+ def self.included(base)
11
+ base.logger ||= begin
12
+ logger = Logger.new(STDERR)
13
+ logger.progname = 'Infopark::Crm'
14
+ logger.level = Logger::INFO
15
+ logger
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ end; end
@@ -0,0 +1,7 @@
1
+ module Infopark
2
+ module Crm
3
+ module Default
4
+ Infopark::Crm.setup_autoload(self, __FILE__)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+ module Infopark; module Crm; module Default
2
+
3
+ class Account < Resource
4
+ ##
5
+ # :singleton-method: search
6
+ # ==== RESTful Web Service
7
+ # GET /api/accounts/search
8
+ # ==== Examples
9
+ # results = Infopark::Crm::Account.search(:params => {:account_group => account_group})
10
+ # results = Infopark::Crm::Account.search(:params => {:q => 'full-text search'})
11
+ has_search
12
+
13
+ self.schema = {
14
+ :account_group => :string,
15
+ :country => :string,
16
+ :extended_address => :string,
17
+ :home_page => :string,
18
+ :locality => :string,
19
+ :name => :string,
20
+ :org_name_address => :string,
21
+ :org_unit_address => :string,
22
+ :phone => :string,
23
+ :postalcode => :string,
24
+ :region => :string,
25
+ :street_address => :string,
26
+ :tags => :array,
27
+ :want_geo_location => :boolean,
28
+ }
29
+ end
30
+ end; end; end
@@ -0,0 +1,54 @@
1
+ require 'ostruct'
2
+
3
+ module Infopark; module Crm; module Default
4
+ class Activity < Resource
5
+ ##
6
+ # :singleton-method: search
7
+ # ==== RESTful Web Service
8
+ # GET /api/activity/search
9
+ # ==== Examples
10
+ # results = Infopark::Crm::Activity.search(:params => {:state => 'created'})
11
+ # results = Infopark::Crm::Activity.search(:params => {:kind => 'support case'})
12
+ # results = Infopark::Crm::Activity.search(:params => {:contact_id => cid})
13
+ # results = Infopark::Crm::Activity.search(:params => {:account_id => aid})
14
+ # results = Infopark::Crm::Activity.search(:params => {:q => 'full-text search'})
15
+ has_search
16
+
17
+ self.schema = {
18
+ :account_id => :string,
19
+ :appointment_contact_id => :string,
20
+ :appointment_dtend_at => :time,
21
+ :appointment_dtstart_at => :time,
22
+ :appointment_location => :string,
23
+ :comment_notes => :string,
24
+ :comment_published => :boolean,
25
+ :contact_id => :string,
26
+ :email_cc => :string,
27
+ :kind => :string,
28
+ :state => :string,
29
+ :tags => :array,
30
+ :task_due_at => :time,
31
+ :task_owner_id => :string,
32
+ :title => :string,
33
+ }
34
+
35
+ # Queries the WebCRM for the Contact with the id +contact_id+.
36
+ # Returns +nil+ if +contact_id+ is +nil+.
37
+ def contact
38
+ Infopark::Crm::Contact.find(contact_id) if contact_id
39
+ end
40
+
41
+ # Queries the WebCRM for the Account with the id +account_id+.
42
+ # Returns +nil+ if +account_id+ is +nil+.
43
+ def account
44
+ Infopark::Crm::Account.find(account_id) if account_id
45
+ end
46
+
47
+ # Queries the WebCRM for the CustomType with the id +kind+.
48
+ # Returns +nil+ if +kind+ is +nil+.
49
+ def custom_type
50
+ Infopark::Crm::CustomType.find(kind) if kind
51
+ end
52
+
53
+ end
54
+ end; end; end
@@ -0,0 +1,112 @@
1
+ module Infopark; module Crm; module Default
2
+ class Contact < Resource
3
+
4
+ ##
5
+ # :singleton-method: search
6
+ # ==== RESTful Web Service
7
+ # GET /api/contacts/search
8
+ # ==== Examples
9
+ # results = Infopark::Crm::Contact.search(:params => {:login => login})
10
+ # results = Infopark::Crm::Contact.search(:params => {:email => email})
11
+ # results = Infopark::Crm::Contact.search(:params => {:q => 'full-text search'})
12
+ has_search
13
+
14
+ self.schema = {
15
+ :account_id => :string,
16
+ :country => :string,
17
+ :email => :string,
18
+ :extended_address => :string,
19
+ :fax => :string,
20
+ :first_name => :string,
21
+ :gender => :string,
22
+ :job_title => :string,
23
+ :language => :string,
24
+ :last_name => :string,
25
+ :locality => :string,
26
+ :login => :string,
27
+ :mobile_phone => :string,
28
+ :name_prefix => :string,
29
+ :org_name_address => :string,
30
+ :org_unit_address => :string,
31
+ :phone => :string,
32
+ :postalcode => :string,
33
+ :region => :string,
34
+ :role_names => :array,
35
+ :street_address => :string,
36
+ :tags => :array,
37
+ :want_email => :boolean,
38
+ :want_geo_location => :boolean,
39
+ :want_phonecall => :boolean,
40
+ :want_snailmail => :boolean,
41
+ }
42
+
43
+ # Queries the WebCRM for the Account with the id +account_id+.
44
+ # Returns +nil+ if +account_id+ is +nil+.
45
+ def account
46
+ Infopark::Crm::Account.find(account_id) if account_id
47
+ end
48
+
49
+ # ==== RESTful Web Service
50
+ # POST /api/contacts/authenticate
51
+ def self.authenticate(login, password)
52
+ begin
53
+ response = post(:authenticate, {}, format.encode({:login => login, :password => password}))
54
+ result = format.decode(response.body)
55
+ return find(result['id']) if result.kind_of? Hash # ActiveResource 3.0
56
+ find(result)
57
+ rescue ActiveResource::ResourceInvalid
58
+ raise AuthenticationFailed
59
+ end
60
+ end
61
+
62
+ # ==== RESTful Web Service
63
+ # POST /api/contacts/password_set
64
+ def self.password_set(password, token)
65
+ response = post(:password_set, {}, format.encode({:password => password, :token => token}))
66
+ result = format.decode(response.body)
67
+ return result['message'] if result.kind_of? Hash # ActiveResource 3.0
68
+ result
69
+ end
70
+
71
+ #--
72
+ # ==== RESTful Web Service
73
+ # POST /api/contacts/:id/password_set
74
+ #--
75
+ # TBD: build this api and use it
76
+ #++
77
+ # Shortcut to set the password of this contact.
78
+ def password_set(password)
79
+ token = password_request(:params => {:only_get_token => true})
80
+ self.class.password_set(password, token)
81
+ end
82
+
83
+ # ==== RESTful Web Service
84
+ # GET /api/contacts/:id/password_request
85
+ #--
86
+ # TBD: return nil instead of message for default parameters?
87
+ #++
88
+ def password_request(options = {})
89
+ params = options[:params] || {}
90
+ response = post(:password_request, {}, self.class.format.encode(params))
91
+ result = self.class.format.decode(response.body)
92
+ return result.values.first if result.kind_of? Hash # ActiveResource 3.0
93
+ result
94
+ end
95
+
96
+ # Returns the live_server_groups of this contact as defined by Configuration.live_server_groups_callback
97
+ def live_server_groups
98
+ return @live_server_groups if defined?(@live_server_groups)
99
+ callback = Configuration.live_server_groups_callback
100
+ @live_server_groups = callback.call(self) if callback.respond_to?(:call)
101
+ raise "live_server_groups_callback: not defined or unexpected result!" unless @live_server_groups
102
+
103
+ @live_server_groups
104
+ end
105
+
106
+ # Overwrites live_server_groups, so live_server_groups_callback is not called for this object.
107
+ def live_server_groups=(value)
108
+ @live_server_groups = value
109
+ end
110
+
111
+ end
112
+ end; end; end
@@ -0,0 +1,24 @@
1
+ module Infopark; module Crm; module Default
2
+ class CustomType < Resource
3
+ self.schema = {
4
+ :custom_attributes => :hash,
5
+ :icon_css_class => :string,
6
+ :kind => :string,
7
+ :name => :string,
8
+ :states => :array,
9
+ }
10
+
11
+ class CustomAttribute < Resource #:nodoc:
12
+
13
+ self.include_root_in_json = false
14
+
15
+ #--
16
+ # TBD: this method is only needed until the deprecated Object#type is removed
17
+ # Better: define self.schema
18
+ #++
19
+ def type #:nodoc:
20
+ attributes['type']
21
+ end
22
+ end
23
+ end
24
+ end; end; end
@@ -0,0 +1,23 @@
1
+ module Infopark; module Crm; module Default
2
+ class Event < Resource
3
+ ##
4
+ # :singleton-method: search
5
+ # ==== RESTful Web Service
6
+ # GET /api/events/search
7
+ # ==== Examples
8
+ # results = Infopark::Crm::Event.search(:params => {:kind => kind})
9
+ # results = Infopark::Crm::Event.search(:params => {:event_set => event_set})
10
+ # results = Infopark::Crm::Event.search(:params => {:q => 'full-text search'})
11
+ has_search
12
+
13
+ self.schema = {
14
+ :details => :string,
15
+ :dtend_at => :time,
16
+ :dtstart_at => :time,
17
+ :event_set => :string,
18
+ :kind => :string,
19
+ :location => :string,
20
+ :title => :string,
21
+ }
22
+ end
23
+ end; end; end
@@ -0,0 +1,57 @@
1
+ module Infopark; module Crm; module Default
2
+ class EventContact < Resource
3
+
4
+ ##
5
+ # :singleton-method: search
6
+ # ==== RESTful Web Service
7
+ # GET /api/event_contacts/search
8
+ # ==== Examples
9
+ # results = Infopark::Crm::EventContacts.search(:params => {:event_id => eid})
10
+ # results = Infopark::Crm::EventContacts.search(:params => {:contact_id => cid})
11
+ # results = Infopark::Crm::EventContacts.search(:params => {:state => state})
12
+ # results = Infopark::Crm::EventContacts.search(:params => {:q => 'full-text search'})
13
+ has_search
14
+
15
+ self.schema = {
16
+ :state => :string,
17
+ :contact_id => :string,
18
+ :event_id => :string,
19
+ }
20
+
21
+ # Queries the WebCRM for the Contact with the id +contact_id+.
22
+ # Returns +nil+ if +contact_id+ is +nil+.
23
+ def contact
24
+ Infopark::Crm::Contact.find(contact_id) if contact_id
25
+ end
26
+
27
+ # Queries the WebCRM for the Event with the id +event_id+.
28
+ # Returns +nil+ if +event_id+ is +nil+.
29
+ def event
30
+ Infopark::Crm::Event.find(event_id) if event_id
31
+ end
32
+
33
+ # ==== DEPRECATED
34
+ # Please use +search+ instead.
35
+ # ==== RESTful Web Service
36
+ # GET /api/event_contacts/find_all_by_event_id_and_state
37
+ # ==== Examples
38
+ # results = Infopark::Crm::EventContacts.find_by(:params => {:event_id => id})
39
+ # count = Infopark::Crm::EventContacts.find_by(:params => {:event_id => id}).size
40
+ def self.find_by(options)
41
+ deprecated('EventContact.find_by', 'please use EventContact.search')
42
+ get_with_continuation(:find_all_by_event_id_and_state, options)
43
+ end
44
+
45
+ # ==== DEPRECATED
46
+ # Please use +search+ instead.
47
+ # ==== RESTful Web Service
48
+ # GET /api/event_contacts/find_by_event_id_and_contact_id
49
+ # ==== Examples
50
+ # result = Infopark::Crm::EventContacts.find_by_event_id_and_contact_id(e_id, c_id))
51
+ def self.find_by_event_id_and_contact_id(event_id, contact_id)
52
+ deprecated('EventContact.find_by_event_id_and_contact_id', 'please use EventContact.search')
53
+ find(:find_by_event_id_and_contact_id, :params => {:event_id => event_id, :contact_id => contact_id})
54
+ end
55
+
56
+ end
57
+ end; end; end
@@ -0,0 +1,33 @@
1
+ module Infopark; module Crm; module Default
2
+ class Mailing < Resource
3
+
4
+ ##
5
+ # :singleton-method: search
6
+ # ==== RESTful Web Service
7
+ # GET /api/mailing/search
8
+ # ==== Examples
9
+ # results = Infopark::Crm::Mailing.search(:params => {:event_id => event_id})
10
+ # results = Infopark::Crm::Mailing.search(:params => {:only_unreleased => true})
11
+ # results = Infopark::Crm::Mailing.search(:params => {:q => 'full-text search'})
12
+ has_search
13
+
14
+ self.schema = {
15
+ :body => :string,
16
+ :dtstart_at => :time,
17
+ :email_from => :string,
18
+ :email_reply_to => :string,
19
+ :email_subject => :string,
20
+ :event_id => :string,
21
+ :html_body => :string,
22
+ :mailing_type => :string,
23
+ :title => :string,
24
+ }
25
+
26
+ # Queries the WebCRM for the Event with the id +event_id+.
27
+ # Returns +nil+ if +event_id+ is +nil+.
28
+ def event
29
+ Infopark::Crm::Event.find(event_id) if event_id
30
+ end
31
+ end
32
+
33
+ end; end; end
@@ -0,0 +1,10 @@
1
+ # :stopdoc:
2
+ module Infopark; module Crm
3
+ module Default
4
+ class Resource < Infopark::Crm::Resource
5
+ def self.defines_webservice?
6
+ to_s.start_with?("Infopark::Crm::Default")
7
+ end
8
+ end
9
+ end
10
+ end; end
@@ -0,0 +1,9 @@
1
+ module Infopark; module Crm; module Default
2
+ class Role < Resource
3
+ self.schema = {
4
+ :description => :string,
5
+ :name => :string,
6
+ :permissions => :array,
7
+ }
8
+ end
9
+ end; end; end
@@ -0,0 +1,4 @@
1
+ module Infopark; module Crm
2
+ # This is an extendable class. See Default::Event for documentation
3
+ class Event < Default::Event; end
4
+ end; end
@@ -0,0 +1,4 @@
1
+ module Infopark; module Crm
2
+ # This is an extendable class. See Default::EventContact for documentation
3
+ class EventContact < Default::EventContact; end
4
+ end; end
@@ -0,0 +1,30 @@
1
+ # :stopdoc:
2
+ module Infopark; module Crm
3
+ module InheritingResource
4
+ module ClassMethods
5
+ def element_name
6
+ superclass.element_name
7
+ end
8
+
9
+ def prefix(*args)
10
+ superclass.prefix(*args)
11
+ end
12
+
13
+ def collection_name
14
+ superclass.collection_name
15
+ end
16
+
17
+ def schema
18
+ superclass.schema
19
+ end
20
+
21
+ def known_attributes
22
+ superclass.known_attributes
23
+ end
24
+ end
25
+
26
+ def self.included(base)
27
+ base.extend(ClassMethods)
28
+ end
29
+ end
30
+ end; end
@@ -0,0 +1,4 @@
1
+ module Infopark; module Crm
2
+ # This is an extendable class. See Default::Mailing for documentation
3
+ class Mailing < Default::Mailing; end
4
+ end; end
@@ -0,0 +1,15 @@
1
+ module Infopark; module Crm
2
+ ##
3
+ # (Extendable) base class for every resource model
4
+ #
5
+ # Supports the ActiveResource::Base lifecycle methods, like
6
+ # * Resource.create(attributes)
7
+ # * Resource.new(attributes)
8
+ # * Resource.find(id)
9
+ # * resource.update_attributes(attributes)
10
+ # * resource.valid?
11
+ # * resource.save
12
+ #
13
+ # See the ActiveResource documentation for a detailed description.
14
+ class Resource < Core::Resource; end
15
+ end; end
@@ -0,0 +1,4 @@
1
+ module Infopark; module Crm
2
+ # This is an extendable class. See Default::Role for documentation
3
+ class Role < Default::Role; end
4
+ end; end
@@ -0,0 +1,29 @@
1
+ module Infopark; module Crm
2
+ # ==== Please note
3
+ # Implementation and naming may change
4
+ #--
5
+ # TBD sync with web service
6
+ #++
7
+ class System
8
+ def self.templates
9
+ response = base.connection.get(path, base.headers)
10
+ return response['templates'] if response.kind_of? Hash # ActiveResource 3.0
11
+ base.format.decode(response.body)
12
+ end
13
+
14
+ def self.templates=(hash)
15
+ data = {'templates' => hash}
16
+ base.connection.put(path, base.format.encode(data), base.headers)
17
+ end
18
+
19
+ private
20
+
21
+ def self.base #:nodoc:
22
+ Infopark::Crm::Resource
23
+ end
24
+
25
+ def self.path #:nodoc:
26
+ base.prefix + 'templates'
27
+ end
28
+ end
29
+ end; end
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'crm_connector')
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: infopark_crm_connector
3
+ version: !ruby/object:Gem::Version
4
+ hash: 63
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 9
9
+ - 2
10
+ version: 0.9.2
11
+ platform: ruby
12
+ authors:
13
+ - Infopark AG
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-04-18 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activeresource
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 5
29
+ segments:
30
+ - 3
31
+ version: "3"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: backports
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 5
43
+ segments:
44
+ - 2
45
+ - 3
46
+ version: "2.3"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: logger
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ description: Infopark CRM Connector
64
+ email: info@infopark.de
65
+ executables: []
66
+
67
+ extensions: []
68
+
69
+ extra_rdoc_files:
70
+ - README.rdoc
71
+ - LICENSE
72
+ files:
73
+ - CHANGELOG.rdoc
74
+ - LICENSE
75
+ - README.rdoc
76
+ - lib/crm_connector.rb
77
+ - lib/crm_connector/account.rb
78
+ - lib/crm_connector/activity.rb
79
+ - lib/crm_connector/base.rb
80
+ - lib/crm_connector/configuration.rb
81
+ - lib/crm_connector/contact.rb
82
+ - lib/crm_connector/core.rb
83
+ - lib/crm_connector/core/base.rb
84
+ - lib/crm_connector/core/continuation_support.rb
85
+ - lib/crm_connector/core/enumerator.rb
86
+ - lib/crm_connector/core/known_attributes.rb
87
+ - lib/crm_connector/core/resource.rb
88
+ - lib/crm_connector/core/search_support.rb
89
+ - lib/crm_connector/custom_type.rb
90
+ - lib/crm_connector/debugging.rb
91
+ - lib/crm_connector/default.rb
92
+ - lib/crm_connector/default/account.rb
93
+ - lib/crm_connector/default/activity.rb
94
+ - lib/crm_connector/default/contact.rb
95
+ - lib/crm_connector/default/custom_type.rb
96
+ - lib/crm_connector/default/event.rb
97
+ - lib/crm_connector/default/event_contact.rb
98
+ - lib/crm_connector/default/mailing.rb
99
+ - lib/crm_connector/default/resource.rb
100
+ - lib/crm_connector/default/role.rb
101
+ - lib/crm_connector/event.rb
102
+ - lib/crm_connector/event_contact.rb
103
+ - lib/crm_connector/inheriting_resource.rb
104
+ - lib/crm_connector/mailing.rb
105
+ - lib/crm_connector/resource.rb
106
+ - lib/crm_connector/role.rb
107
+ - lib/crm_connector/system.rb
108
+ - lib/infopark_crm_connector.rb
109
+ homepage: http://www.infopark.de
110
+ licenses: []
111
+
112
+ post_install_message:
113
+ rdoc_options:
114
+ - --charset
115
+ - UTF-8
116
+ - --main
117
+ - README.rdoc
118
+ - --title
119
+ - Infopark CRM Connector 0.9.2 Documentation
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ hash: 17
137
+ segments:
138
+ - 1
139
+ - 3
140
+ - 5
141
+ version: 1.3.5
142
+ requirements: []
143
+
144
+ rubyforge_project:
145
+ rubygems_version: 1.8.15
146
+ signing_key:
147
+ specification_version: 3
148
+ summary: Infopark CRM Connector
149
+ test_files: []
150
+