capsule_crm 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/lib/capsule_crm/address.rb +4 -3
  4. data/lib/capsule_crm/associations/belongs_to.rb +2 -1
  5. data/lib/capsule_crm/associations/belongs_to_association.rb +19 -2
  6. data/lib/capsule_crm/associations/belongs_to_finder.rb +46 -0
  7. data/lib/capsule_crm/associations/has_many_association.rb +23 -9
  8. data/lib/capsule_crm/associations/has_many_proxy.rb +38 -4
  9. data/lib/capsule_crm/case.rb +33 -236
  10. data/lib/capsule_crm/configuration.rb +1 -1
  11. data/lib/capsule_crm/connection.rb +3 -0
  12. data/lib/capsule_crm/contactable.rb +1 -1
  13. data/lib/capsule_crm/country.rb +7 -13
  14. data/lib/capsule_crm/currency.rb +7 -13
  15. data/lib/capsule_crm/custom_field.rb +14 -54
  16. data/lib/capsule_crm/custom_field_definition.rb +36 -0
  17. data/lib/capsule_crm/email.rb +4 -3
  18. data/lib/capsule_crm/gettable.rb +11 -0
  19. data/lib/capsule_crm/hash_helper.rb +5 -0
  20. data/lib/capsule_crm/history.rb +37 -252
  21. data/lib/capsule_crm/milestone.rb +9 -9
  22. data/lib/capsule_crm/normalizer.rb +85 -0
  23. data/lib/capsule_crm/opportunity.rb +30 -271
  24. data/lib/capsule_crm/organization.rb +19 -197
  25. data/lib/capsule_crm/party.rb +13 -26
  26. data/lib/capsule_crm/persistence/configuration.rb +25 -0
  27. data/lib/capsule_crm/persistence/deletable.rb +14 -0
  28. data/lib/capsule_crm/persistence/persistable.rb +76 -0
  29. data/lib/capsule_crm/persistence.rb +3 -0
  30. data/lib/capsule_crm/person.rb +19 -194
  31. data/lib/capsule_crm/phone.rb +4 -3
  32. data/lib/capsule_crm/querying/configuration.rb +21 -0
  33. data/lib/capsule_crm/querying/find_all.rb +16 -0
  34. data/lib/capsule_crm/querying/find_one.rb +14 -0
  35. data/lib/capsule_crm/querying/findable.rb +14 -0
  36. data/lib/capsule_crm/querying.rb +4 -0
  37. data/lib/capsule_crm/serializable.rb +38 -0
  38. data/lib/capsule_crm/serializer.rb +54 -7
  39. data/lib/capsule_crm/task.rb +16 -96
  40. data/lib/capsule_crm/track.rb +5 -10
  41. data/lib/capsule_crm/user.rb +3 -15
  42. data/lib/capsule_crm/version.rb +1 -1
  43. data/lib/capsule_crm/website.rb +4 -2
  44. data/lib/capsule_crm.rb +15 -5
  45. data/spec/fabricators/case_fabricator.rb +1 -0
  46. data/spec/fabricators/history_fabricator.rb +1 -0
  47. data/spec/fabricators/opportunity_fabricator.rb +1 -0
  48. data/spec/lib/capsule_crm/associations/belongs_to_finder_spec.rb +48 -0
  49. data/spec/lib/capsule_crm/associations/belongs_to_spec.rb +34 -0
  50. data/spec/lib/capsule_crm/associations/has_many_proxy_spec.rb +54 -14
  51. data/spec/lib/capsule_crm/associations/has_many_spec.rb +15 -2
  52. data/spec/lib/capsule_crm/case_spec.rb +20 -330
  53. data/spec/lib/capsule_crm/country_spec.rb +1 -16
  54. data/spec/lib/capsule_crm/currency_spec.rb +1 -18
  55. data/spec/lib/capsule_crm/custom_field_definition_spec.rb +59 -0
  56. data/spec/lib/capsule_crm/custom_field_spec.rb +2 -27
  57. data/spec/lib/capsule_crm/history_spec.rb +14 -389
  58. data/spec/lib/capsule_crm/milestone_spec.rb +1 -23
  59. data/spec/lib/capsule_crm/normalizer_spec.rb +11 -0
  60. data/spec/lib/capsule_crm/opportunity_spec.rb +22 -341
  61. data/spec/lib/capsule_crm/organization_spec.rb +39 -60
  62. data/spec/lib/capsule_crm/party_spec.rb +37 -59
  63. data/spec/lib/capsule_crm/person_spec.rb +49 -247
  64. data/spec/lib/capsule_crm/serializer_spec.rb +25 -4
  65. data/spec/lib/capsule_crm/task_spec.rb +21 -250
  66. data/spec/lib/capsule_crm/track_spec.rb +1 -15
  67. data/spec/lib/capsule_crm/user_spec.rb +1 -14
  68. data/spec/support/{countries.json → all_countries.json} +0 -0
  69. data/spec/support/{currencies.json → all_currencies.json} +0 -0
  70. data/spec/support/{milestones.json → all_milestones.json} +0 -0
  71. data/spec/support/{tracks.json → all_tracks.json} +0 -0
  72. data/spec/support/custom_field_definitions.json +19 -0
  73. data/spec/support/helpers.rb +3 -2
  74. data/spec/support/no_cases.json +5 -0
  75. data/spec/support/no_countries.json +5 -0
  76. data/spec/support/no_currencies.json +5 -0
  77. data/spec/support/no_milestones.json +5 -0
  78. data/spec/support/no_opportunities.json +5 -0
  79. data/spec/support/no_tasks.json +5 -0
  80. data/spec/support/no_tracks.json +5 -0
  81. data/spec/support/no_users.json +5 -0
  82. data/spec/support/shared_examples/deletable.rb +15 -0
  83. data/spec/support/shared_examples/find_all.rb +34 -0
  84. data/spec/support/shared_examples/find_one.rb +23 -0
  85. data/spec/support/shared_examples/persistable.rb +318 -0
  86. data/spec/support/single_person.json +16 -0
  87. metadata +60 -15
  88. data/lib/capsule_crm/attributes.rb +0 -11
  89. data/lib/capsule_crm/capsule_jsonable.rb +0 -13
  90. data/lib/capsule_crm/collection.rb +0 -9
  91. data/spec/support/single_user.json +0 -25
@@ -7,8 +7,17 @@ module CapsuleCRM
7
7
  include ActiveModel::Validations
8
8
 
9
9
  include CapsuleCRM::Associations
10
- include CapsuleCRM::Attributes
11
- include CapsuleCRM::Collection
10
+ include CapsuleCRM::Querying::Configuration
11
+ include CapsuleCRM::Serializable
12
+
13
+ serializable_config do |config|
14
+ config.root = 'customField'
15
+ config.collection_root = 'customFields'
16
+ end
17
+
18
+ queryable_config do |config|
19
+ config.plural = 'customfields'
20
+ end
12
21
 
13
22
  attribute :id, Integer
14
23
  attribute :label, String
@@ -20,62 +29,13 @@ module CapsuleCRM
20
29
  validates :id, numericality: { allow_blank: true }
21
30
  validates :label, presence: true
22
31
 
23
- belongs_to :party, class_name: 'CapsuleCRM::Party'
24
-
25
- def self._for_party(party_id)
26
- init_collection(
27
- CapsuleCRM::Connection.
28
- get("/api/party/#{party_id}/customfields")['customFields'].
29
- fetch('customField', nil)
30
- )
31
- end
32
+ belongs_to :party
33
+ belongs_to :opportunity
34
+ belongs_to :case
32
35
 
33
36
  class << self
34
37
  alias :_for_organization :_for_party
35
38
  alias :_for_person :_for_party
36
39
  end
37
-
38
- def self.create(attributes = {})
39
- new(attributes).tap(&:save)
40
- end
41
-
42
- def self.create!(attribute = {})
43
- new(attributes).tap(&:save)
44
- end
45
-
46
- def save
47
- if valid?
48
- update_record
49
- else
50
- false
51
- end
52
- end
53
-
54
- def save!
55
- if valid?
56
- update_record
57
- else
58
- raise CapsuleCRM::Errors::RecordInvalid.new(self)
59
- end
60
- end
61
-
62
- def destroy
63
- end
64
-
65
- def to_capsule_json
66
- { 'customFields' => serializer.serialize }
67
- end
68
-
69
- private
70
-
71
- def serializer
72
- @serializer ||= CapsuleCRM::Serializer.new(self, root: 'customField')
73
- end
74
-
75
- def update_record
76
- CapsuleCRM::Connection.post(
77
- "/api/party/#{party.id}/customfields", to_capsule_json
78
- )
79
- end
80
40
  end
81
41
  end
@@ -0,0 +1,36 @@
1
+ module CapsuleCRM
2
+ class CustomFieldDefinition
3
+ include Virtus
4
+ include CapsuleCRM::Serializable
5
+ include CapsuleCRM::Gettable
6
+
7
+ serializable_config do |config|
8
+ config.collection_root = :customFieldDefinitions
9
+ config.root = :customFieldDefinition
10
+ end
11
+
12
+ attribute :id, Integer
13
+ attribute :tag, String
14
+ attribute :label, String
15
+ attribute :type, String
16
+ attribute :options, String
17
+
18
+ def self.for_parties
19
+ normalizer.normalize_collection get('/api/party/customfield/definitions')
20
+ end
21
+
22
+ def self.for_opportunities
23
+ normalizer.normalize_collection(
24
+ get('/api/opportunity/customfield/definitions')
25
+ )
26
+ end
27
+
28
+ def self.for_cases
29
+ normalizer.normalize_collection get('/api/kase/customfield/definitions')
30
+ end
31
+
32
+ def self.normalizer
33
+ @normalizer ||= CapsuleCRM::Normalizer.new(self)
34
+ end
35
+ end
36
+ end
@@ -1,11 +1,12 @@
1
1
  module CapsuleCRM
2
2
  class Email
3
3
  include Virtus
4
-
4
+ include CapsuleCRM::Serializable
5
5
  extend ActiveModel::Naming
6
- include ActiveModel::Serializers::JSON
7
6
 
8
- include CapsuleCRM::CapsuleJsonable
7
+ serializable_config do |config|
8
+ config.include_root = false
9
+ end
9
10
 
10
11
  attribute :type
11
12
  attribute :email_address
@@ -0,0 +1,11 @@
1
+ module CapsuleCRM
2
+ module Gettable
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def get(path)
7
+ CapsuleCRM::Connection.get(path)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -8,6 +8,11 @@ module CapsuleCRM
8
8
  end
9
9
  end
10
10
 
11
+ def self.underscore_keys(hash)
12
+ underscore_keys!(hash)
13
+ hash
14
+ end
15
+
11
16
  def self.camelize_keys!(hash)
12
17
  hash.keys.each do |key|
13
18
  hash[key.to_s.camelize(:lower)] = hash.delete(key)
@@ -7,8 +7,26 @@ module CapsuleCRM
7
7
  include ActiveModel::Validations
8
8
 
9
9
  include CapsuleCRM::Associations
10
- include CapsuleCRM::Attributes
11
- include CapsuleCRM::Collection
10
+ include CapsuleCRM::Persistence::Persistable
11
+ include CapsuleCRM::Persistence::Deletable
12
+ include CapsuleCRM::Querying::Configuration
13
+ include CapsuleCRM::Querying::FindOne
14
+ include CapsuleCRM::Serializable
15
+
16
+ persistable_config do |config|
17
+ config.create = lambda do |history|
18
+ "#{history.belongs_to_api_name}/#{history.belongs_to_id}/history"
19
+ end
20
+ end
21
+
22
+ serializable_config do |config|
23
+ config.root = :historyItem
24
+ config.collection_root = :history
25
+ end
26
+
27
+ queryable_config do |config|
28
+ config.plural = :history
29
+ end
12
30
 
13
31
  attribute :id, Integer
14
32
  attribute :type, String
@@ -16,63 +34,25 @@ module CapsuleCRM
16
34
  attribute :subject, String
17
35
  attribute :note, String
18
36
 
19
- has_many :attachments, class_name: 'CapsuleCRM::Attachment'
20
- has_many :participants, class_name: 'CapsuleCRM::Participant'
37
+ has_many :attachments
38
+ has_many :participants
21
39
 
22
- belongs_to :creator, class_name: 'CapsuleCRM::Person',
23
- serializable_key: :creator
24
- belongs_to :party, class_name: 'CapsuleCRM::Party', serialize: false
25
- belongs_to :kase, class_name: 'CapsuleCRM::Case',
26
- foreign_key: :case_id, serialize: false
27
- belongs_to :opportunity, class_name: 'CapsuleCRM::Opportunity',
28
- serialize: false
40
+ belongs_to :creator, serializable_key: :creator,
41
+ class_name: 'CapsuleCRM::Person'
42
+ belongs_to :party, serialize: false
43
+ belongs_to :case, serialize: false
44
+ belongs_to :opportunity, serialize: false
29
45
 
30
46
  validates :id, numericality: { allow_blank: true }
31
47
  validates :note, presence: true
32
- validates :party, :kase, :opportunity,
48
+ validates :party, :case, :opportunity,
33
49
  presence: { if: :belongs_to_required? }
34
50
 
35
- def self._for_party(party_id)
36
- init_collection(
37
- CapsuleCRM::Connection.
38
- get("/api/party/#{party_id}/history")['history'].
39
- fetch('historyItem', nil)
40
- )
41
- end
42
-
43
51
  class << self
44
52
  alias :_for_organization :_for_party
45
53
  alias :_for_person :_for_party
46
54
  end
47
55
 
48
- def self._for_case(case_id)
49
- init_collection(
50
- CapsuleCRM::Connection.
51
- get("/api/kase/#{case_id}/history")['history']['historyItem']
52
- )
53
- end
54
-
55
- def self._for_opportunity(opportunity_id)
56
- init_collection(
57
- CapsuleCRM::Connection.
58
- get("/api/opportunity/#{opportunity_id}/history")\
59
- ['history']['historyItem']
60
- )
61
- end
62
-
63
- # Public: find a CapsuleCRM::History by ID
64
- #
65
- # id - The Integer CapsuleCRM::History ID
66
- #
67
- # Examples
68
- #
69
- # CapsuleCRM::History.find(2)
70
- #
71
- # Returns a CapsuleCRM::History object
72
- def self.find(id)
73
- new CapsuleCRM::Connection.get("/api/history/#{id}")['historyItem']
74
- end
75
-
76
56
  # Public: Set the creator of this history item
77
57
  #
78
58
  # user - The String username OR a CapsuleCRM::User object
@@ -94,220 +74,25 @@ module CapsuleCRM
94
74
  self
95
75
  end
96
76
 
97
- # Public: create a CapsuleCRM::History item and persist it
98
- #
99
- # attributes - The Hash of attributes (default: {}):
100
- # :note - The String note
101
- # :creator - The CapsuleCRM::User who created this history
102
- # item
103
- # :entry_date - The date when this history item was created
104
- #
105
- # Examples
106
- #
107
- # CapsuleCRM::History.create(note: 'Some history note text')
108
- #
109
- # person = CapsuleCRM::User.find_by_username('some.username')
110
- # CapsuleCRM::History.create(
111
- # note: 'another note to add to the history', person: person,
112
- # entry_date: Time.now
113
- # )
114
- #
115
- # Returns a CapsuleCRM::History object
116
- def self.create(attributes = {})
117
- new(attributes).tap(&:save)
118
- end
119
-
120
- # Public: create a CapsuleCRM::History item and persist it. If persistence
121
- # is not possible then raise an error
122
- #
123
- # attributes - The Hash of attributes (default: {}):
124
- # :note - The String note
125
- # :creator - The CapsuleCRM::User who created this history
126
- # item
127
- # :entry_date - The date when this history item was created
128
- #
129
- # Examples
130
- #
131
- # CapsuleCRM::History.create!(note: 'Some history note text')
132
- #
133
- # person = CapsuleCRM::User.find_by_username('some.username')
134
- # CapsuleCRM::History.create!(
135
- # note: 'another note to add to the history', person: person,
136
- # entry_date: Time.now
137
- # )
138
- #
139
- # CapsuleCRM::History.create! {}
140
- # => CapsuleCRM::Errors::RecordInvalid
141
- #
142
- # Returns a CapsuleCRM::History object
143
- def self.create!(attributes = {})
144
- new(attributes).tap(&:save!)
145
- end
146
-
147
- # Public: update the attributes of a CapsuleCRM::History item and persist
148
- # the changes
149
- #
150
- # attributes - The Hash of attributes (default: {}):
151
- # :note - The String note
152
- # :creator - The String creator username OR
153
- # a CapsuleCRM::Person object
154
- # :entry_date - The DateTime when the history item was
155
- # created
156
- #
157
- # Examples
158
- #
159
- # history = CapsuleCRM::History.find(1)
160
- # history.update_attributes note: 'some updated note text'
161
- #
162
- # Returns a CapsuleCRM::History item or false
163
- def update_attributes(attributes = {})
164
- self.attributes = attributes
165
- save
166
- end
167
-
168
- # Public: update the attributes of a CapsuleCRM::History item and persist
169
- # the changes. If persistence is not possible then raise an error
170
- #
171
- # attributes - The Hash of attributes (default: {}):
172
- # :note - The String note
173
- # :creator - The String creator username OR
174
- # a CapsuleCRM::Person object
175
- # :entry_date - The DateTime when the history item was
176
- # created
177
- #
178
- # Examples
179
- #
180
- # history = CapsuleCRM::History.find(1)
181
- # history.update_attributes note: 'some updated note text'
182
- #
183
- # history.update_attributes note: nil
184
- # => CapsuleCRM::Errors::RecordInvalid
185
- #
186
- # Returns a CapsuleCRM::History item or a CapsuleCRM::Errors::RecordInvalid
187
- def update_attributes!(attributes = {})
188
- self.attributes = attributes
189
- save!
190
- end
191
-
192
- # Public: Save this history item. If it is already existing in capsule crm
193
- # then update it, otherwise create a new one
194
- #
195
- # Examples
196
- #
197
- # CapsuleCRM::History.new(note: 'some note text').save
198
- #
199
- # Returns a CapsuleCRM::History object of false
200
- def save
201
- if valid?
202
- new_record? ? create_record : update_record
203
- else
204
- false
205
- end
206
- end
207
-
208
- # Public: Save this history item. If it is already existing in capsule crm
209
- # then update it, otherwise create a new one. If persistence is not possible
210
- # then raise an error
211
- #
212
- # Examples
213
- #
214
- # CapsuleCRM::History.new(note: 'the note text').save!
215
- #
216
- # CapsuleCRM::History.new.save!
217
- # => CapsuleCRM::Errors::RecordInvalid
218
- #
219
- # Returns a CapsuleCRM::History object
220
- def save!
221
- if valid?
222
- new_record? ? create_record : update_record
223
- else
224
- raise CapsuleCRM::Errors::RecordInvalid.new(self)
225
- end
226
- end
227
-
228
- # Public: Delete this history item from capsule crm.
229
- #
230
- # Examples
231
- #
232
- # CapsuleCRM::History.find(1).destroy
233
- #
234
- # Returns the CapsuleCRM::History object
235
- def destroy
236
- self.id = nil if CapsuleCRM::Connection.delete("/api/history/#{id}")
237
- self
238
- end
239
-
240
- # Public: Is this history item a new record?
241
- #
242
- # Examples
243
- #
244
- # CapsuleCRM::History.new.new_record?
245
- # => true
246
- #
247
- # CapsuleCRM::History.find(1).new_record?
248
- # => false
249
- def new_record?
250
- !id
251
- end
252
-
253
- # Public: Is this history item persisted?
254
- #
255
- # Examples
256
- #
257
- # CapsuleCRM::History.new.persisted?
258
- # => fale
259
- #
260
- # CapsuleCRM::History.find(1).persisted?
261
- # => true
262
- def persisted?
263
- !new_record?
264
- end
265
-
266
- # Public: Generate the attributes hash to send to capsule
267
- #
268
- # Examples
269
- #
270
- # CapsuleCRM::History.find(1).to_capsule_json
271
- #
272
- # Returns a Hash of attributes
273
- def to_capsule_json
274
- serializer.serialize
275
- end
276
-
277
- private
278
-
279
- def serializer
280
- @serializer ||= CapsuleCRM::Serializer.new(self, root: :historyItem)
281
- end
282
-
283
- def belongs_to_required?
284
- party.blank? && kase.blank? && opportunity.blank?
285
- end
286
-
287
- def create_record
288
- self.attributes = CapsuleCRM::Connection.post(
289
- "/api/#{belongs_to_api_name}/#{belongs_to_id}/history", to_capsule_json
290
- )
291
- self
292
- end
293
-
294
77
  def belongs_to_api_name
295
78
  {
296
- person: 'party', organization: 'party', case: 'kase',
79
+ person: 'party', organization: 'party', case: 'case',
297
80
  opportunity: 'opportunity'
298
81
  }.stringify_keys[belongs_to_name]
299
82
  end
300
83
 
301
- def belongs_to_name
302
- (party || kase || opportunity).class.to_s.demodulize.downcase
84
+ def belongs_to_id
85
+ (party || self.case || opportunity).try(:id)
303
86
  end
304
87
 
305
- def belongs_to_id
306
- (party || kase || opportunity).id
88
+ private
89
+
90
+ def belongs_to_required?
91
+ party.blank? && self.case.blank? && opportunity.blank?
307
92
  end
308
93
 
309
- def update_record
310
- CapsuleCRM::Connection.put("/api/history/#{id}", to_capsule_json)
94
+ def belongs_to_name
95
+ (party || self.case || opportunity).class.to_s.demodulize.downcase
311
96
  end
312
97
  end
313
98
  end
@@ -1,8 +1,15 @@
1
1
  module CapsuleCRM
2
2
  class Milestone
3
- include Virtus
4
- include CapsuleCRM::Collection
5
3
  include ActiveModel::Validations
4
+ include Virtus
5
+
6
+ include CapsuleCRM::Querying::Configuration
7
+ include CapsuleCRM::Querying::FindAll
8
+ include CapsuleCRM::Serializable
9
+
10
+ queryable_config do |config|
11
+ config.plural = 'opportunity/milestones'
12
+ end
6
13
 
7
14
  attribute :id, Integer
8
15
  attribute :name, String
@@ -12,13 +19,6 @@ module CapsuleCRM
12
19
 
13
20
  validates :id, numericality: { allow_blank: true }
14
21
 
15
- def self.all
16
- init_collection(
17
- CapsuleCRM::Connection.
18
- get('/api/opportunity/milestones')['milestones']['milestone']
19
- )
20
- end
21
-
22
22
  def self.find(id)
23
23
  all.select { |item| item.id == id }.first
24
24
  end
@@ -0,0 +1,85 @@
1
+ module CapsuleCRM
2
+ class Normalizer
3
+ attr_reader :klass, :options
4
+
5
+ def initialize(klass, options = {})
6
+ @klass = klass
7
+ @options = options
8
+ end
9
+
10
+ def normalize(attrs = {})
11
+ subclasses? ? normalize_subclass(attrs) : normalize_single(attrs)
12
+ end
13
+
14
+ def normalize_collection(attrs)
15
+ if subclasses?
16
+ normalize_subclass_collection(attrs)
17
+ else
18
+ normalize_standard_collection(attrs)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def root
25
+ @root ||= options[:root] || klass.serializable_options.root
26
+ end
27
+
28
+ def collection_root
29
+ @collection_root ||= options[:collection_root] ||
30
+ klass.serializable_options.collection_root
31
+ end
32
+
33
+ def attribute_to_assign
34
+ @attribute_to_assign ||= klass.serializable_options.attribute_to_assign
35
+ end
36
+
37
+ def normalize_subclass(attrs)
38
+ hash_helper.underscore_keys!(attrs[attrs.keys.first])
39
+ klass.child_classes[attrs.keys.first].constantize.new(
40
+ attrs[attrs.keys.first]
41
+ )
42
+ end
43
+
44
+ def normalize_single(attrs)
45
+ hash_helper.underscore_keys!(attrs[root.to_s])
46
+ klass.new(attrs[root.to_s])
47
+ end
48
+
49
+ def normalize_subclass_collection(attrs)
50
+ [].tap do |objects|
51
+ attrs[collection_root.to_s].each do |key, value|
52
+ next unless klass.child_classes.keys.include?(key)
53
+ if value.is_a?(Hash)
54
+ objects << klass.child_classes[key].constantize.
55
+ new(hash_helper.underscore_keys(value))
56
+ else
57
+ value.each do |attributes|
58
+ objects << klass.child_classes[key].constantize.
59
+ new(hash_helper.underscore_keys(attributes))
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ def normalize_standard_collection(attrs)
67
+ return [] unless attrs[collection_root.to_s][root.to_s]
68
+ [attrs[collection_root.to_s][root.to_s]].flatten.map do |singular|
69
+ if attribute_to_assign
70
+ klass.new attribute_to_assign => singular
71
+ else
72
+ klass.new hash_helper.underscore_keys(singular)
73
+ end
74
+ end
75
+ end
76
+
77
+ def subclasses?
78
+ root.is_a?(Array)
79
+ end
80
+
81
+ def hash_helper
82
+ @hash_helper ||= CapsuleCRM::HashHelper
83
+ end
84
+ end
85
+ end