your_membership 1.1.0 → 1.1.1

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.env +5 -0
  3. data/.gitignore +1 -0
  4. data/.rspec +1 -0
  5. data/CHANGELOG.md +10 -0
  6. data/README.md +12 -10
  7. data/lib/httparty/patch.rb +33 -33
  8. data/lib/your_membership/base.rb +197 -197
  9. data/lib/your_membership/commerce.rb +25 -25
  10. data/lib/your_membership/config.rb +41 -41
  11. data/lib/your_membership/convert.rb +24 -24
  12. data/lib/your_membership/error.rb +21 -21
  13. data/lib/your_membership/events.rb +60 -60
  14. data/lib/your_membership/feeds.rb +37 -37
  15. data/lib/your_membership/member.rb +399 -397
  16. data/lib/your_membership/members.rb +124 -124
  17. data/lib/your_membership/people.rb +38 -38
  18. data/lib/your_membership/profile.rb +92 -85
  19. data/lib/your_membership/sa.rb +6 -6
  20. data/lib/your_membership/sa_auth.rb +34 -34
  21. data/lib/your_membership/sa_certifications.rb +22 -22
  22. data/lib/your_membership/sa_commerce.rb +22 -22
  23. data/lib/your_membership/sa_events.rb +66 -66
  24. data/lib/your_membership/sa_export.rb +195 -195
  25. data/lib/your_membership/sa_groups.rb +30 -30
  26. data/lib/your_membership/sa_member.rb +49 -49
  27. data/lib/your_membership/sa_members.rb +180 -179
  28. data/lib/your_membership/sa_nonmembers.rb +41 -41
  29. data/lib/your_membership/sa_people.rb +92 -92
  30. data/lib/your_membership/session.rb +148 -152
  31. data/lib/your_membership/version.rb +1 -1
  32. data/spec/fixtures/vcr_cassettes/sa_members_all_getids_timestamp_multiple.yml +51 -0
  33. data/spec/fixtures/vcr_cassettes/sa_members_all_getids_timestamp_none.yml +51 -0
  34. data/spec/fixtures/vcr_cassettes/sa_members_all_getids_timestamp_single.yml +51 -0
  35. data/spec/lib/{profile_spec.rb → your_membership/profile_spec.rb} +232 -197
  36. data/spec/lib/your_membership/sa_members_spec.rb +38 -0
  37. data/spec/spec_helper.rb +101 -78
  38. data/your_membership.gemspec +4 -0
  39. metadata +85 -19
@@ -1,124 +1,124 @@
1
- module YourMembership
2
- # YourMembership Members Namespace
3
- class Members < YourMembership::Base
4
- # Returns a member's connection category list.
5
- #
6
- # @see https://api.yourmembership.com/reference/2_00/Members_Connections_Categories_Get.htm
7
- #
8
- # @param [YourMembership::Session] session
9
- # @param [String] member_id or ProfileID of the member's connections to get.
10
- # @return [Array] Returns an Array of Hashes representing a member's connection categories.
11
- # @note If you attempt to retrieve a member's connection category list and they have not assigned any connections to
12
- # categories an execption of type 406 from YourMembership.com 'Method could not uniquely identify a record on which
13
- # to operate' will be raised.
14
- def self.connections_categories_get(session, member_id)
15
- options = {}
16
- options[:ID] = member_id
17
- response = post('/', :body => build_XML_request('Members.Connections.Categories.Get', session, options))
18
-
19
- response_valid? response
20
- response_to_array_of_hashes response['YourMembership_Response']['Members.Connections.Categories.Get'], ['Category']
21
- end
22
-
23
- # Returns a member's connection list, optionally filtered by category. Returns a maximum of 100 records per request.
24
- #
25
- # @see https://api.yourmembership.com/reference/2_00/Members_Connections_Get.htm
26
- #
27
- # @param [YourMembership::Session] session
28
- # @param [String] member_id or ProfileID of the member's connections to get.
29
- # @param [Hash] options
30
- # @option options [Integer] :CategoryID Filter the returned results by connection category.
31
- # @option options [Integer] :PageSize The maximum number of records in the returned result set.
32
- # @option options [Integer] :StartRecord The record number at which to start the returned result set.
33
- # @return [Array] Returns an Array of Hashes representing a member's connections.
34
- def self.connections_get(session, member_id, options = {})
35
- options = {}
36
- options[:ID] = member_id
37
- response = post('/', :body => build_XML_request('Members.Connections.Get', session, options))
38
-
39
- response_valid? response
40
- response_to_array_of_hashes response['YourMembership_Response']['Members.Connections.Get'], ['Connection']
41
- end
42
-
43
- # Returns a member's media gallery album list. The returned list will include <AlbumID>-1</AlbumID> which is a
44
- # virtual album containing all of the member's media gallery items.
45
- #
46
- # @see https://api.yourmembership.com/reference/2_00/Members_MediaGallery_Albums_Get.htm
47
- #
48
- # @param [YourMembership::Session] session
49
- # @param [String] member_id or ProfileID of the member whose media gallery albums to return.
50
- # @return [Array] Returns an Array of Hashes representing a member's albums.
51
- # @note BUG NOTED - This method seems to raise an exception on every call saying that Method Call Failed one or more
52
- # elements is missing or invalid
53
- # @todo Contact YourMembership.com dev team to see if we're doing this correctly.
54
- def self.mediaGallery_albums_get(session, member_id) # rubocop:disable Style/MethodName
55
- options = {}
56
- options[:ID] = member_id
57
- # puts build_XML_request('Members.MediaGallery.Albums.Get', session, options)
58
- response = post('/', :body => build_XML_request('Members.MediaGallery.Albums.Get', session, options))
59
-
60
- response_valid? response
61
- response_to_array_of_hashes response['YourMembership_Response']['Members.MediaGallery.Albums.Get'], ['Album']
62
- end
63
-
64
- # Returns a member's media gallery item list, optionally filtered by album. Returns a maximum of 100 records per
65
- # request.
66
- #
67
- # @see https://api.yourmembership.com/reference/2_00/Members_MediaGallery_Get.htm
68
- #
69
- # @param [YourMembership::Session] session
70
- # @param [String] member_id or ProfileID of the member whose media gallery to retrieve.
71
- # @param [Hash] options
72
- # @option options [String] :AlbumID Filter the returned results by media gallery album.
73
- # @option options [Integer] :PageSize The maximum number of records in the returned result set.
74
- # @option options [Integer] :StartRecord The record number at which to start the returned result set.
75
- # @return [Array] Returns an Array of Hashes representing a member's media items.
76
- # @note If you attempt to retrieve a member's gallery item list and they have no media an exception will be thrown
77
- # of type 406 from YourMembership.com 'Method could not uniquely identify a record on which to operate'
78
- def self.mediaGallery_get(session, member_id, options = {}) # rubocop:disable Style/MethodName
79
- options = {}
80
- options[:ID] = member_id
81
- response = post('/', :body => build_XML_request('Members.MediaGallery.Get', session, options))
82
-
83
- response_valid? response
84
- response_to_array_of_hashes response['YourMembership_Response']['Members.MediaGallery.Get'], ['Item']
85
- end
86
-
87
- # Returns a single media gallery item.
88
- #
89
- # @see https://api.yourmembership.com/reference/2_00/Members_MediaGallery_Item_Get.htm
90
- #
91
- # @param [YourMembership::Session] session
92
- # @param [String] member_id or ProfileID of the member whose media gallery item to return.
93
- # @param [Integer] item_id of the media gallery item to return.
94
- # @return [Hash] Returns an Hash that represents a single media item.
95
- def self.mediaGallery_item_get(session, member_id, item_id) # rubocop:disable Style/MethodName
96
- options = {}
97
- options[:ID] = member_id
98
- options[:ItemID] = item_id
99
- response = post('/', :body => build_XML_request('Members.MediaGallery.Item.Get', session, options))
100
-
101
- response_valid? response
102
- response['YourMembership_Response']['Members.MediaGallery.Item.Get']
103
- end
104
-
105
- # Returns a member's wall.
106
- #
107
- # @see https://api.yourmembership.com/reference/2_00/Members_Wall_Get.htm
108
- #
109
- # @param [YourMembership::Session] session
110
- # @param [String] member_id ID or ProfileID of the member's wall to get.
111
- # @param [Hash] options
112
- # @option options [Integer] :PageSize The maximum number of records in the returned result set.
113
- # @option options [Integer] :StartRecord The record number at which to start the returned result set.
114
- # @return [Hash] Returns a Hash representing the requested user's wall.
115
- def self.wall_get(session, member_id, options = {})
116
- options = {}
117
- options[:ID] = member_id
118
- response = post('/', :body => build_XML_request('Members.Wall.Get', session, options))
119
-
120
- response_valid? response
121
- response['YourMembership_Response']['Members.Wall.Get']
122
- end
123
- end
124
- end
1
+ module YourMembership
2
+ # YourMembership Members Namespace
3
+ class Members < YourMembership::Base
4
+ # Returns a member's connection category list.
5
+ #
6
+ # @see https://api.yourmembership.com/reference/2_00/Members_Connections_Categories_Get.htm
7
+ #
8
+ # @param [YourMembership::Session] session
9
+ # @param [String] member_id or ProfileID of the member's connections to get.
10
+ # @return [Array] Returns an Array of Hashes representing a member's connection categories.
11
+ # @note If you attempt to retrieve a member's connection category list and they have not assigned any connections to
12
+ # categories an execption of type 406 from YourMembership.com 'Method could not uniquely identify a record on which
13
+ # to operate' will be raised.
14
+ def self.connections_categories_get(session, member_id)
15
+ options = {}
16
+ options[:ID] = member_id
17
+ response = post('/', :body => build_XML_request('Members.Connections.Categories.Get', session, options))
18
+
19
+ response_valid? response
20
+ response_to_array_of_hashes response['YourMembership_Response']['Members.Connections.Categories.Get'], ['Category']
21
+ end
22
+
23
+ # Returns a member's connection list, optionally filtered by category. Returns a maximum of 100 records per request.
24
+ #
25
+ # @see https://api.yourmembership.com/reference/2_00/Members_Connections_Get.htm
26
+ #
27
+ # @param [YourMembership::Session] session
28
+ # @param [String] member_id or ProfileID of the member's connections to get.
29
+ # @param [Hash] options
30
+ # @option options [Integer] :CategoryID Filter the returned results by connection category.
31
+ # @option options [Integer] :PageSize The maximum number of records in the returned result set.
32
+ # @option options [Integer] :StartRecord The record number at which to start the returned result set.
33
+ # @return [Array] Returns an Array of Hashes representing a member's connections.
34
+ def self.connections_get(session, member_id, options = {})
35
+ options = {}
36
+ options[:ID] = member_id
37
+ response = post('/', :body => build_XML_request('Members.Connections.Get', session, options))
38
+
39
+ response_valid? response
40
+ response_to_array_of_hashes response['YourMembership_Response']['Members.Connections.Get'], ['Connection']
41
+ end
42
+
43
+ # Returns a member's media gallery album list. The returned list will include <AlbumID>-1</AlbumID> which is a
44
+ # virtual album containing all of the member's media gallery items.
45
+ #
46
+ # @see https://api.yourmembership.com/reference/2_00/Members_MediaGallery_Albums_Get.htm
47
+ #
48
+ # @param [YourMembership::Session] session
49
+ # @param [String] member_id or ProfileID of the member whose media gallery albums to return.
50
+ # @return [Array] Returns an Array of Hashes representing a member's albums.
51
+ # @note BUG NOTED - This method seems to raise an exception on every call saying that Method Call Failed one or more
52
+ # elements is missing or invalid
53
+ # @todo Contact YourMembership.com dev team to see if we're doing this correctly.
54
+ def self.mediaGallery_albums_get(session, member_id) # rubocop:disable Style/MethodName
55
+ options = {}
56
+ options[:ID] = member_id
57
+ # puts build_XML_request('Members.MediaGallery.Albums.Get', session, options)
58
+ response = post('/', :body => build_XML_request('Members.MediaGallery.Albums.Get', session, options))
59
+
60
+ response_valid? response
61
+ response_to_array_of_hashes response['YourMembership_Response']['Members.MediaGallery.Albums.Get'], ['Album']
62
+ end
63
+
64
+ # Returns a member's media gallery item list, optionally filtered by album. Returns a maximum of 100 records per
65
+ # request.
66
+ #
67
+ # @see https://api.yourmembership.com/reference/2_00/Members_MediaGallery_Get.htm
68
+ #
69
+ # @param [YourMembership::Session] session
70
+ # @param [String] member_id or ProfileID of the member whose media gallery to retrieve.
71
+ # @param [Hash] options
72
+ # @option options [String] :AlbumID Filter the returned results by media gallery album.
73
+ # @option options [Integer] :PageSize The maximum number of records in the returned result set.
74
+ # @option options [Integer] :StartRecord The record number at which to start the returned result set.
75
+ # @return [Array] Returns an Array of Hashes representing a member's media items.
76
+ # @note If you attempt to retrieve a member's gallery item list and they have no media an exception will be thrown
77
+ # of type 406 from YourMembership.com 'Method could not uniquely identify a record on which to operate'
78
+ def self.mediaGallery_get(session, member_id, options = {}) # rubocop:disable Style/MethodName
79
+ options = {}
80
+ options[:ID] = member_id
81
+ response = post('/', :body => build_XML_request('Members.MediaGallery.Get', session, options))
82
+
83
+ response_valid? response
84
+ response_to_array_of_hashes response['YourMembership_Response']['Members.MediaGallery.Get'], ['Item']
85
+ end
86
+
87
+ # Returns a single media gallery item.
88
+ #
89
+ # @see https://api.yourmembership.com/reference/2_00/Members_MediaGallery_Item_Get.htm
90
+ #
91
+ # @param [YourMembership::Session] session
92
+ # @param [String] member_id or ProfileID of the member whose media gallery item to return.
93
+ # @param [Integer] item_id of the media gallery item to return.
94
+ # @return [Hash] Returns an Hash that represents a single media item.
95
+ def self.mediaGallery_item_get(session, member_id, item_id) # rubocop:disable Style/MethodName
96
+ options = {}
97
+ options[:ID] = member_id
98
+ options[:ItemID] = item_id
99
+ response = post('/', :body => build_XML_request('Members.MediaGallery.Item.Get', session, options))
100
+
101
+ response_valid? response
102
+ response['YourMembership_Response']['Members.MediaGallery.Item.Get']
103
+ end
104
+
105
+ # Returns a member's wall.
106
+ #
107
+ # @see https://api.yourmembership.com/reference/2_00/Members_Wall_Get.htm
108
+ #
109
+ # @param [YourMembership::Session] session
110
+ # @param [String] member_id ID or ProfileID of the member's wall to get.
111
+ # @param [Hash] options
112
+ # @option options [Integer] :PageSize The maximum number of records in the returned result set.
113
+ # @option options [Integer] :StartRecord The record number at which to start the returned result set.
114
+ # @return [Hash] Returns a Hash representing the requested user's wall.
115
+ def self.wall_get(session, member_id, options = {})
116
+ options = {}
117
+ options[:ID] = member_id
118
+ response = post('/', :body => build_XML_request('Members.Wall.Get', session, options))
119
+
120
+ response_valid? response
121
+ response['YourMembership_Response']['Members.Wall.Get']
122
+ end
123
+ end
124
+ end
@@ -1,38 +1,38 @@
1
- module YourMembership
2
- # YourMembership People Namespace
3
- class People < YourMembership::Base
4
- # Returns paged results for a search request. Returns a maximum of 100 records per request.
5
- #
6
- # @see https://api.yourmembership.com/reference/2_00/People_All_Search.htm
7
- #
8
- # @param [YourMembership::Session] session
9
- # @param [Hash] options
10
- # @option options [String] :SearchText Text to be searched
11
- # @option options [Integer] :PageSize The maximum number of records in the returned result set.
12
- # @option options [Integer] :StartRecord The record number at which to start the returned result set.
13
- # @return [Array] Returns an Array of Hashes representing search results
14
- def self.all_search(session, options = {})
15
- response = post('/', :body => build_XML_request('People.All.Search', session, options))
16
-
17
- response_valid? response
18
- response_to_array_of_hashes response['YourMembership_Response']['People.All.Search'], ['Results', 'Item']
19
- end
20
-
21
- # Returns a person's profile data.
22
- #
23
- # @see https://api.yourmembership.com/reference/2_00/People_Profile_Get.htm
24
- #
25
- # @param [YourMembership::Session] session
26
- # @param [String] id ID or ProfileID of the person's whose profile data to return.
27
- # @return [YourMembership::Profile] Returns a Profile object that represents the person's profile
28
- def self.profile_get(session, id)
29
- options = {}
30
- options['ID'] = id
31
-
32
- response = post('/', :body => build_XML_request('People.Profile.Get', session, options))
33
-
34
- response_valid? response
35
- YourMembership::Profile.new response['YourMembership_Response']['People.Profile.Get']
36
- end
37
- end
38
- end
1
+ module YourMembership
2
+ # YourMembership People Namespace
3
+ class People < YourMembership::Base
4
+ # Returns paged results for a search request. Returns a maximum of 100 records per request.
5
+ #
6
+ # @see https://api.yourmembership.com/reference/2_00/People_All_Search.htm
7
+ #
8
+ # @param [YourMembership::Session] session
9
+ # @param [Hash] options
10
+ # @option options [String] :SearchText Text to be searched
11
+ # @option options [Integer] :PageSize The maximum number of records in the returned result set.
12
+ # @option options [Integer] :StartRecord The record number at which to start the returned result set.
13
+ # @return [Array] Returns an Array of Hashes representing search results
14
+ def self.all_search(session, options = {})
15
+ response = post('/', :body => build_XML_request('People.All.Search', session, options))
16
+
17
+ response_valid? response
18
+ response_to_array_of_hashes response['YourMembership_Response']['People.All.Search'], ['Results', 'Item']
19
+ end
20
+
21
+ # Returns a person's profile data.
22
+ #
23
+ # @see https://api.yourmembership.com/reference/2_00/People_Profile_Get.htm
24
+ #
25
+ # @param [YourMembership::Session] session
26
+ # @param [String] id ID or ProfileID of the person's whose profile data to return.
27
+ # @return [YourMembership::Profile] Returns a Profile object that represents the person's profile
28
+ def self.profile_get(session, id)
29
+ options = {}
30
+ options['ID'] = id
31
+
32
+ response = post('/', :body => build_XML_request('People.Profile.Get', session, options))
33
+
34
+ response_valid? response
35
+ YourMembership::Profile.new response['YourMembership_Response']['People.Profile.Get']
36
+ end
37
+ end
38
+ end
@@ -1,85 +1,92 @@
1
- module YourMembership
2
- # The Profile object provides a convenient abstraction that encapsulates a person's profile allowing clear and concise
3
- # access to both the core fields provided by YourMembership and the custom fields added by site administrators
4
- #
5
- # A new profile for a new person should be instantiated through the create_new method
6
- #
7
- # A profile can be loaded by passing a hash directly to the initializer (Profile.new) method this can be useful in
8
- # creating a profile object from an API response
9
- #
10
- # A profile can be created empty or by passing a hash for standard and/or custom fields. This is useful for
11
- # updating an existing profile without changing unnecessary records.
12
- #
13
- # @attr_reader [Hash] data These are fields that are part of the core YourMembership profile implementation
14
- # @attr_reader [Hash] custom_data These are fields that are the ones added as Custom Fields to a YourMembership
15
- # Community
16
- class Profile
17
- attr_accessor :data, :custom_data
18
-
19
- # @param [Hash] options Initial Values for the profile.
20
- def initialize(options = {})
21
- @data = {}
22
- @custom_data = {}
23
-
24
- options.each do |k, v|
25
- if k == 'CustomFieldResponses'
26
- @custom_data = parse_custom_field_responses(v)
27
- else
28
- @data[k] = v
29
- end
30
- end
31
- end
32
-
33
- # Returns the full contents of the profile in a Hash without items that have a Nil value
34
- # @return [Hash]
35
- def to_h
36
- temp_data = clean @data
37
- temp_custom_data = clean @custom_data
38
- temp_data['CustomFieldResponses'] = temp_custom_data
39
- temp_data
40
- end
41
-
42
- # @param [String] last_name
43
- # @param [String] member_type_code
44
- # @param [String] email
45
- # @param [String] username
46
- # @param [String] password
47
- # @param [Hash] options
48
- # @return [YourMembership::Profile] Builds a new profile with required and optional fields
49
- # @note: It has been found that for some users you must also specify a 'Membership' field as well as the
50
- # 'MemberTypeCode' The official documentation does not say this field is required but many times the user
51
- # cannot log in if no membership is provided. This means that the system cannot masquerade as this user until a
52
- # membership is specified.
53
- def self.create_new(first_name, last_name, member_type_code, email, username, password, options = {})
54
- options['FirstName'] = first_name
55
- options['LastName'] = last_name
56
- options['MemberTypeCode'] = member_type_code
57
- options['EmailAddr'] = email
58
- options['Username'] = username
59
- options['Password'] = password
60
- new(options)
61
- end
62
-
63
- private
64
-
65
- # @param [Hash] custom_fields The 'CustomFieldResponses' Hash
66
- # @return [Hash] Single dimension hash containing keys and values as strings or arrays
67
- def parse_custom_field_responses(custom_fields)
68
- output_hash = {}
69
- custom_fields['CustomFieldResponse'].each do |field|
70
- output_hash[field['FieldCode']] = field['Values']['Value'] if field['Values']
71
- end
72
- output_hash
73
- end
74
-
75
- # Removes nil values
76
- def clean(data_hash)
77
- clean_hash = {}
78
- # Remove Nils
79
- data_hash.each do |k, v|
80
- clean_hash[k] = v if v
81
- end
82
- clean_hash
83
- end
84
- end
85
- end
1
+ module YourMembership
2
+ # The Profile object provides a convenient abstraction that encapsulates a person's profile allowing clear and concise
3
+ # access to both the core fields provided by YourMembership and the custom fields added by site administrators
4
+ #
5
+ # A new profile for a new person should be instantiated through the create_new method
6
+ #
7
+ # A profile can be loaded by passing a hash directly to the initializer (Profile.new) method this can be useful in
8
+ # creating a profile object from an API response
9
+ #
10
+ # A profile can be created empty or by passing a hash for standard and/or custom fields. This is useful for
11
+ # updating an existing profile without changing unnecessary records.
12
+ #
13
+ # @attr_reader [Hash] data These are fields that are part of the core YourMembership profile implementation
14
+ # @attr_reader [Hash] custom_data These are fields that are the ones added as Custom Fields to a YourMembership
15
+ # Community
16
+ class Profile
17
+ attr_accessor :data, :custom_data
18
+
19
+ # @param [Hash] options Initial Values for the profile.
20
+ def initialize(options = {})
21
+ @data = {}
22
+ @custom_data = {}
23
+
24
+ options.each do |k, v|
25
+ if k == 'CustomFieldResponses'
26
+ @custom_data = parse_custom_field_responses(v)
27
+ else
28
+ @data[k] = v
29
+ end
30
+ end
31
+ end
32
+
33
+ # Returns the full contents of the profile in a Hash without items that have a Nil value
34
+ # @return [Hash]
35
+ def to_h
36
+ temp_data = clean @data
37
+ temp_custom_data = clean @custom_data
38
+ temp_data['CustomFieldResponses'] = temp_custom_data
39
+ temp_data
40
+ end
41
+
42
+ # @param [String] last_name
43
+ # @param [String] member_type_code
44
+ # @param [String] email
45
+ # @param [String] username
46
+ # @param [String] password
47
+ # @param [Hash] options
48
+ # @return [YourMembership::Profile] Builds a new profile with required and optional fields
49
+ # @note: It has been found that for some users you must also specify a 'Membership' field as well as the
50
+ # 'MemberTypeCode' The official documentation does not say this field is required but many times the user
51
+ # cannot log in if no membership is provided. This means that the system cannot masquerade as this user until a
52
+ # membership is specified.
53
+ def self.create_new(first_name, last_name, member_type_code, email, username, password, options = {})
54
+ options['FirstName'] = first_name
55
+ options['LastName'] = last_name
56
+ options['MemberTypeCode'] = member_type_code
57
+ options['EmailAddr'] = email
58
+ options['Username'] = username
59
+ options['Password'] = password
60
+ new(options)
61
+ end
62
+
63
+ private
64
+
65
+ # @param [Hash] custom_fields The 'CustomFieldResponses' Hash
66
+ # @return [Hash] Single dimension hash containing keys and values as strings or arrays
67
+ def parse_custom_field_responses(custom_fields)
68
+ return {} unless custom_fields
69
+
70
+ # CustomFieldResponse may be an array (if multiple responses) or a hash
71
+ # (if single response). Make sure we're always dealing with an array.
72
+ responses = custom_fields['CustomFieldResponse']
73
+ responses = [responses] unless responses.is_a?(Array)
74
+
75
+ output_hash = {}
76
+ responses.each do |field|
77
+ output_hash[field['FieldCode']] = field['Values']['Value'] if field['Values']
78
+ end
79
+ output_hash
80
+ end
81
+
82
+ # Removes nil values
83
+ def clean(data_hash)
84
+ clean_hash = {}
85
+ # Remove Nils
86
+ data_hash.each do |k, v|
87
+ clean_hash[k] = v if v
88
+ end
89
+ clean_hash
90
+ end
91
+ end
92
+ end