capsule_crm 1.1.0 → 1.2.0

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +19 -0
  4. data/README.md +1 -1
  5. data/lib/capsule_crm/associations/belongs_to.rb +12 -10
  6. data/lib/capsule_crm/associations/belongs_to_association.rb +80 -0
  7. data/lib/capsule_crm/associations/has_many.rb +8 -18
  8. data/lib/capsule_crm/associations/has_many_association.rb +80 -0
  9. data/lib/capsule_crm/associations.rb +26 -0
  10. data/lib/capsule_crm/capsule_jsonable.rb +5 -1
  11. data/lib/capsule_crm/case.rb +7 -9
  12. data/lib/capsule_crm/contacts.rb +1 -1
  13. data/lib/capsule_crm/custom_field.rb +5 -8
  14. data/lib/capsule_crm/history.rb +11 -11
  15. data/lib/capsule_crm/opportunity.rb +5 -7
  16. data/lib/capsule_crm/organization.rb +6 -7
  17. data/lib/capsule_crm/participant.rb +0 -4
  18. data/lib/capsule_crm/party.rb +1 -1
  19. data/lib/capsule_crm/person.rb +6 -7
  20. data/lib/capsule_crm/serializer.rb +56 -0
  21. data/lib/capsule_crm/task.rb +7 -5
  22. data/lib/capsule_crm/track.rb +1 -1
  23. data/lib/capsule_crm/user.rb +5 -1
  24. data/lib/capsule_crm/version.rb +1 -1
  25. data/lib/capsule_crm.rb +1 -0
  26. data/spec/fabricators/custom_field_fabricator.rb +7 -0
  27. data/spec/lib/capsule_crm/associations/belongs_to_association_spec.rb +78 -0
  28. data/spec/lib/capsule_crm/associations/has_many_association_spec.rb +84 -0
  29. data/spec/lib/capsule_crm/associations/has_many_proxy_spec.rb +2 -2
  30. data/spec/lib/capsule_crm/associations_spec.rb +46 -0
  31. data/spec/lib/capsule_crm/custom_field_spec.rb +20 -597
  32. data/spec/lib/capsule_crm/history_spec.rb +8 -9
  33. data/spec/lib/capsule_crm/person_spec.rb +0 -16
  34. data/spec/lib/capsule_crm/serializer_spec.rb +103 -0
  35. data/spec/lib/capsule_crm/task_spec.rb +6 -14
  36. metadata +15 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c009a947688f5f89bc4b47b49423502a91523bb9
4
- data.tar.gz: 0efb281b53de063eff58eb3ae377111fe1a1399e
3
+ metadata.gz: a1ae5fc726cd57ca7e7026cc85e30bab83221431
4
+ data.tar.gz: 98cbdf209e74f7ff4a0d8b5cb8cf6554773432ed
5
5
  SHA512:
6
- metadata.gz: 4b90a009a0257c2f54885f361191cbf36afce7fe0341f71b18afc4821eaca7d23a7cc095507c71447d1e533d33c301138047b6dc0b54217dd5694d78036221c2
7
- data.tar.gz: b621f0a7989688a34e4505fb7952b8f69f26e17f6c715acd313b6a8ea4f4a3f0139334affebb8f02fa35535904b73f32fa7327e3c62e4a42bd3e94af20714751
6
+ metadata.gz: 77e2bb19b4a89d0a41fbc823243448d3d341863c9bd0b5c1918e281c5f6c458f1c97b14c85ee427715a8cdb092224be9522bfdd81c1469da2b3b43a90d7777c9
7
+ data.tar.gz: 2151b5e5d3c3e8ecd2305f8c89e0ac3983779f705819193d9572f7b24fcb361c183c9ce1284218a8d627b0d162c6e6fb8fcb5a54a30c039f745400d69fa585f6
data/.travis.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.1.0
3
4
  - 2.0.0
4
5
  - 1.9.3
5
6
  - jruby-19mode
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0
4
+
5
+ - Refactor associations. Now all classes know about their associations and
6
+ associations may be queried using
7
+ Class.associations/has_many_associations/belongs_to_associations
8
+ - Add a serializer class to deal with serializing objects into their capsule crm
9
+ json
10
+ - Refactor to_capsule_crm in all models to use the new serializer
11
+
12
+ ## 1.1.0
13
+
14
+ - Refactored connection error raising to use faraday middleware
15
+
16
+ ## 1.0.1
17
+
18
+ - Raise an error when trying to call create on a not yet saved has_many
19
+ association
20
+ - Validate numericality of ID on all models
21
+
3
22
  ## 1.0.0
4
23
 
5
24
  - Using SemVer and this gem is being used in production, so bumped to version 1
data/README.md CHANGED
@@ -304,7 +304,7 @@ CapsuleCRM::Currency.all
304
304
 
305
305
  ## Supported Rubies
306
306
 
307
- 1.9.3, 2.0, jruby-19mode
307
+ 1.9.3, 2.0, 2.1, jruby-19mode
308
308
 
309
309
  ## Versioning
310
310
 
@@ -1,3 +1,5 @@
1
+ require_relative 'belongs_to_association'
2
+
1
3
  module CapsuleCRM
2
4
  module Associations
3
5
  module BelongsTo
@@ -29,10 +31,12 @@ module CapsuleCRM
29
31
  # person.organisation
30
32
  # => organisation
31
33
  def belongs_to(association_name, options = {})
32
- foreign_key = options[:foreign_key] || :"#{association_name}_id"
34
+ association = CapsuleCRM::Associations::BelongsToAssociation.
35
+ new(association_name, self, options)
36
+ self.associations[association_name] = association
33
37
 
34
38
  class_eval do
35
- attribute foreign_key, Integer
39
+ attribute association.foreign_key, Integer
36
40
  end
37
41
 
38
42
  (class << self; self; end).instance_eval do
@@ -43,20 +47,18 @@ module CapsuleCRM
43
47
 
44
48
  define_method association_name do
45
49
  instance_variable_get(:"@#{association_name}") ||
46
- if self.send(foreign_key)
47
- options[:class_name].constantize.
48
- find(self.send(foreign_key)).tap do |object|
50
+ if self.send(association.foreign_key)
51
+ association.parent(self).tap do |object|
49
52
  self.send("#{association_name}=", object)
50
53
  end
51
- else
52
- nil
53
54
  end
54
55
  end
55
56
 
56
57
  define_method "#{association_name}=" do |associated_object|
57
- instance_variable_set(:"@#{association_name}", associated_object)
58
- id = associated_object ? associated_object.id : nil
59
- self.send "#{foreign_key}=", id
58
+ associated_object.tap do |object|
59
+ instance_variable_set(:"@#{association_name}", associated_object)
60
+ self.send "#{association.foreign_key}=", associated_object.try(:id)
61
+ end
60
62
  end
61
63
  end
62
64
  end
@@ -0,0 +1,80 @@
1
+ module CapsuleCRM
2
+ module Associations
3
+ class BelongsToAssociation
4
+ attr_reader :association_name, :defined_on, :options
5
+
6
+ # Public: Initialize a new CapsuleCRM::Associations::BelongsToAssociation
7
+ #
8
+ # association_name - The Symbol name of the association
9
+ # defined_on - The String name of the class that this association
10
+ # is defined on
11
+ # options - The Hash of association options
12
+ # foreign_key - The String foreign_key column name
13
+ # class_name - The String name of the parent class
14
+ #
15
+ # Examples
16
+ #
17
+ # CapsuleCRM::Associations::BelongsToAssociation.new(
18
+ # :person, 'CapsuleCRM::Opportunity', class_name: 'CapsuleCRM::Person'
19
+ # )
20
+ #
21
+ # Returns a CapsuleCRM::Associations::BelongsToAssociation
22
+ def initialize(association_name, defined_on, options)
23
+ @association_name = association_name
24
+ @defined_on = defined_on
25
+ @options = options
26
+ end
27
+
28
+ # Public: Build the foreign key column name. If a foreign key name was
29
+ # supplied in the options during initialization, then that is returned.
30
+ # Otherwise it is inferred from the association name
31
+ #
32
+ # Returns a String foreign key name
33
+ def foreign_key
34
+ @foreign_key ||= options[:foreign_key] || "#{association_name}_id"
35
+ end
36
+
37
+ # Public: Find the parent object of the supplied object
38
+ #
39
+ # object - The object to find the parent for
40
+ #
41
+ # Examples
42
+ #
43
+ # association = CapsuleCRM::Associations::BelongsToAssociation.new(
44
+ # :person, 'CapsuleCRM::Opportunity', class_name: 'CapsuleCRM::Person'
45
+ # )
46
+ # object = CapsuleCRM::Opportunity.first
47
+ # association.parent(object)
48
+ #
49
+ # Returns an Object that is on the parent side of the belongs to
50
+ # association
51
+ def parent(object)
52
+ target_klass.find(object.send(foreign_key))
53
+ end
54
+
55
+ # Public: The type of association. Just a convenience method
56
+ #
57
+ # Returns a Symbol :belongs_to
58
+ def macro
59
+ :belongs_to
60
+ end
61
+
62
+ # Public: The key to use when serializing this association
63
+ #
64
+ # Returns the String key
65
+ def serializable_key
66
+ @serializable_key ||= options[:serializable_key] || foreign_key
67
+ end
68
+
69
+ def serialize
70
+ @serialize ||= options[:serialize]
71
+ end
72
+
73
+ private
74
+
75
+ def target_klass
76
+ @target_klass ||= options[:class_name].constantize
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,4 +1,5 @@
1
- require 'capsule_crm/associations/has_many_proxy'
1
+ require_relative 'has_many_association'
2
+ require_relative 'has_many_proxy'
2
3
 
3
4
  module CapsuleCRM
4
5
  module Associations
@@ -34,29 +35,18 @@ module CapsuleCRM
34
35
  # organization.people
35
36
  # => [person]
36
37
  def has_many(association_name, options = {})
38
+ association = CapsuleCRM::Associations::HasManyAssociation.
39
+ new(association_name, self, options)
40
+ self.associations[association_name] = association
41
+
37
42
  define_method association_name do
38
43
  instance_variable_get(:"@#{association_name}") ||
39
- CapsuleCRM::Associations::HasManyProxy.new(
40
- self, # parent
41
- options[:class_name].constantize, # target class
42
- options[:class_name].constantize.
43
- send("_for_#{self.class.to_s.demodulize.downcase}", self.id),
44
- options[:source] # source
45
- ).tap do |proxy|
46
- instance_variable_set :"@#{association_name}", proxy
47
- end
48
- instance_variable_get :"@#{association_name}"
44
+ instance_variable_set(:"@#{association_name}", association.proxy(self))
49
45
  end
50
46
 
51
47
  define_method "#{association_name}=" do |associated_objects|
52
- if associated_objects.is_a?(Hash)
53
- associated_objects = Array(options[:class_name].constantize.new(associated_objects[options[:class_name].demodulize.downcase]))
54
- end
55
48
  instance_variable_set :"@#{association_name}",
56
- CapsuleCRM::Associations::HasManyProxy.new(
57
- self, options[:class_name].constantize,
58
- associated_objects, options[:source]
59
- )
49
+ association.proxy(self, associated_objects)
60
50
  end
61
51
  end
62
52
  end
@@ -0,0 +1,80 @@
1
+ module CapsuleCRM
2
+ module Associations
3
+ class HasManyAssociation
4
+ attr_reader :association_name, :options, :defined_on
5
+
6
+ # Public: Initialize a new CapsuleCRM::Associations::HasManyAssociation
7
+ #
8
+ # association_name - The Symbox association name
9
+ # defined_on - The String name of the class that this association
10
+ # is defined on
11
+ # options - The Hash of association options
12
+ # :class_name - The String name of the belongs to
13
+ # class
14
+ # :source - The Symbol name of the accessor method on
15
+ # the belongs to class
16
+ #
17
+ # Examples
18
+ #
19
+ # CapsuleCRM::Associations::HasManyAssociation.new(
20
+ # :opportunities, CapsuleCRM::Person, class_name:
21
+ # 'CapsuleCRM::Opportunity, source: :person
22
+ # )
23
+ #
24
+ # Returns a CapsuleCRM::Associations::HasManyAssociation
25
+ def initialize(association_name, defined_on, options)
26
+ @association_name = association_name
27
+ @options = options
28
+ @defined_on = defined_on
29
+ end
30
+
31
+ # Public: Build the HasManyProxy object
32
+ #
33
+ # parent - The instance of the class that the has many assocation is
34
+ # defined on
35
+ # collection - An optional Array or Hash to use as the target for the
36
+ # proxy
37
+ #
38
+ # Returns a CapsuleCRM::Associations::HasManyProxy
39
+ def proxy(parent, collection = nil)
40
+ CapsuleCRM::Associations::HasManyProxy.new(
41
+ parent, target_klass, build_target(parent, collection), source
42
+ )
43
+ end
44
+
45
+ # Public: The type of association. Just a convenience method
46
+ #
47
+ # Return a Symbol :has_many
48
+ def macro
49
+ :has_many
50
+ end
51
+
52
+ private
53
+
54
+ def build_target(parent, collection)
55
+ collection.nil? ? target(parent) : collection_to_array(collection)
56
+ end
57
+
58
+ def collection_to_array(collection)
59
+ if collection.is_a?(Hash)
60
+ Array(target_klass.new(collection[collection.keys.first]))
61
+ else
62
+ collection
63
+ end
64
+ end
65
+
66
+ def target_klass
67
+ @target_klass ||= options[:class_name].constantize
68
+ end
69
+
70
+ def target(parent)
71
+ target_klass.
72
+ send("_for_#{parent.class.to_s.demodulize.downcase}", parent.id)
73
+ end
74
+
75
+ def source
76
+ @source ||= options[:source]
77
+ end
78
+ end
79
+ end
80
+ end
@@ -8,6 +8,32 @@ module CapsuleCRM
8
8
  included do
9
9
  include CapsuleCRM::Associations::BelongsTo
10
10
  include CapsuleCRM::Associations::HasMany
11
+
12
+ class_attribute :associations
13
+ self.associations = {}
14
+ end
15
+
16
+ module ClassMethods
17
+ # Public: Gets all the has many associations defined on the class
18
+ #
19
+ # Returns a Hash
20
+ def has_many_associations
21
+ select_associations(:has_many)
22
+ end
23
+
24
+ # Public: Get all the belongs to associations defined on the class
25
+ #
26
+ # Returns a Hash
27
+ def belongs_to_associations
28
+ select_associations(:belongs_to)
29
+ end
30
+
31
+ def select_associations(macro)
32
+ associations.select do |name, association|
33
+ association.macro == macro &&
34
+ [self, self.parent].include?(association.defined_on)
35
+ end
36
+ end
11
37
  end
12
38
  end
13
39
  end
@@ -3,7 +3,11 @@ module CapsuleCRM
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  def to_capsule_json
6
- CapsuleCRM::HashHelper.camelize_keys attributes
6
+ serializer.serialize.delete(serializer.root)
7
+ end
8
+
9
+ def serializer
10
+ @serializer ||= CapsuleCRM::Serializer.new(self)
7
11
  end
8
12
  end
9
13
  end
@@ -7,8 +7,7 @@ module CapsuleCRM
7
7
  include ActiveModel::Validations
8
8
 
9
9
  include CapsuleCRM::Collection
10
- include CapsuleCRM::Associations::HasMany
11
- include CapsuleCRM::Associations::BelongsTo
10
+ include CapsuleCRM::Associations
12
11
  include CapsuleCRM::Taggable
13
12
 
14
13
  attribute :id, Integer
@@ -238,13 +237,7 @@ module CapsuleCRM
238
237
  end
239
238
 
240
239
  def to_capsule_json
241
- {
242
- kase: CapsuleCRM::HashHelper.camelize_keys(
243
- attributes.dup.delete_if do |key, value|
244
- value.blank? || key == 'track_id'
245
- end
246
- )
247
- }
240
+ serializer.serialize
248
241
  end
249
242
 
250
243
  def self._for_track(track)
@@ -253,6 +246,11 @@ module CapsuleCRM
253
246
 
254
247
  private
255
248
 
249
+ def serializer
250
+ @serializer ||= CapsuleCRM::Serializer.
251
+ new(self, excluded_keys: ['track_id'], root: :kaze)
252
+ end
253
+
256
254
  def create_record
257
255
  path = "/api/party/#{party_id}/kase"
258
256
  path += "?trackId=#{track_id}" if track_id
@@ -146,7 +146,7 @@ module CapsuleCRM
146
146
  email: emails.map(&:to_capsule_json),
147
147
  phone: phones.map(&:to_capsule_json),
148
148
  website: websites.map(&:to_capsule_json)
149
- }.stringify_keys
149
+ }.delete_if { |key, value| value.blank? }.stringify_keys
150
150
  end
151
151
  end
152
152
  end
@@ -63,18 +63,15 @@ module CapsuleCRM
63
63
  end
64
64
 
65
65
  def to_capsule_json
66
- {
67
- customFields: {
68
- customField: [
69
- CapsuleCRM::HashHelper.camelize_keys(attributes).
70
- delete_if { |key, value| value.blank? }
71
- ]
72
- }
73
- }
66
+ { 'customFields' => serializer.serialize }
74
67
  end
75
68
 
76
69
  private
77
70
 
71
+ def serializer
72
+ @serializer ||= CapsuleCRM::Serializer.new(self, root: 'customField')
73
+ end
74
+
78
75
  def update_record
79
76
  CapsuleCRM::Connection.post(
80
77
  "/api/party/#{party.id}/customfields", to_capsule_json
@@ -19,11 +19,13 @@ module CapsuleCRM
19
19
  has_many :attachments, class_name: 'CapsuleCRM::Attachment'
20
20
  has_many :participants, class_name: 'CapsuleCRM::Participant'
21
21
 
22
- belongs_to :creator, class_name: 'CapsuleCRM::Person'
23
- belongs_to :party, class_name: 'CapsuleCRM::Party'
22
+ belongs_to :creator, class_name: 'CapsuleCRM::Person',
23
+ serializable_key: :creator
24
+ belongs_to :party, class_name: 'CapsuleCRM::Party', serialize: false
24
25
  belongs_to :kase, class_name: 'CapsuleCRM::Case',
25
- foreign_key: :case_id
26
- belongs_to :opportunity, class_name: 'CapsuleCRM::Opportunity'
26
+ foreign_key: :case_id, serialize: false
27
+ belongs_to :opportunity, class_name: 'CapsuleCRM::Opportunity',
28
+ serialize: false
27
29
 
28
30
  validates :id, numericality: { allow_blank: true }
29
31
  validates :note, presence: true
@@ -269,17 +271,15 @@ module CapsuleCRM
269
271
  #
270
272
  # Returns a Hash of attributes
271
273
  def to_capsule_json
272
- {
273
- historyItem: CapsuleCRM::HashHelper.camelize_keys(
274
- {
275
- note: note, entry_date: entry_date, creator: creator.try(:username)
276
- }.delete_if { |key, value| value.blank? }
277
- )
278
- }
274
+ serializer.serialize
279
275
  end
280
276
 
281
277
  private
282
278
 
279
+ def serializer
280
+ @serializer ||= CapsuleCRM::Serializer.new(self, root: :historyItem)
281
+ end
282
+
283
283
  def belongs_to_required?
284
284
  party.blank? && kase.blank? && opportunity.blank?
285
285
  end
@@ -293,13 +293,7 @@ module CapsuleCRM
293
293
  #
294
294
  # Returns a Hash
295
295
  def to_capsule_json
296
- {
297
- opportunity: CapsuleCRM::HashHelper.camelize_keys(
298
- attributes.dup.delete_if do |key, value|
299
- value.blank? || key == 'track_id'
300
- end
301
- )
302
- }.stringify_keys
296
+ serializer.serialize
303
297
  end
304
298
 
305
299
  # Public: Delete the opportunity in capsule
@@ -316,6 +310,10 @@ module CapsuleCRM
316
310
 
317
311
  private
318
312
 
313
+ def serializer
314
+ @serializer ||= CapsuleCRM::Serializer.new(self, excluded_keys: ['track_id'])
315
+ end
316
+
319
317
  def create_record
320
318
  path = "/api/party/#{party_id}/opportunity"
321
319
  path += "?trackId=#{track_id}" if track_id
@@ -6,12 +6,9 @@ module CapsuleCRM
6
6
  extend ActiveModel::Callbacks
7
7
  extend ActiveModel::Conversion
8
8
  include ActiveModel::Validations
9
- include ActiveModel::Validations::Callbacks
10
9
 
11
- include CapsuleCRM::Associations::HasMany
12
10
  include CapsuleCRM::Collection
13
11
  include CapsuleCRM::Contactable
14
- include CapsuleCRM::Taggable
15
12
 
16
13
  attribute :id, Integer
17
14
  attribute :name, String
@@ -209,10 +206,7 @@ module CapsuleCRM
209
206
  #
210
207
  # Returns a Hash
211
208
  def to_capsule_json
212
- {
213
- organisation: attributes.merge(contacts: contacts.to_capsule_json).
214
- stringify_keys
215
- }.stringify_keys
209
+ serializer.serialize
216
210
  end
217
211
 
218
212
  # Public: Delete the organization in capsule
@@ -229,6 +223,11 @@ module CapsuleCRM
229
223
 
230
224
  private
231
225
 
226
+ def serializer
227
+ @serializer ||= CapsuleCRM::Serializer.
228
+ new(self, root: :organisation, additional_methods: [:contacts])
229
+ end
230
+
232
231
  def create_record
233
232
  self.attributes = CapsuleCRM::Connection.post(
234
233
  '/api/organisation', to_capsule_json
@@ -13,9 +13,5 @@ module CapsuleCRM
13
13
  def self._for_history(history_id)
14
14
  CapsuleCRM::ResultsProxy.new([])
15
15
  end
16
-
17
- def to_capsule_json
18
- CapsuleCRM::HashHelper.camelize_keys(attributes.dup)
19
- end
20
16
  end
21
17
  end
@@ -3,7 +3,7 @@ class CapsuleCRM::Party
3
3
 
4
4
  include CapsuleCRM::Attributes
5
5
  include CapsuleCRM::Taggable
6
- include CapsuleCRM::Associations::HasMany
6
+ include CapsuleCRM::Associations
7
7
 
8
8
  has_many :histories, class_name: 'CapsuleCRM::History', source: :party
9
9
  has_many :tasks, class_name: 'CapsuleCRM::Task', source: :party
@@ -2,7 +2,6 @@ module CapsuleCRM
2
2
  class Person < CapsuleCRM::Party
3
3
  include CapsuleCRM::Collection
4
4
  include CapsuleCRM::Contactable
5
- include CapsuleCRM::Associations::BelongsTo
6
5
 
7
6
  extend ActiveModel::Naming
8
7
  include ActiveModel::Conversion
@@ -220,16 +219,16 @@ module CapsuleCRM
220
219
  #
221
220
  # Returns a Hash
222
221
  def to_capsule_json
223
- {
224
- person: CapsuleCRM::HashHelper.camelize_keys(
225
- attributes.dup.delete_if { |key, value| value.blank? }.
226
- merge(contacts: contacts.to_capsule_json)
227
- )
228
- }.stringify_keys
222
+ serializer.serialize
229
223
  end
230
224
 
231
225
  private
232
226
 
227
+ def serializer
228
+ @serializer ||= CapsuleCRM::Serializer.
229
+ new(self, additional_methods: [:contacts])
230
+ end
231
+
233
232
  def create_record
234
233
  self.attributes = CapsuleCRM::Connection.post(
235
234
  '/api/person', to_capsule_json
@@ -0,0 +1,56 @@
1
+ module CapsuleCRM
2
+ class Serializer
3
+ attr_reader :object, :options
4
+
5
+ def initialize(object, options = {})
6
+ @object = object
7
+ @options = options
8
+ end
9
+
10
+ def serialize
11
+ @serialized ||= { root => build_attributes_hash }.stringify_keys
12
+ end
13
+
14
+ def root
15
+ @root ||= options[:root] ||
16
+ object.class.to_s.demodulize.downcase.singularize.camelize(:lower)
17
+ end
18
+
19
+ private
20
+
21
+ def additional_methods
22
+ @additional_methods ||= options[:additional_methods] || []
23
+ end
24
+
25
+ def excluded_keys
26
+ @excluded_keys ||= options[:excluded_keys] || []
27
+ end
28
+
29
+ def build_attributes_hash
30
+ CapsuleCRM::HashHelper.camelize_keys(cleaned_attributes)
31
+ end
32
+
33
+ def cleaned_attributes
34
+ attributes.delete_if do |key, value|
35
+ value.blank? || key.to_s == 'id' || excluded_keys.include?(key)
36
+ end
37
+ end
38
+
39
+ def attributes
40
+ object.attributes.dup.tap do |attrs|
41
+ attrs.each do |key, value|
42
+ attrs[key] = value.to_s(:db) if value.is_a?(Date)
43
+ attrs[key] = value.strftime("%Y-%m-%dT%H:%M:%SZ") if value.is_a?(DateTime)
44
+ end
45
+ additional_methods.each do |method|
46
+ attrs.merge!(method => object.send(method).to_capsule_json)
47
+ end
48
+ object.class.belongs_to_associations.each do |name, association|
49
+ attrs.merge!(
50
+ association.serializable_key => object.send(name).try(:id)
51
+ ) unless association.serialize == false
52
+ end if object.class.respond_to?(:belongs_to_associations)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -6,7 +6,7 @@ module CapsuleCRM
6
6
  include ActiveModel::Conversion
7
7
  include ActiveModel::Validations
8
8
 
9
- include CapsuleCRM::Associations::BelongsTo
9
+ include CapsuleCRM::Associations
10
10
  include CapsuleCRM::Attributes
11
11
  include CapsuleCRM::Collection
12
12
 
@@ -20,7 +20,7 @@ module CapsuleCRM
20
20
  belongs_to :party, class_name: 'CapsuleCRM::Party'
21
21
  belongs_to :opportunity, class_name: 'CapsuleCRM::Opportunity'
22
22
  belongs_to :case, class_name: 'CapsuleCRM::Case'
23
- belongs_to :owner, class_name: 'CapsuleCRM::User'
23
+ belongs_to :owner, class_name: 'CapsuleCRM::User', serializable_key: :owner
24
24
 
25
25
  validates :id, numericality: { allow_blank: true }
26
26
  validates :description, presence: true
@@ -130,13 +130,15 @@ module CapsuleCRM
130
130
  end
131
131
 
132
132
  def to_capsule_json
133
- {
134
- task: CapsuleCRM::HashHelper.camelize_keys(capsule_attributes)
135
- }.stringify_keys
133
+ serializer.serialize
136
134
  end
137
135
 
138
136
  private
139
137
 
138
+ def serializer
139
+ @serializer ||= CapsuleCRM::Serializer.new(self)
140
+ end
141
+
140
142
  def capsule_attributes
141
143
  { description: description, category: category }.tap do |attrs|
142
144
  attrs.merge!(owner: owner.username) if owner