capsule_crm 1.2.0 → 1.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/lib/capsule_crm/address.rb +4 -3
- data/lib/capsule_crm/associations/belongs_to.rb +2 -1
- data/lib/capsule_crm/associations/belongs_to_association.rb +19 -2
- data/lib/capsule_crm/associations/belongs_to_finder.rb +46 -0
- data/lib/capsule_crm/associations/has_many_association.rb +23 -9
- data/lib/capsule_crm/associations/has_many_proxy.rb +38 -4
- data/lib/capsule_crm/case.rb +33 -236
- data/lib/capsule_crm/configuration.rb +1 -1
- data/lib/capsule_crm/connection.rb +3 -0
- data/lib/capsule_crm/contactable.rb +1 -1
- data/lib/capsule_crm/country.rb +7 -13
- data/lib/capsule_crm/currency.rb +7 -13
- data/lib/capsule_crm/custom_field.rb +14 -54
- data/lib/capsule_crm/custom_field_definition.rb +36 -0
- data/lib/capsule_crm/email.rb +4 -3
- data/lib/capsule_crm/gettable.rb +11 -0
- data/lib/capsule_crm/hash_helper.rb +5 -0
- data/lib/capsule_crm/history.rb +37 -252
- data/lib/capsule_crm/milestone.rb +9 -9
- data/lib/capsule_crm/normalizer.rb +85 -0
- data/lib/capsule_crm/opportunity.rb +30 -271
- data/lib/capsule_crm/organization.rb +19 -197
- data/lib/capsule_crm/party.rb +13 -26
- data/lib/capsule_crm/persistence/configuration.rb +25 -0
- data/lib/capsule_crm/persistence/deletable.rb +14 -0
- data/lib/capsule_crm/persistence/persistable.rb +76 -0
- data/lib/capsule_crm/persistence.rb +3 -0
- data/lib/capsule_crm/person.rb +19 -194
- data/lib/capsule_crm/phone.rb +4 -3
- data/lib/capsule_crm/querying/configuration.rb +21 -0
- data/lib/capsule_crm/querying/find_all.rb +16 -0
- data/lib/capsule_crm/querying/find_one.rb +14 -0
- data/lib/capsule_crm/querying/findable.rb +14 -0
- data/lib/capsule_crm/querying.rb +4 -0
- data/lib/capsule_crm/serializable.rb +38 -0
- data/lib/capsule_crm/serializer.rb +54 -7
- data/lib/capsule_crm/task.rb +16 -96
- data/lib/capsule_crm/track.rb +5 -10
- data/lib/capsule_crm/user.rb +3 -15
- data/lib/capsule_crm/version.rb +1 -1
- data/lib/capsule_crm/website.rb +4 -2
- data/lib/capsule_crm.rb +15 -5
- data/spec/fabricators/case_fabricator.rb +1 -0
- data/spec/fabricators/history_fabricator.rb +1 -0
- data/spec/fabricators/opportunity_fabricator.rb +1 -0
- data/spec/lib/capsule_crm/associations/belongs_to_finder_spec.rb +48 -0
- data/spec/lib/capsule_crm/associations/belongs_to_spec.rb +34 -0
- data/spec/lib/capsule_crm/associations/has_many_proxy_spec.rb +54 -14
- data/spec/lib/capsule_crm/associations/has_many_spec.rb +15 -2
- data/spec/lib/capsule_crm/case_spec.rb +20 -330
- data/spec/lib/capsule_crm/country_spec.rb +1 -16
- data/spec/lib/capsule_crm/currency_spec.rb +1 -18
- data/spec/lib/capsule_crm/custom_field_definition_spec.rb +59 -0
- data/spec/lib/capsule_crm/custom_field_spec.rb +2 -27
- data/spec/lib/capsule_crm/history_spec.rb +14 -389
- data/spec/lib/capsule_crm/milestone_spec.rb +1 -23
- data/spec/lib/capsule_crm/normalizer_spec.rb +11 -0
- data/spec/lib/capsule_crm/opportunity_spec.rb +22 -341
- data/spec/lib/capsule_crm/organization_spec.rb +39 -60
- data/spec/lib/capsule_crm/party_spec.rb +37 -59
- data/spec/lib/capsule_crm/person_spec.rb +49 -247
- data/spec/lib/capsule_crm/serializer_spec.rb +25 -4
- data/spec/lib/capsule_crm/task_spec.rb +21 -250
- data/spec/lib/capsule_crm/track_spec.rb +1 -15
- data/spec/lib/capsule_crm/user_spec.rb +1 -14
- data/spec/support/{countries.json → all_countries.json} +0 -0
- data/spec/support/{currencies.json → all_currencies.json} +0 -0
- data/spec/support/{milestones.json → all_milestones.json} +0 -0
- data/spec/support/{tracks.json → all_tracks.json} +0 -0
- data/spec/support/custom_field_definitions.json +19 -0
- data/spec/support/helpers.rb +3 -2
- data/spec/support/no_cases.json +5 -0
- data/spec/support/no_countries.json +5 -0
- data/spec/support/no_currencies.json +5 -0
- data/spec/support/no_milestones.json +5 -0
- data/spec/support/no_opportunities.json +5 -0
- data/spec/support/no_tasks.json +5 -0
- data/spec/support/no_tracks.json +5 -0
- data/spec/support/no_users.json +5 -0
- data/spec/support/shared_examples/deletable.rb +15 -0
- data/spec/support/shared_examples/find_all.rb +34 -0
- data/spec/support/shared_examples/find_one.rb +23 -0
- data/spec/support/shared_examples/persistable.rb +318 -0
- data/spec/support/single_person.json +16 -0
- metadata +60 -15
- data/lib/capsule_crm/attributes.rb +0 -11
- data/lib/capsule_crm/capsule_jsonable.rb +0 -13
- data/lib/capsule_crm/collection.rb +0 -9
- data/spec/support/single_user.json +0 -25
@@ -0,0 +1,76 @@
|
|
1
|
+
module CapsuleCRM
|
2
|
+
module Persistence
|
3
|
+
module Persistable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.send :include, CapsuleCRM::Persistence::Configuration
|
8
|
+
base.extend CapsuleCRM::Persistence::Persistable::ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def create(attributes = {})
|
13
|
+
new(attributes).tap(&:save)
|
14
|
+
end
|
15
|
+
|
16
|
+
def create!(attributes = {})
|
17
|
+
new(attributes).tap(&:save!)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def save
|
22
|
+
if valid?
|
23
|
+
new_record? ? create_record : update_record
|
24
|
+
else
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def save!
|
30
|
+
if valid?
|
31
|
+
new_record? ? create_record : update_record
|
32
|
+
else
|
33
|
+
raise CapsuleCRM::Errors::RecordInvalid.new(self)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def update_attributes(attributes = {})
|
38
|
+
self.attributes = attributes
|
39
|
+
save
|
40
|
+
end
|
41
|
+
|
42
|
+
def update_attributes!(attributes = {})
|
43
|
+
self.attributes = attributes
|
44
|
+
save!
|
45
|
+
end
|
46
|
+
|
47
|
+
def new_record?
|
48
|
+
!id
|
49
|
+
end
|
50
|
+
|
51
|
+
def persisted?
|
52
|
+
!new_record?
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_record
|
56
|
+
self.attributes = CapsuleCRM::Connection.post(
|
57
|
+
build_create_path, to_capsule_json
|
58
|
+
)
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
def build_create_path
|
63
|
+
"/api/#{self.class.connection_options.create.call(self)}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def build_update_path
|
67
|
+
"/api/#{self.class.connection_options.update.call(self)}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_record
|
71
|
+
CapsuleCRM::Connection.put(build_update_path, to_capsule_json)
|
72
|
+
self
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/capsule_crm/person.rb
CHANGED
@@ -1,12 +1,29 @@
|
|
1
1
|
module CapsuleCRM
|
2
2
|
class Person < CapsuleCRM::Party
|
3
|
-
include CapsuleCRM::Collection
|
4
3
|
include CapsuleCRM::Contactable
|
4
|
+
include CapsuleCRM::Persistence::Persistable
|
5
|
+
include CapsuleCRM::Persistence::Deletable
|
6
|
+
include CapsuleCRM::Querying::Configuration
|
7
|
+
include CapsuleCRM::Serializable
|
5
8
|
|
6
9
|
extend ActiveModel::Naming
|
7
10
|
include ActiveModel::Conversion
|
8
11
|
include ActiveModel::Validations
|
9
12
|
|
13
|
+
serializable_config do |config|
|
14
|
+
config.collection_root = :parties
|
15
|
+
config.additional_methods = [:contacts]
|
16
|
+
end
|
17
|
+
|
18
|
+
queryable_config do |config|
|
19
|
+
config.singular = :party
|
20
|
+
end
|
21
|
+
|
22
|
+
persistable_config do |config|
|
23
|
+
config.create = lambda { |person| "person" }
|
24
|
+
config.destroy = lambda { |person| "party/#{person.id}" }
|
25
|
+
end
|
26
|
+
|
10
27
|
attribute :id, Integer
|
11
28
|
attribute :title
|
12
29
|
attribute :first_name
|
@@ -15,24 +32,12 @@ module CapsuleCRM
|
|
15
32
|
attribute :about
|
16
33
|
attribute :organisation_name
|
17
34
|
|
18
|
-
belongs_to :organization,
|
19
|
-
foreign_key: :organisation_id
|
20
|
-
|
21
|
-
has_many :custom_fields, class_name: 'CapsuleCRM::CustomField',
|
22
|
-
source: :party
|
35
|
+
belongs_to :organization, foreign_key: :organisation_id
|
23
36
|
|
24
37
|
validates :id, numericality: { allow_blank: true }
|
25
38
|
validates :first_name, presence: { if: :first_name_required? }
|
26
39
|
validates :last_name, presence: { if: :last_name_required? }
|
27
40
|
|
28
|
-
def self._for_organization(organization_id)
|
29
|
-
init_collection(
|
30
|
-
CapsuleCRM::Connection.get(
|
31
|
-
"/api/party/#{organization_id}/people"
|
32
|
-
)['parties']['person']
|
33
|
-
)
|
34
|
-
end
|
35
|
-
|
36
41
|
# Public: Get all people from Capsule. The list can be restricted
|
37
42
|
# and/or paginated with various query parameters sent through the options
|
38
43
|
# hash.
|
@@ -59,188 +64,8 @@ module CapsuleCRM
|
|
59
64
|
delete_if { |item| !item.is_a?(CapsuleCRM::Person) }
|
60
65
|
end
|
61
66
|
|
62
|
-
# Public: Create a new person in capsulecrm
|
63
|
-
#
|
64
|
-
# attributes - The Hash of person attributes (default: {}):
|
65
|
-
# :first_name - The String first name
|
66
|
-
# :last_name - The String last name
|
67
|
-
# :job_title - The String job title
|
68
|
-
# :about - The String information about the person
|
69
|
-
# :organisation_name - The String organisation name. If now
|
70
|
-
# :organisation_id is supplied, then a new one will be created
|
71
|
-
# with this name
|
72
|
-
# :organisation_id - The Integer ID of the organisation this
|
73
|
-
# person belongs to
|
74
|
-
#
|
75
|
-
# Examples
|
76
|
-
#
|
77
|
-
# CapsuleCRM::Person.create(first_name: 'Matt', last_name: 'Beedle')
|
78
|
-
#
|
79
|
-
# Returns a CapsuleCRM::Person
|
80
|
-
def self.create(attributes = {})
|
81
|
-
new(attributes).tap(&:save)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Public: Create a new person in capsulecrm and raise a
|
85
|
-
# CapsuleCRM::Errors::InvalidRecord error if not possible
|
86
|
-
#
|
87
|
-
# attributes - The Hash of person attributes (default: {}):
|
88
|
-
# :first_name - The String first name
|
89
|
-
# :last_name - The String last name
|
90
|
-
# :job_title - The String job title
|
91
|
-
# :about - The String information about the person
|
92
|
-
# :organisation_name - The String organisation name. If now
|
93
|
-
# :organisation_id is supplied, then a new one will be created
|
94
|
-
# with this name
|
95
|
-
# :organisation_id - The Integer ID of the organisation this
|
96
|
-
# person belongs to
|
97
|
-
#
|
98
|
-
# Examples
|
99
|
-
#
|
100
|
-
# CapsuleCRM::Person.create!(first_name: 'Matt', last_name: 'Beedle')
|
101
|
-
#
|
102
|
-
# Returns a CapsuleCRM
|
103
|
-
def self.create!(attributes = {})
|
104
|
-
new(attributes).tap(&:save!)
|
105
|
-
end
|
106
|
-
|
107
|
-
# Public: If the person already exists in capsule then update them,
|
108
|
-
# otherwise create a new person
|
109
|
-
#
|
110
|
-
# Examples
|
111
|
-
#
|
112
|
-
# person = CapsuleCRM::Person.new(first_name: 'Matt')
|
113
|
-
# person.save
|
114
|
-
#
|
115
|
-
# person = CapsuleCRM::Person.find(1)
|
116
|
-
# person.first_name = 'Matt'
|
117
|
-
# person.save
|
118
|
-
#
|
119
|
-
# Returns a CapsuleCRM::Person
|
120
|
-
def save
|
121
|
-
if valid?
|
122
|
-
new_record? ? create_record : update_record
|
123
|
-
else
|
124
|
-
false
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
# Public: If the person already exists in capsule then update them,
|
129
|
-
# otherwise create a new person. If the person is not valid then a
|
130
|
-
# CapsuleCRM::Errors::RecordInvalid exception is raised
|
131
|
-
#
|
132
|
-
# Examples
|
133
|
-
#
|
134
|
-
# person = CapsuleCRM::Person.new(first_name: 'Matt')
|
135
|
-
# person.save
|
136
|
-
#
|
137
|
-
# person = CapsuleCRM::Person.find(1)
|
138
|
-
# person.first_name = 'Matt'
|
139
|
-
# person.save
|
140
|
-
#
|
141
|
-
# Returns a CapsuleCRM::Person
|
142
|
-
def save!
|
143
|
-
if valid?
|
144
|
-
new_record? ? create_record : update_record
|
145
|
-
else
|
146
|
-
raise CapsuleCRM::Errors::RecordInvalid.new(self)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
# Public: Update the person in capsule
|
151
|
-
#
|
152
|
-
# attributes - The Hash of person attributes (default: {}):
|
153
|
-
# :first_name - The String first name
|
154
|
-
# :last_name - The String last name
|
155
|
-
# :job_title - The String job title
|
156
|
-
# :about - The String information about the person
|
157
|
-
# :organisation_name - The String organisation name
|
158
|
-
# :organisation_id - The String organisation id
|
159
|
-
#
|
160
|
-
# Examples
|
161
|
-
#
|
162
|
-
# person = CapsuleCRM::Person.find(1)
|
163
|
-
# person.update_attributes first_name: 'Matt', last_name: 'Beedle'
|
164
|
-
#
|
165
|
-
# Returns a CapsuleCRM::Person
|
166
|
-
def update_attributes(attributes = {})
|
167
|
-
self.attributes = attributes
|
168
|
-
save
|
169
|
-
end
|
170
|
-
|
171
|
-
# Public: Update the person in capsule. If the person is not valid then a
|
172
|
-
# CapsuleCRM::Errors::RecordInvalid exception will be raised
|
173
|
-
#
|
174
|
-
# attributes - The Hash of person attributes (default: {}):
|
175
|
-
# :first_name - The String first name
|
176
|
-
# :last_name - The String last name
|
177
|
-
# :job_title - The String job title
|
178
|
-
# :about - The String information about the person
|
179
|
-
# :organisation_name - The String organisation name
|
180
|
-
# :organisation_id - The String organisation id
|
181
|
-
#
|
182
|
-
# Examples
|
183
|
-
#
|
184
|
-
# person = CapsuleCRM::Person.find(1)
|
185
|
-
# person.update_attributes first_name: 'Matt', last_name: 'Beedle'
|
186
|
-
#
|
187
|
-
# Returns a CapsuleCRM::Person
|
188
|
-
def update_attributes!(attributes = {})
|
189
|
-
self.attributes = attributes
|
190
|
-
save!
|
191
|
-
end
|
192
|
-
|
193
|
-
def destroy
|
194
|
-
self.id = nil if CapsuleCRM::Connection.delete("/api/party/#{id}")
|
195
|
-
self
|
196
|
-
end
|
197
|
-
|
198
|
-
# Public: Determine whether this CapsuleCRM::Person is a new record or not
|
199
|
-
#
|
200
|
-
# Returns a Boolean
|
201
|
-
def new_record?
|
202
|
-
!id
|
203
|
-
end
|
204
|
-
|
205
|
-
# Public: Determine whether or not this CapsuleCRM::Person has already been
|
206
|
-
# persisted to capsulecrm
|
207
|
-
#
|
208
|
-
# Returns a Boolean
|
209
|
-
def persisted?
|
210
|
-
!new_record?
|
211
|
-
end
|
212
|
-
|
213
|
-
# Public: Build a hash of attributes and merge in the attributes for the
|
214
|
-
# contact information
|
215
|
-
#
|
216
|
-
# Examples
|
217
|
-
#
|
218
|
-
# person.to_capsule_json
|
219
|
-
#
|
220
|
-
# Returns a Hash
|
221
|
-
def to_capsule_json
|
222
|
-
serializer.serialize
|
223
|
-
end
|
224
|
-
|
225
67
|
private
|
226
68
|
|
227
|
-
def serializer
|
228
|
-
@serializer ||= CapsuleCRM::Serializer.
|
229
|
-
new(self, additional_methods: [:contacts])
|
230
|
-
end
|
231
|
-
|
232
|
-
def create_record
|
233
|
-
self.attributes = CapsuleCRM::Connection.post(
|
234
|
-
'/api/person', to_capsule_json
|
235
|
-
)
|
236
|
-
self
|
237
|
-
end
|
238
|
-
|
239
|
-
def update_record
|
240
|
-
CapsuleCRM::Connection.put("/api/person/#{id}", to_capsule_json)
|
241
|
-
self
|
242
|
-
end
|
243
|
-
|
244
69
|
# Private: Determines whether the person first name is required. Either the
|
245
70
|
# first or the last name is always required
|
246
71
|
#
|
data/lib/capsule_crm/phone.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
module CapsuleCRM
|
2
2
|
class Phone
|
3
3
|
include Virtus
|
4
|
-
|
4
|
+
include CapsuleCRM::Serializable
|
5
5
|
extend ActiveModel::Naming
|
6
|
-
include ActiveModel::Serializers::JSON
|
7
6
|
|
8
|
-
|
7
|
+
serializable_config do |config|
|
8
|
+
config.include_root = false
|
9
|
+
end
|
9
10
|
|
10
11
|
attribute :type
|
11
12
|
attribute :phone_number
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CapsuleCRM
|
2
|
+
module Querying
|
3
|
+
module Configuration
|
4
|
+
def self.included(base)
|
5
|
+
base.send :class_attribute, :queryable_options
|
6
|
+
base.extend CapsuleCRM::Querying::Configuration::ClassMethods
|
7
|
+
|
8
|
+
base.queryable_options = OpenStruct.new(
|
9
|
+
plural: base.to_s.demodulize.downcase.pluralize,
|
10
|
+
singular: base.to_s.demodulize.downcase.singularize
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def queryable_config
|
16
|
+
yield(queryable_options)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module CapsuleCRM
|
2
|
+
module Querying
|
3
|
+
module FindAll
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def all(options = {})
|
8
|
+
CapsuleCRM::Normalizer.new(self).normalize_collection(
|
9
|
+
CapsuleCRM::Connection.
|
10
|
+
get("/api/#{queryable_options.plural}", options)
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'find_all'
|
2
|
+
require_relative 'find_one'
|
3
|
+
|
4
|
+
module CapsuleCRM
|
5
|
+
module Querying
|
6
|
+
module Findable
|
7
|
+
def self.included(base)
|
8
|
+
base.send :include, CapsuleCRM::Querying::Configuration
|
9
|
+
base.send :include, CapsuleCRM::Querying::FindAll
|
10
|
+
base.send :include, CapsuleCRM::Querying::FindOne
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module CapsuleCRM
|
2
|
+
module Serializable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
# We need to use "self.included" here instead of "included do" to make sure
|
6
|
+
# that organizations and people don't inherit a pointer to the
|
7
|
+
# serializable_options of their parent class and modify that.
|
8
|
+
def self.included(base)
|
9
|
+
base.send :class_attribute, :serializable_options
|
10
|
+
|
11
|
+
base.serializable_options = OpenStruct.new(
|
12
|
+
collection_root: base.to_s.demodulize.downcase.pluralize,
|
13
|
+
root: base.to_s.demodulize.downcase.singularize,
|
14
|
+
include_root: true,
|
15
|
+
excluded_keys: [],
|
16
|
+
additional_methods: []
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_capsule_json
|
21
|
+
serializer.serialize(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
def serializer
|
25
|
+
@serializer ||= CapsuleCRM::Serializer.new(self.serializable_options)
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
def from_capsule_json(json)
|
30
|
+
CapsuleCRM::Normalizer.new(self).normalize(json)
|
31
|
+
end
|
32
|
+
|
33
|
+
def serializable_config
|
34
|
+
yield(serializable_options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -2,13 +2,35 @@ module CapsuleCRM
|
|
2
2
|
class Serializer
|
3
3
|
attr_reader :object, :options
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@object = object
|
5
|
+
def initialize(options = {})
|
7
6
|
@options = options
|
8
7
|
end
|
9
8
|
|
10
|
-
def serialize
|
11
|
-
@
|
9
|
+
def serialize(object)
|
10
|
+
@object = object
|
11
|
+
@serialized ||=
|
12
|
+
if include_root?
|
13
|
+
serialize_with_root
|
14
|
+
else
|
15
|
+
serialize_without_root
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.serialize_collection(klass, collection)
|
20
|
+
collection = collection.map do |item|
|
21
|
+
options = klass.serializable_options
|
22
|
+
options.include_root = false
|
23
|
+
::CapsuleCRM::Serializer.new(options).serialize(item)
|
24
|
+
end
|
25
|
+
{ klass.serializable_options.root => collection }
|
26
|
+
end
|
27
|
+
|
28
|
+
def serialize_with_root
|
29
|
+
{ root => build_attributes_hash }.stringify_keys
|
30
|
+
end
|
31
|
+
|
32
|
+
def serialize_without_root
|
33
|
+
build_attributes_hash
|
12
34
|
end
|
13
35
|
|
14
36
|
def root
|
@@ -16,8 +38,16 @@ module CapsuleCRM
|
|
16
38
|
object.class.to_s.demodulize.downcase.singularize.camelize(:lower)
|
17
39
|
end
|
18
40
|
|
41
|
+
def collection_root
|
42
|
+
@collection_root ||= options[:collection_root] || root.pluralize
|
43
|
+
end
|
44
|
+
|
19
45
|
private
|
20
46
|
|
47
|
+
def include_root?
|
48
|
+
@include_root ||= true unless options[:include_root] == false
|
49
|
+
end
|
50
|
+
|
21
51
|
def additional_methods
|
22
52
|
@additional_methods ||= options[:additional_methods] || []
|
23
53
|
end
|
@@ -30,20 +60,37 @@ module CapsuleCRM
|
|
30
60
|
CapsuleCRM::HashHelper.camelize_keys(cleaned_attributes)
|
31
61
|
end
|
32
62
|
|
63
|
+
def excluded_association_keys
|
64
|
+
@excluded_association_keys ||=
|
65
|
+
if object.class.respond_to?(:belongs_to_associations)
|
66
|
+
object.class.belongs_to_associations.map do |name, association|
|
67
|
+
association.foreign_key if association.inverse.try(:embedded)
|
68
|
+
end.compact
|
69
|
+
else
|
70
|
+
[]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
33
74
|
def cleaned_attributes
|
34
75
|
attributes.delete_if do |key, value|
|
35
|
-
value.blank? || key.to_s == 'id' || excluded_keys.include?(key)
|
76
|
+
value.blank? || key.to_s == 'id' || excluded_keys.include?(key) ||
|
77
|
+
excluded_association_keys.include?(key.to_s)
|
36
78
|
end
|
37
79
|
end
|
38
80
|
|
81
|
+
# TODO OMG, clean this up!
|
39
82
|
def attributes
|
40
83
|
object.attributes.dup.tap do |attrs|
|
41
84
|
attrs.each do |key, value|
|
42
85
|
attrs[key] = value.to_s(:db) if value.is_a?(Date)
|
43
|
-
|
86
|
+
if value.is_a?(DateTime)
|
87
|
+
attrs[key] = value.strftime("%Y-%m-%dT%H:%M:%SZ")
|
88
|
+
end
|
44
89
|
end
|
45
90
|
additional_methods.each do |method|
|
46
|
-
|
91
|
+
unless object.send(method).blank?
|
92
|
+
attrs.merge!(method => object.send(method).to_capsule_json)
|
93
|
+
end
|
47
94
|
end
|
48
95
|
object.class.belongs_to_associations.each do |name, association|
|
49
96
|
attrs.merge!(
|
data/lib/capsule_crm/task.rb
CHANGED
@@ -7,8 +7,14 @@ module CapsuleCRM
|
|
7
7
|
include ActiveModel::Validations
|
8
8
|
|
9
9
|
include CapsuleCRM::Associations
|
10
|
-
include CapsuleCRM::
|
11
|
-
include CapsuleCRM::
|
10
|
+
include CapsuleCRM::Persistence::Persistable
|
11
|
+
include CapsuleCRM::Persistence::Deletable
|
12
|
+
include CapsuleCRM::Querying::Findable
|
13
|
+
include CapsuleCRM::Serializable
|
14
|
+
|
15
|
+
persistable_config do |config|
|
16
|
+
config.create = lambda { |task| task.create_url }
|
17
|
+
end
|
12
18
|
|
13
19
|
attribute :id, Integer
|
14
20
|
attribute :due_date, Date
|
@@ -17,9 +23,9 @@ module CapsuleCRM
|
|
17
23
|
attribute :description, String
|
18
24
|
attribute :detail, String
|
19
25
|
|
20
|
-
belongs_to :party
|
21
|
-
belongs_to :opportunity
|
22
|
-
belongs_to :case
|
26
|
+
belongs_to :party
|
27
|
+
belongs_to :opportunity
|
28
|
+
belongs_to :case
|
23
29
|
belongs_to :owner, class_name: 'CapsuleCRM::User', serializable_key: :owner
|
24
30
|
|
25
31
|
validates :id, numericality: { allow_blank: true }
|
@@ -57,55 +63,6 @@ module CapsuleCRM
|
|
57
63
|
self
|
58
64
|
end
|
59
65
|
|
60
|
-
def self.all(options = {})
|
61
|
-
init_collection(
|
62
|
-
CapsuleCRM::Connection.get('/api/tasks', options)['tasks']['task']
|
63
|
-
)
|
64
|
-
end
|
65
|
-
|
66
|
-
def self.find(id)
|
67
|
-
new CapsuleCRM::Connection.get("/api/task/#{id}")['task']
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.create(attributes = {})
|
71
|
-
new(attributes).tap(&:save)
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.create!(attributes = {})
|
75
|
-
new(attributes).tap(&:save!)
|
76
|
-
end
|
77
|
-
|
78
|
-
def update_attributes(attributes = {})
|
79
|
-
self.attributes = attributes
|
80
|
-
save
|
81
|
-
end
|
82
|
-
|
83
|
-
def update_attributes!(attributes = {})
|
84
|
-
self.attributes = attributes
|
85
|
-
save!
|
86
|
-
end
|
87
|
-
|
88
|
-
def save
|
89
|
-
if valid?
|
90
|
-
new_record? ? create_record : update_record
|
91
|
-
else
|
92
|
-
false
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def save!
|
97
|
-
if valid?
|
98
|
-
save
|
99
|
-
else
|
100
|
-
raise CapsuleCRM::Errors::RecordInvalid.new(self)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
def destroy
|
105
|
-
self.id = nil if CapsuleCRM::Connection.delete("/api/task/#{id}")
|
106
|
-
self
|
107
|
-
end
|
108
|
-
|
109
66
|
def complete
|
110
67
|
CapsuleCRM::Connection.post("/api/task/#{id}/complete")
|
111
68
|
self
|
@@ -116,59 +73,22 @@ module CapsuleCRM
|
|
116
73
|
self
|
117
74
|
end
|
118
75
|
|
76
|
+
# TODO Change this to an embedded association, like custom fields
|
119
77
|
def self.categories
|
120
78
|
CapsuleCRM::Connection.
|
121
79
|
get('/api/task/categories')['taskCategories']['taskCategory']
|
122
80
|
end
|
123
81
|
|
124
|
-
def new_record?
|
125
|
-
!id
|
126
|
-
end
|
127
|
-
|
128
|
-
def persisted?
|
129
|
-
!new_record?
|
130
|
-
end
|
131
|
-
|
132
|
-
def to_capsule_json
|
133
|
-
serializer.serialize
|
134
|
-
end
|
135
|
-
|
136
|
-
private
|
137
|
-
|
138
|
-
def serializer
|
139
|
-
@serializer ||= CapsuleCRM::Serializer.new(self)
|
140
|
-
end
|
141
|
-
|
142
|
-
def capsule_attributes
|
143
|
-
{ description: description, category: category }.tap do |attrs|
|
144
|
-
attrs.merge!(owner: owner.username) if owner
|
145
|
-
attrs.merge!(due_date: due_date.to_s(:db)) if due_date
|
146
|
-
attrs.merge!(due_date_time: due_date_time.to_s(:db)) if due_date_time
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def create_record
|
151
|
-
self.attributes = CapsuleCRM::Connection.post(
|
152
|
-
create_url, to_capsule_json
|
153
|
-
)
|
154
|
-
self
|
155
|
-
end
|
156
|
-
|
157
82
|
def create_url
|
158
83
|
if party_id
|
159
|
-
"
|
84
|
+
"party/#{party_id}/task"
|
160
85
|
elsif opportunity_id
|
161
|
-
"
|
86
|
+
"opportunity/#{opportunity_id}/task"
|
162
87
|
elsif case_id
|
163
|
-
"
|
88
|
+
"kase/#{case_id}/task"
|
164
89
|
else
|
165
|
-
'
|
90
|
+
'task'
|
166
91
|
end
|
167
92
|
end
|
168
|
-
|
169
|
-
def update_record
|
170
|
-
CapsuleCRM::Connection.put("/api/task/#{id}", to_capsule_json)
|
171
|
-
self
|
172
|
-
end
|
173
93
|
end
|
174
94
|
end
|