capsule_crm 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Guardfile +1 -1
- data/lib/capsule_crm.rb +1 -0
- data/lib/capsule_crm/attributes.rb +11 -0
- data/lib/capsule_crm/contactable.rb +3 -0
- data/lib/capsule_crm/contacts.rb +13 -9
- data/lib/capsule_crm/custom_field.rb +5 -16
- data/lib/capsule_crm/email.rb +5 -0
- data/lib/capsule_crm/history.rb +1 -42
- data/lib/capsule_crm/opportunity.rb +1 -30
- data/lib/capsule_crm/organization.rb +1 -21
- data/lib/capsule_crm/party.rb +3 -1
- data/lib/capsule_crm/person.rb +1 -28
- data/lib/capsule_crm/phone.rb +5 -0
- data/lib/capsule_crm/task.rb +1 -5
- data/lib/capsule_crm/version.rb +1 -1
- data/lib/capsule_crm/website.rb +5 -0
- data/spec/lib/capsule_crm/party_spec.rb +57 -1
- data/spec/support/organisation.json +12 -3
- data/spec/support/person.json +28 -3
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 143725dc45cebfffee7104b902cda999f6e5d5a4
|
4
|
+
data.tar.gz: b15eee85686b5e11f0f2c5cea64701ed85d02a9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3ca68c5b10e99a3b7cbe9b2fad98d4a84e1d4b3d79bc7fcfdbe327c038a1b122a5504cd8c02a74b67620cc9f7704571d6b8c06e5717ab2d4aa3e938a16a80fe
|
7
|
+
data.tar.gz: b20d34a05f2695e836e07bf2c1053dcf7806a96297d31dacdfbcf1797b55d9c0f7577a1a77a03109b3f579be816c2cd924ae9b6b81dfc25a197de073c10e2115
|
data/CHANGELOG.md
CHANGED
data/Guardfile
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
notification :tmux
|
5
5
|
|
6
|
-
guard 'rspec', all_on_start: true, all_after_pass: true do
|
6
|
+
guard 'rspec', all_on_start: true, all_after_pass: true, keep_failed: true do
|
7
7
|
watch(%r{^spec/.+_spec\.rb$})
|
8
8
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
9
9
|
watch('spec/spec_helper.rb') { "spec" }
|
data/lib/capsule_crm.rb
CHANGED
data/lib/capsule_crm/contacts.rb
CHANGED
@@ -15,10 +15,10 @@ module CapsuleCRM
|
|
15
15
|
#
|
16
16
|
# Returns a CapsuleCRM::Contact
|
17
17
|
def initialize(attributes = {})
|
18
|
-
self.addresses =
|
19
|
-
self.emails =
|
20
|
-
self.phones =
|
21
|
-
self.websites =
|
18
|
+
self.addresses = attributes[:addresses] || attributes[:address]
|
19
|
+
self.emails = attributes[:emails] || attributes[:email]
|
20
|
+
self.phones = attributes[:phones] || attributes[:phone]
|
21
|
+
self.websites = attributes[:websites] || attributes[:website]
|
22
22
|
end
|
23
23
|
|
24
24
|
# Public: Sets the addresses for this contacts container
|
@@ -34,7 +34,8 @@ module CapsuleCRM
|
|
34
34
|
#
|
35
35
|
# Returns an Array of CapsuleCRM::Address objects
|
36
36
|
def addresses=(addresses)
|
37
|
-
|
37
|
+
addresses = CapsuleCRM::Address.new(addresses) if addresses.is_a?(Hash)
|
38
|
+
@addresses = Array(addresses)
|
38
39
|
end
|
39
40
|
|
40
41
|
# Public: Gets the addresses for this contacts container
|
@@ -45,7 +46,7 @@ module CapsuleCRM
|
|
45
46
|
#
|
46
47
|
# Returns an Array of CapsuleCRM::Address objects
|
47
48
|
def addresses
|
48
|
-
@addresses
|
49
|
+
Array(@addresses)
|
49
50
|
end
|
50
51
|
|
51
52
|
# Public: Sets the emails for this contacts container
|
@@ -61,7 +62,8 @@ module CapsuleCRM
|
|
61
62
|
#
|
62
63
|
# Returns an Array of CapsuleCRM::Email objects
|
63
64
|
def emails=(emails)
|
64
|
-
|
65
|
+
emails = CapsuleCRM::Email.new(emails) if emails.is_a?(Hash)
|
66
|
+
@emails = Array(emails)
|
65
67
|
end
|
66
68
|
|
67
69
|
# Public: Gets the emails for this contacts container
|
@@ -87,7 +89,8 @@ module CapsuleCRM
|
|
87
89
|
#
|
88
90
|
# Returns an Array of CapsuleCRM::Phone objects
|
89
91
|
def phones=(phones)
|
90
|
-
|
92
|
+
phones = CapsuleCRM::Phone.new(phones) if phones.is_a?(Hash)
|
93
|
+
@phones = Array(phones)
|
91
94
|
end
|
92
95
|
|
93
96
|
# Public: Gets the phones for this contacts container
|
@@ -115,7 +118,8 @@ module CapsuleCRM
|
|
115
118
|
#
|
116
119
|
# Returns an Array of CapsuleCRM::Website objects
|
117
120
|
def websites=(websites)
|
118
|
-
|
121
|
+
websites = CapsuleCRM::Website.new(websites) if websites.is_a?(Hash)
|
122
|
+
@websites = Array(websites)
|
119
123
|
end
|
120
124
|
|
121
125
|
# Public: Gets the websites for this contacts container
|
@@ -7,6 +7,7 @@ module CapsuleCRM
|
|
7
7
|
include ActiveModel::Validations
|
8
8
|
|
9
9
|
include CapsuleCRM::Associations
|
10
|
+
include CapsuleCRM::Attributes
|
10
11
|
include CapsuleCRM::Collection
|
11
12
|
|
12
13
|
attribute :id, Integer
|
@@ -33,12 +34,6 @@ module CapsuleCRM
|
|
33
34
|
alias :_for_person :_for_party
|
34
35
|
end
|
35
36
|
|
36
|
-
def attributes=(attributes)
|
37
|
-
CapsuleCRM::HashHelper.underscore_keys!(attributes)
|
38
|
-
super(attributes)
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
37
|
def self.create(attributes = {})
|
43
38
|
new(attributes).tap(&:save)
|
44
39
|
end
|
@@ -69,16 +64,10 @@ module CapsuleCRM
|
|
69
64
|
def to_capsule_json
|
70
65
|
{
|
71
66
|
customFields: {
|
72
|
-
customField: [
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
date: date,
|
77
|
-
tag: tag,
|
78
|
-
boolean: boolean,
|
79
|
-
text: text,
|
80
|
-
}.delete_if { |key, value| value.blank? }
|
81
|
-
)]
|
67
|
+
customField: [
|
68
|
+
CapsuleCRM::HashHelper.camelize_keys(attributes).
|
69
|
+
delete_if { |key, value| value.blank? }
|
70
|
+
]
|
82
71
|
}
|
83
72
|
}
|
84
73
|
end
|
data/lib/capsule_crm/email.rb
CHANGED
data/lib/capsule_crm/history.rb
CHANGED
@@ -7,6 +7,7 @@ module CapsuleCRM
|
|
7
7
|
include ActiveModel::Validations
|
8
8
|
|
9
9
|
include CapsuleCRM::Associations
|
10
|
+
include CapsuleCRM::Attributes
|
10
11
|
include CapsuleCRM::Collection
|
11
12
|
|
12
13
|
attribute :id, Integer
|
@@ -56,48 +57,6 @@ module CapsuleCRM
|
|
56
57
|
)
|
57
58
|
end
|
58
59
|
|
59
|
-
# Public: Underscore all of the attributes keys and set the attributes of
|
60
|
-
# this history item
|
61
|
-
#
|
62
|
-
# attributes - The Hash of history attributes (default: {}):
|
63
|
-
# :id - The Integer ID of this history item
|
64
|
-
# :creator - The String username of the creator
|
65
|
-
# (CapsuleCRM::User) OR a CapsuleCRM::User object
|
66
|
-
# :type - The String type (Note, Email or Task)
|
67
|
-
# :note - The String note
|
68
|
-
# :subject - The String email subject if this history
|
69
|
-
# item is from an email
|
70
|
-
# :entry_date - The date when this history item was
|
71
|
-
# created
|
72
|
-
# :attachments - An Array of CapsuleCRM::Attachment
|
73
|
-
# objects OR an Array of CapsuleCRM::Attachment attributes
|
74
|
-
# hashes
|
75
|
-
# :participants - An Array of CapsuleCRM::Participant
|
76
|
-
# objects OR an Array of CapsuleCRM::Participant attributes
|
77
|
-
# hashes
|
78
|
-
# :party_id - The Integer ID of the party that this
|
79
|
-
# history item belongs to
|
80
|
-
# :case_id - The Integer ID of the case that this
|
81
|
-
# history item belongs to
|
82
|
-
# :opportunity_id - The Integer ID of the opportunity that
|
83
|
-
# this item belongs to
|
84
|
-
#
|
85
|
-
# Examples
|
86
|
-
#
|
87
|
-
# history = CapsuleCRM::History.new
|
88
|
-
# history.attributes = { entry_date: Time.now }
|
89
|
-
#
|
90
|
-
# or
|
91
|
-
#
|
92
|
-
# history.attributes = { entryDate: Time.now }
|
93
|
-
#
|
94
|
-
# Returns a CapsuleCRM::History object
|
95
|
-
def attributes=(attributes)
|
96
|
-
CapsuleCRM::HashHelper.underscore_keys!(attributes)
|
97
|
-
super(attributes)
|
98
|
-
self
|
99
|
-
end
|
100
|
-
|
101
60
|
# Public: find a CapsuleCRM::History by ID
|
102
61
|
#
|
103
62
|
# id - The Integer CapsuleCRM::History ID
|
@@ -7,6 +7,7 @@ module CapsuleCRM
|
|
7
7
|
include ActiveModel::Validations
|
8
8
|
|
9
9
|
include CapsuleCRM::Associations
|
10
|
+
include CapsuleCRM::Attributes
|
10
11
|
include CapsuleCRM::Collection
|
11
12
|
|
12
13
|
attribute :id, Integer
|
@@ -41,36 +42,6 @@ module CapsuleCRM
|
|
41
42
|
self
|
42
43
|
end
|
43
44
|
|
44
|
-
# Public: Set the attributes of a opportunity
|
45
|
-
#
|
46
|
-
# attributes - The Hash of attributes (default: {}):
|
47
|
-
# :name - The String opportunity name
|
48
|
-
# :description - The String opportunity description
|
49
|
-
# :currency - The String currency code
|
50
|
-
# :value - The Float opportunity (financial) value
|
51
|
-
# :duration_basis - The String duration basis
|
52
|
-
# :duration - The Integer duration (for opportunities
|
53
|
-
# with a repeating (not FIXED) duratin basis
|
54
|
-
# :party_id - The Integer party id
|
55
|
-
# :milestone_id - The Integer milestone id
|
56
|
-
# :expected_close_date - The DateTime when the opportunity
|
57
|
-
# is expected to be closed
|
58
|
-
# :actual_close_date - The DateTime when the opportunity
|
59
|
-
# was actually closed
|
60
|
-
# :probability - The Float probability that this
|
61
|
-
# opportunity will be won
|
62
|
-
#
|
63
|
-
# Examples
|
64
|
-
#
|
65
|
-
# CapsuleCRM::Opportunity.new
|
66
|
-
#
|
67
|
-
# Returns a CapsuleCRM::Opportunity
|
68
|
-
def attributes=(attributes)
|
69
|
-
CapsuleCRM::HashHelper.underscore_keys!(attributes)
|
70
|
-
super(attributes)
|
71
|
-
self
|
72
|
-
end
|
73
|
-
|
74
45
|
# Public: Get all opportunities from Capsule. The list can be restricted
|
75
46
|
# and/or paginated with various query parameters sent through the options
|
76
47
|
# hash.
|
@@ -2,8 +2,6 @@ require 'active_support/core_ext'
|
|
2
2
|
|
3
3
|
module CapsuleCRM
|
4
4
|
class Organization < CapsuleCRM::Party
|
5
|
-
include Virtus
|
6
|
-
|
7
5
|
extend ActiveModel::Naming
|
8
6
|
extend ActiveModel::Callbacks
|
9
7
|
extend ActiveModel::Conversion
|
@@ -24,23 +22,6 @@ module CapsuleCRM
|
|
24
22
|
has_many :people, class_name: 'CapsuleCRM::Person', source: :organization
|
25
23
|
has_many :custom_fields, class_name: 'CapsuleCRM::CustomField', source: :organization
|
26
24
|
|
27
|
-
# Public: Set the attributes of an organization
|
28
|
-
#
|
29
|
-
# attributes - The Hash of attributes (default: {}):
|
30
|
-
# :name - The String organization name
|
31
|
-
# :about - The String information about the organization
|
32
|
-
#
|
33
|
-
# Examples
|
34
|
-
#
|
35
|
-
# CapsuleCRM::Organization.new
|
36
|
-
#
|
37
|
-
# Returns a CapsuleCRM::Organization
|
38
|
-
def attributes=(attributes)
|
39
|
-
CapsuleCRM::HashHelper.underscore_keys!(attributes)
|
40
|
-
super(attributes)
|
41
|
-
self
|
42
|
-
end
|
43
|
-
|
44
25
|
# Public: Get all people from Capsule. The list can be restricted
|
45
26
|
# and/or paginated with various query parameters sent through the options
|
46
27
|
# hash.
|
@@ -229,9 +210,8 @@ module CapsuleCRM
|
|
229
210
|
#
|
230
211
|
# Returns a Hash
|
231
212
|
def to_capsule_json
|
232
|
-
self.contacts = nil if self.contacts.blank?
|
233
213
|
{
|
234
|
-
organisation: attributes.merge(
|
214
|
+
organisation: attributes.merge(contacts: contacts.to_capsule_json).
|
235
215
|
stringify_keys
|
236
216
|
}.stringify_keys
|
237
217
|
end
|
data/lib/capsule_crm/party.rb
CHANGED
data/lib/capsule_crm/person.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module CapsuleCRM
|
2
2
|
class Person < CapsuleCRM::Party
|
3
|
-
include Virtus
|
4
|
-
|
5
3
|
include CapsuleCRM::Collection
|
6
4
|
include CapsuleCRM::Contactable
|
7
5
|
include CapsuleCRM::Associations::BelongsTo
|
@@ -62,30 +60,6 @@ module CapsuleCRM
|
|
62
60
|
)
|
63
61
|
end
|
64
62
|
|
65
|
-
# Public: Set the attributes of a person
|
66
|
-
#
|
67
|
-
# attributes - The Hash of attributes (default: {}):
|
68
|
-
# :first_name - The String person first name
|
69
|
-
# :last_name - The String person last name
|
70
|
-
# :job_title - The String job title
|
71
|
-
# :about - The String information about the person
|
72
|
-
# :organisation_name - The String name of the organisation. If
|
73
|
-
# this organisation does not exist in capsule then a new one
|
74
|
-
# will be created on save
|
75
|
-
# :organisation_id - The Integer ID of the organisation in
|
76
|
-
# capsulecrm.
|
77
|
-
#
|
78
|
-
# Examples
|
79
|
-
#
|
80
|
-
# CapsuleCRM::Person.new
|
81
|
-
#
|
82
|
-
# Returns a CapsuleCRM::Person
|
83
|
-
def attributes=(attributes)
|
84
|
-
CapsuleCRM::HashHelper.underscore_keys!(attributes)
|
85
|
-
super(attributes)
|
86
|
-
self
|
87
|
-
end
|
88
|
-
|
89
63
|
# Public: Create a new person in capsulecrm
|
90
64
|
#
|
91
65
|
# attributes - The Hash of person attributes (default: {}):
|
@@ -246,11 +220,10 @@ module CapsuleCRM
|
|
246
220
|
#
|
247
221
|
# Returns a Hash
|
248
222
|
def to_capsule_json
|
249
|
-
self.contacts = nil if self.contacts.blank?
|
250
223
|
{
|
251
224
|
person: CapsuleCRM::HashHelper.camelize_keys(
|
252
225
|
attributes.dup.delete_if { |key, value| value.blank? }.
|
253
|
-
merge(
|
226
|
+
merge(contacts: contacts.to_capsule_json)
|
254
227
|
)
|
255
228
|
}.stringify_keys
|
256
229
|
end
|
data/lib/capsule_crm/phone.rb
CHANGED
data/lib/capsule_crm/task.rb
CHANGED
@@ -7,6 +7,7 @@ module CapsuleCRM
|
|
7
7
|
include ActiveModel::Validations
|
8
8
|
|
9
9
|
include CapsuleCRM::Associations::BelongsTo
|
10
|
+
include CapsuleCRM::Attributes
|
10
11
|
include CapsuleCRM::Collection
|
11
12
|
|
12
13
|
attribute :id, Integer
|
@@ -49,11 +50,6 @@ module CapsuleCRM
|
|
49
50
|
)
|
50
51
|
end
|
51
52
|
|
52
|
-
def attributes=(attributes)
|
53
|
-
CapsuleCRM::HashHelper.underscore_keys!(attributes)
|
54
|
-
super(attributes)
|
55
|
-
end
|
56
|
-
|
57
53
|
def owner=(user)
|
58
54
|
user = CapsuleCRM::User.find_by_username(user) if user.is_a?(String)
|
59
55
|
@owner = user
|
data/lib/capsule_crm/version.rb
CHANGED
data/lib/capsule_crm/website.rb
CHANGED
@@ -4,7 +4,63 @@ describe CapsuleCRM::Party do
|
|
4
4
|
before { configure }
|
5
5
|
|
6
6
|
describe '.find' do
|
7
|
-
|
7
|
+
context 'when finding an organization' do
|
8
|
+
before do
|
9
|
+
stub_request(:get, /\/api\/party\/#{id}$/).
|
10
|
+
to_return(body: File.read('spec/support/organisation.json'))
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { CapsuleCRM::Party.find(id) }
|
14
|
+
|
15
|
+
let(:id) { rand(10) }
|
16
|
+
|
17
|
+
it { expect(subject).to be_a(CapsuleCRM::Organization) }
|
18
|
+
|
19
|
+
it { expect(subject.contacts).to be_a(CapsuleCRM::Contacts) }
|
20
|
+
|
21
|
+
it 'should get the contact address street' do
|
22
|
+
expect(subject.addresses.first.street).
|
23
|
+
to eql('1600 Amphitheatre Parkway')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should get the contact address city' do
|
27
|
+
expect(subject.addresses.first.city).
|
28
|
+
to eql('Mountain View')
|
29
|
+
end
|
30
|
+
|
31
|
+
it { expect(subject.addresses.first.state).to eql('CA') }
|
32
|
+
|
33
|
+
it { expect(subject.addresses.first.zip).to eql('94043') }
|
34
|
+
|
35
|
+
it 'should get the contact address country' do
|
36
|
+
expect(subject.addresses.first.country).
|
37
|
+
to eql('United States')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when finding a person' do
|
42
|
+
before do
|
43
|
+
stub_request(:get, /\/api\/party\/#{id}$/).
|
44
|
+
to_return(body: File.read('spec/support/person.json'))
|
45
|
+
end
|
46
|
+
|
47
|
+
subject { CapsuleCRM::Party.find(id) }
|
48
|
+
|
49
|
+
let(:id) { rand(10) }
|
50
|
+
|
51
|
+
it 'should get the email address' do
|
52
|
+
expect(subject.emails.first.email_address).
|
53
|
+
to eql('e.schmidt@google.com')
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should get the phone number' do
|
57
|
+
expect(subject.phones.first.phone_number).to eql('+1 888 555555')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should get the website' do
|
61
|
+
expect(subject.websites.first.web_address).to eql('www.google.com')
|
62
|
+
end
|
63
|
+
end
|
8
64
|
end
|
9
65
|
|
10
66
|
describe '.all' do
|
@@ -1,8 +1,17 @@
|
|
1
1
|
{
|
2
2
|
"organisation": {
|
3
|
-
"
|
4
|
-
|
3
|
+
"contacts": {
|
4
|
+
"address": {
|
5
|
+
"type": "Office",
|
6
|
+
"street": "1600 Amphitheatre Parkway",
|
7
|
+
"city": "Mountain View",
|
8
|
+
"state": "CA",
|
9
|
+
"zip": "94043",
|
10
|
+
"country": "United States"
|
11
|
+
}
|
12
|
+
},
|
13
|
+
"id": "1",
|
5
14
|
"name": "Google Inc",
|
6
|
-
"
|
15
|
+
"about": "A comment here"
|
7
16
|
}
|
8
17
|
}
|
data/spec/support/person.json
CHANGED
@@ -1,9 +1,34 @@
|
|
1
1
|
{
|
2
2
|
"person": {
|
3
|
+
"contacts": {
|
4
|
+
"address": {
|
5
|
+
"type": "Office",
|
6
|
+
"street": "1600 Amphitheatre Parkway",
|
7
|
+
"city": "Mountain View",
|
8
|
+
"state": "CA",
|
9
|
+
"zip": "94043",
|
10
|
+
"country": "United States"
|
11
|
+
},
|
12
|
+
"email": {
|
13
|
+
"type": "Home",
|
14
|
+
"emailAddress": "e.schmidt@google.com"
|
15
|
+
},
|
16
|
+
"phone": {
|
17
|
+
"type": "Mobile",
|
18
|
+
"phoneNumber": "+1 888 555555"
|
19
|
+
},
|
20
|
+
"website": {
|
21
|
+
"type": "work",
|
22
|
+
"webService": "URL",
|
23
|
+
"webAddress": "www.google.com"
|
24
|
+
}
|
25
|
+
},
|
3
26
|
"id": "100",
|
4
|
-
"
|
5
|
-
"createdOn": "2011-09-14T15:22:01Z",
|
27
|
+
"title": "Mr",
|
6
28
|
"firstName": "Eric",
|
7
|
-
"
|
29
|
+
"lastName": "Schmidt",
|
30
|
+
"jobTitle": "Chairman",
|
31
|
+
"organisationName": "Google Inc",
|
32
|
+
"about": "A comment here"
|
8
33
|
}
|
9
34
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capsule_crm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Beedle
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -259,6 +259,7 @@ files:
|
|
259
259
|
- lib/capsule_crm/associations/has_many.rb
|
260
260
|
- lib/capsule_crm/associations/has_many_proxy.rb
|
261
261
|
- lib/capsule_crm/attachment.rb
|
262
|
+
- lib/capsule_crm/attributes.rb
|
262
263
|
- lib/capsule_crm/capsule_jsonable.rb
|
263
264
|
- lib/capsule_crm/case.rb
|
264
265
|
- lib/capsule_crm/collection.rb
|