capsule_crm 1.1.0 → 1.2.0

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