capsule_crm 1.7.0 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/capsule_crm/associations/belongs_to_finder.rb +11 -3
- data/lib/capsule_crm/associations/has_many.rb +2 -5
- data/lib/capsule_crm/associations/has_many_association.rb +1 -1
- data/lib/capsule_crm/associations/has_many_proxy.rb +3 -2
- data/lib/capsule_crm/custom_field.rb +15 -4
- data/lib/capsule_crm/organization.rb +12 -0
- data/lib/capsule_crm/person.rb +12 -0
- data/lib/capsule_crm/querying/find_one.rb +8 -0
- data/lib/capsule_crm/version.rb +1 -1
- data/spec/lib/capsule_crm/associations/belongs_to_finder_spec.rb +2 -1
- data/spec/lib/capsule_crm/custom_field_spec.rb +38 -1
- data/spec/lib/capsule_crm/organization_spec.rb +8 -0
- data/spec/lib/capsule_crm/person_spec.rb +8 -0
- data/spec/support/put_customfields.json +20 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40b178add184629b0011c050d6c021eecb3061ed
|
4
|
+
data.tar.gz: 07a406a438880798916012ef6af98fe59786db58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5e6e13677f95912036882050ad7e5babb5a662b813007ffe94ed293a10d5b0b54858aaa9459206d9065cce3fd2583263876bc48f30b26e221b1f149f7013bd8
|
7
|
+
data.tar.gz: 4966758a6dfc65e830d68e133341dd104861e7afce472ea43907ed27fd7c65c3c23e15ed73138cdbd9a8154ee6201966e51f4b1247a13da56fa02ef316f0a3ea
|
data/CHANGELOG.md
CHANGED
@@ -9,7 +9,7 @@ module CapsuleCRM
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def call(id)
|
12
|
-
id ?
|
12
|
+
id ? find_by_parent_id(id) : []
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
@@ -18,6 +18,10 @@ module CapsuleCRM
|
|
18
18
|
@inverse ||= association.inverse
|
19
19
|
end
|
20
20
|
|
21
|
+
def embedded?
|
22
|
+
inverse.embedded
|
23
|
+
end
|
24
|
+
|
21
25
|
def singular
|
22
26
|
@singular ||= inverse.defined_on.queryable_options.singular
|
23
27
|
end
|
@@ -26,8 +30,12 @@ module CapsuleCRM
|
|
26
30
|
@plural ||= association.defined_on.queryable_options.plural
|
27
31
|
end
|
28
32
|
|
29
|
-
def
|
30
|
-
normalizer.normalize_collection
|
33
|
+
def find_by_parent_id(id)
|
34
|
+
normalizer.normalize_collection(get(path(id))).tap do |collection|
|
35
|
+
collection.each do |item|
|
36
|
+
item.send("#{association.foreign_key}=", id)
|
37
|
+
end if embedded?
|
38
|
+
end
|
31
39
|
end
|
32
40
|
|
33
41
|
def get(path_string)
|
@@ -41,10 +41,8 @@ module CapsuleCRM
|
|
41
41
|
|
42
42
|
if options[:embedded]
|
43
43
|
define_method "save_#{association_name}" do
|
44
|
-
unless
|
45
|
-
|
46
|
-
a = self.send(association_name)
|
47
|
-
a.save
|
44
|
+
unless send(association_name).empty?
|
45
|
+
send(association_name).save
|
48
46
|
end
|
49
47
|
end
|
50
48
|
|
@@ -52,7 +50,6 @@ module CapsuleCRM
|
|
52
50
|
after_save :"save_#{association_name}" if respond_to?(:after_save)
|
53
51
|
private :"save_#{association_name}"
|
54
52
|
end
|
55
|
-
|
56
53
|
end
|
57
54
|
|
58
55
|
define_method association_name do
|
@@ -5,7 +5,7 @@ module CapsuleCRM
|
|
5
5
|
|
6
6
|
# Public: Initialize a new CapsuleCRM::Associations::HasManyAssociation
|
7
7
|
#
|
8
|
-
# association_name - The
|
8
|
+
# association_name - The Symbol association name
|
9
9
|
# defined_on - The String name of the class that this association
|
10
10
|
# is defined on
|
11
11
|
# options - The Hash of association options
|
@@ -8,6 +8,7 @@ module CapsuleCRM
|
|
8
8
|
@target_klass = target_klass
|
9
9
|
@source = source
|
10
10
|
@embedded = embedded
|
11
|
+
self
|
11
12
|
end
|
12
13
|
|
13
14
|
def method_missing(name, *args, &block)
|
@@ -25,14 +26,14 @@ module CapsuleCRM
|
|
25
26
|
record = build(attributes).tap do |r|
|
26
27
|
record_not_saved(r) unless parent.persisted?
|
27
28
|
end
|
28
|
-
embedded? ? save : record.save
|
29
|
+
record if embedded? ? save : record.save
|
29
30
|
end
|
30
31
|
|
31
32
|
def create!(attributes = {})
|
32
33
|
record = build(attributes).tap do |r|
|
33
34
|
record_not_saved(r) unless parent.persisted?
|
34
35
|
end
|
35
|
-
embedded? ? save! : record.save!
|
36
|
+
record if embedded? ? save! : record.save!
|
36
37
|
end
|
37
38
|
|
38
39
|
def tap
|
@@ -12,7 +12,7 @@ module CapsuleCRM
|
|
12
12
|
include CapsuleCRM::Serializable
|
13
13
|
|
14
14
|
serializable_config do |config|
|
15
|
-
config.root
|
15
|
+
config.root = 'customField'
|
16
16
|
config.collection_root = 'customFields'
|
17
17
|
end
|
18
18
|
|
@@ -30,13 +30,24 @@ module CapsuleCRM
|
|
30
30
|
validates :id, numericality: { allow_blank: true }
|
31
31
|
validates :label, presence: true
|
32
32
|
|
33
|
-
belongs_to :party
|
34
|
-
belongs_to :opportunity
|
35
|
-
belongs_to :case
|
33
|
+
belongs_to :party, serialize: false
|
34
|
+
belongs_to :opportunity, serialize: false
|
35
|
+
belongs_to :case, serialize: false
|
36
36
|
|
37
37
|
class << self
|
38
38
|
alias :_for_organization :_for_party
|
39
39
|
alias :_for_person :_for_party
|
40
40
|
end
|
41
|
+
|
42
|
+
def parent
|
43
|
+
party || opportunity || self.case
|
44
|
+
end
|
45
|
+
|
46
|
+
def destroy
|
47
|
+
self.date, self.tag, self.boolean, self.text = nil, nil, nil, nil
|
48
|
+
parent.custom_fields.save
|
49
|
+
parent.custom_fields.delete_if { |cf| cf.id == id }
|
50
|
+
true
|
51
|
+
end
|
41
52
|
end
|
42
53
|
end
|
@@ -63,5 +63,17 @@ module CapsuleCRM
|
|
63
63
|
CapsuleCRM::Party.all(options).
|
64
64
|
delete_if { |item| !item.is_a?(CapsuleCRM::Organization) }
|
65
65
|
end
|
66
|
+
|
67
|
+
def self.first
|
68
|
+
raise NotImplementedError.new(
|
69
|
+
[
|
70
|
+
'Unfortunately the capsulecrm.com API returns people and',
|
71
|
+
'organizations in one response. There is no way to query directly',
|
72
|
+
'for people. This means that quite often the first item returned',
|
73
|
+
'will actually be a person and so CapsuleCRM::Organization.first is',
|
74
|
+
'not possible.'
|
75
|
+
].join(' ')
|
76
|
+
)
|
77
|
+
end
|
66
78
|
end
|
67
79
|
end
|
data/lib/capsule_crm/person.rb
CHANGED
@@ -66,6 +66,18 @@ module CapsuleCRM
|
|
66
66
|
delete_if { |item| !item.is_a?(CapsuleCRM::Person) }
|
67
67
|
end
|
68
68
|
|
69
|
+
def self.first
|
70
|
+
raise NotImplementedError.new(
|
71
|
+
[
|
72
|
+
'Unfortunately the capsulecrm.com API returns people and',
|
73
|
+
'organizations in one response. There is no way to query directly',
|
74
|
+
'for people. This means that quite often the first item returned',
|
75
|
+
'will actually be an organization and so CapsuleCRM::Person.first is',
|
76
|
+
'not possible.'
|
77
|
+
].join(' ')
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
69
81
|
private
|
70
82
|
|
71
83
|
# Private: Determines whether the person first name is required. Either the
|
@@ -9,6 +9,14 @@ module CapsuleCRM
|
|
9
9
|
get("/api/#{queryable_options.singular}/#{id}")
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
def reload
|
14
|
+
self.attributes = self.class.find(id).attributes
|
15
|
+
associations.keys.each do |association_name|
|
16
|
+
instance_variable_set(:"@#{association_name}", nil)
|
17
|
+
end
|
18
|
+
self
|
19
|
+
end
|
12
20
|
end
|
13
21
|
end
|
14
22
|
end
|
data/lib/capsule_crm/version.rb
CHANGED
@@ -10,12 +10,13 @@ describe CapsuleCRM::Associations::BelongsToFinder do
|
|
10
10
|
)
|
11
11
|
end
|
12
12
|
let(:inverse) do
|
13
|
-
double('CapsuleCRM::Associations::HasManyAssociation')
|
13
|
+
double('CapsuleCRM::Associations::HasManyAssociation', embedded: false)
|
14
14
|
end
|
15
15
|
let(:normalizer) do
|
16
16
|
double('CapsuleCRM::Normalizer', normalize_collection: [])
|
17
17
|
end
|
18
18
|
let(:finder) { described_class.new(association) }
|
19
|
+
|
19
20
|
before do
|
20
21
|
finder.singular = 'person'
|
21
22
|
finder.plural = 'customfields'
|
@@ -27,7 +27,8 @@ describe CapsuleCRM::CustomField do
|
|
27
27
|
|
28
28
|
it { should be_an(Array) }
|
29
29
|
it do
|
30
|
-
subject.all? { |item| item.is_a?(CapsuleCRM::CustomField) }.
|
30
|
+
subject.all? { |item| item.is_a?(CapsuleCRM::CustomField) }.
|
31
|
+
should be_true
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
@@ -53,4 +54,40 @@ describe CapsuleCRM::CustomField do
|
|
53
54
|
expect(subject.keys.first).to eql('customField')
|
54
55
|
end
|
55
56
|
end
|
57
|
+
|
58
|
+
describe '#destroy' do
|
59
|
+
let(:custom_field) { Fabricate.build(:custom_field, party: person) }
|
60
|
+
let(:person) { Fabricate.build(:person, id: Random.rand(1..10)) }
|
61
|
+
|
62
|
+
def stub_requests
|
63
|
+
stub_request(
|
64
|
+
:get,
|
65
|
+
[
|
66
|
+
'https://1234:@company.capsulecrm.com/api/party/',
|
67
|
+
person.id,
|
68
|
+
'/customfields'
|
69
|
+
].join
|
70
|
+
).to_return(body: File.read('spec/support/no_customfields.json'))
|
71
|
+
# note, this test still passes although completely different data is being
|
72
|
+
# returned from this stub. The data returned should overwrite the
|
73
|
+
# association data
|
74
|
+
stub_request(
|
75
|
+
:put, [
|
76
|
+
'https://1234:@company.capsulecrm.com/api/party/',
|
77
|
+
person.id,
|
78
|
+
'/customfields'
|
79
|
+
].join
|
80
|
+
).to_return(body: File.read('spec/support/put_customfields.json'))
|
81
|
+
end
|
82
|
+
|
83
|
+
before do
|
84
|
+
stub_requests
|
85
|
+
person.custom_fields << custom_field
|
86
|
+
custom_field.destroy
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should remove the custom field from the parent association' do
|
90
|
+
expect(person.custom_fields).not_to include(custom_field)
|
91
|
+
end
|
92
|
+
end
|
56
93
|
end
|
@@ -48,6 +48,14 @@ describe CapsuleCRM::Organization do
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
describe '.first' do
|
52
|
+
subject { described_class }
|
53
|
+
|
54
|
+
it 'should raise a NotImplementedError' do
|
55
|
+
expect { subject.first }.to raise_error(NotImplementedError)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
51
59
|
describe '#custom_fields' do
|
52
60
|
before do
|
53
61
|
stub_request(:get, /\/api\/party\/#{organization.id}\/customfields/).
|
@@ -68,6 +68,14 @@ describe CapsuleCRM::Person do
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
describe '.first' do
|
72
|
+
subject { described_class }
|
73
|
+
|
74
|
+
it 'should raise a NotImplementedError' do
|
75
|
+
expect { subject.first }.to raise_error(NotImplementedError)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
71
79
|
describe '#tasks' do
|
72
80
|
let(:person) { Fabricate.build(:person, id: 1) }
|
73
81
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"customFields": {
|
3
|
+
"customField": [
|
4
|
+
{
|
5
|
+
"tag": "Staff",
|
6
|
+
"label": "NI Number",
|
7
|
+
"text": "12345678"
|
8
|
+
},
|
9
|
+
{
|
10
|
+
"tag": "Staff",
|
11
|
+
"label": "Start Date",
|
12
|
+
"date": "2011-03-13T00:00:00Z"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"label": "Send newsletter",
|
16
|
+
"boolean": "true"
|
17
|
+
}
|
18
|
+
]
|
19
|
+
}
|
20
|
+
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capsule_crm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Beedle
|
@@ -388,6 +388,7 @@ files:
|
|
388
388
|
- spec/support/opportunity.json
|
389
389
|
- spec/support/organisation.json
|
390
390
|
- spec/support/person.json
|
391
|
+
- spec/support/put_customfields.json
|
391
392
|
- spec/support/shared_examples/capsule_json.rb
|
392
393
|
- spec/support/shared_examples/contactable.rb
|
393
394
|
- spec/support/shared_examples/deletable.rb
|
@@ -499,6 +500,7 @@ test_files:
|
|
499
500
|
- spec/support/opportunity.json
|
500
501
|
- spec/support/organisation.json
|
501
502
|
- spec/support/person.json
|
503
|
+
- spec/support/put_customfields.json
|
502
504
|
- spec/support/shared_examples/capsule_json.rb
|
503
505
|
- spec/support/shared_examples/contactable.rb
|
504
506
|
- spec/support/shared_examples/deletable.rb
|