infopark_crm_connector 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
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
+