capsulecrm 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README +29 -0
- data/Rakefile +9 -0
- data/capsulecrm.gemspec +25 -0
- data/examples.rb +65 -0
- data/lib/capsulecrm.rb +40 -0
- data/lib/capsulecrm/address.rb +23 -0
- data/lib/capsulecrm/base.rb +175 -0
- data/lib/capsulecrm/child.rb +24 -0
- data/lib/capsulecrm/child_collection.rb +14 -0
- data/lib/capsulecrm/collection.rb +14 -0
- data/lib/capsulecrm/contact.rb +12 -0
- data/lib/capsulecrm/custom_field.rb +41 -0
- data/lib/capsulecrm/email.rb +15 -0
- data/lib/capsulecrm/organisation.rb +41 -0
- data/lib/capsulecrm/party.rb +64 -0
- data/lib/capsulecrm/person.rb +125 -0
- data/lib/capsulecrm/phone.rb +15 -0
- data/lib/capsulecrm/record_not_found.rb +1 -0
- data/lib/capsulecrm/version.rb +3 -0
- data/test/create_person_test.rb +36 -0
- data/test/fixtures/responses/create_person.yml +59 -0
- data/test/fixtures/responses/person_find_all.yml +28 -0
- data/test/fixtures/responses/person_find_all_with_limit.yml +26 -0
- data/test/fixtures/responses/person_find_all_with_offset.yml +28 -0
- data/test/fixtures/responses/person_find_by_id.yml +76 -0
- data/test/fixtures/responses/update_person.yml +85 -0
- data/test/fixtures/responses/update_person_without_changes.yml +28 -0
- data/test/person_dot_find_all_test.rb +48 -0
- data/test/person_dot_find_by_id_test.rb +57 -0
- data/test/test_helper.rb +51 -0
- data/test/update_person_test.rb +46 -0
- metadata +147 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
class CapsuleCRM::CustomField < CapsuleCRM::Child
|
2
|
+
|
3
|
+
attr_accessor :boolean
|
4
|
+
attr_accessor :date
|
5
|
+
attr_accessor :label
|
6
|
+
attr_accessor :text
|
7
|
+
|
8
|
+
|
9
|
+
# nodoc
|
10
|
+
def boolean=(value)
|
11
|
+
return @boolean = true if value.to_s == 'true'
|
12
|
+
@boolean = false
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
# nodoc
|
17
|
+
def date=(value)
|
18
|
+
value = Time.parse(value) if value.is_a?(String)
|
19
|
+
@date = value
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# nodoc
|
24
|
+
def value
|
25
|
+
date || text || boolean
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# nodoc
|
30
|
+
def self.xml_map
|
31
|
+
map = {
|
32
|
+
'label' => 'label',
|
33
|
+
'text' => 'text',
|
34
|
+
'date' => 'date',
|
35
|
+
'boolean' => 'boolean'
|
36
|
+
}
|
37
|
+
super.merge map
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class CapsuleCRM::Organisation < CapsuleCRM::Party
|
2
|
+
|
3
|
+
attr_accessor :about
|
4
|
+
attr_accessor :name
|
5
|
+
|
6
|
+
|
7
|
+
# nodoc
|
8
|
+
def people
|
9
|
+
return @people if @people
|
10
|
+
path = self.class.base_path
|
11
|
+
path = [path, '/', id, '/people'].join
|
12
|
+
last_response = self.class.get(path)
|
13
|
+
@people = CapsuleCRM::Person.init_many(last_response)
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# nodoc
|
18
|
+
def self.init_many(response)
|
19
|
+
data = response['parties']['organisation']
|
20
|
+
CapsuleCRM::Collection.new(self, data)
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# nodoc
|
25
|
+
def self.init_one(response)
|
26
|
+
data = response['organisation']
|
27
|
+
new(attributes_from_xml_hash(data))
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# nodoc
|
32
|
+
def self.xml_map
|
33
|
+
map = {
|
34
|
+
'about' => 'about',
|
35
|
+
'name' => 'name'
|
36
|
+
}
|
37
|
+
super.merge map
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class CapsuleCRM::Party < CapsuleCRM::Base
|
2
|
+
|
3
|
+
|
4
|
+
# nodoc
|
5
|
+
def addresses
|
6
|
+
return @addresses if @addresses
|
7
|
+
data = raw_data['contacts']['address']
|
8
|
+
@addresses = CapsuleCRM::Address.init_many(self, data)
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
# nodoc
|
13
|
+
def custom_fields
|
14
|
+
return @custom_fields if @custom_fields
|
15
|
+
path = self.class.base_path
|
16
|
+
path = [path, '/', id, '/customfield'].join
|
17
|
+
last_response = self.class.get(path)
|
18
|
+
data = last_response['customFields']['customField']
|
19
|
+
@custom_fields = CapsuleCRM::CustomField.init_many(self, data)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# nodoc
|
24
|
+
def emails
|
25
|
+
return @emails if @emails
|
26
|
+
data = raw_data['contacts']['email']
|
27
|
+
@emails = CapsuleCRM::Email.init_many(self, data)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# nodoc
|
32
|
+
def phone_numbers
|
33
|
+
return @phone_numbers if @phone_numbers
|
34
|
+
data = raw_data['contacts']['phone']
|
35
|
+
@phone_numbers = CapsuleCRM::Phone.init_many(self, data)
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# nodoc
|
40
|
+
def self.get_path
|
41
|
+
'/api/party'
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def self.find_all_by_email(email, options={})
|
46
|
+
options[:email] = email
|
47
|
+
find_all(options)
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
# nodoc
|
52
|
+
def self.find_by_email(email)
|
53
|
+
find_all_by_email(email, :limit => 1, :offset => 0).first
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
# nodoc
|
58
|
+
def self.search(query, options={})
|
59
|
+
options[:q] = query
|
60
|
+
find_all(options)
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
class CapsuleCRM::Person < CapsuleCRM::Party
|
2
|
+
|
3
|
+
attr_accessor :about
|
4
|
+
attr_accessor :first_name
|
5
|
+
attr_accessor :job_title
|
6
|
+
attr_accessor :last_name
|
7
|
+
attr_accessor :organisation_id
|
8
|
+
attr_accessor :title
|
9
|
+
|
10
|
+
|
11
|
+
define_attribute_methods [:about, :first_name, :last_name, :job_title, :organisation_id, :title]
|
12
|
+
|
13
|
+
|
14
|
+
# nodoc
|
15
|
+
def attributes
|
16
|
+
attrs = {}
|
17
|
+
arr = [:about, :first_name, :last_name, :title, :job_title]
|
18
|
+
arr.each do |key|
|
19
|
+
attrs[key] = self.send(key)
|
20
|
+
end
|
21
|
+
attrs
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# nodoc
|
26
|
+
def first_name=(value)
|
27
|
+
first_name_will_change! unless value == first_name
|
28
|
+
@first_name = value
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# nodoc
|
33
|
+
def last_name=(value)
|
34
|
+
last_name_will_change! unless value == last_name
|
35
|
+
@last_name = value
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# nodoc
|
40
|
+
def title=(value)
|
41
|
+
title_will_change! unless value == title
|
42
|
+
@title = value
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# nodoc
|
47
|
+
def organisation
|
48
|
+
return nil if organisation_id.nil?
|
49
|
+
@organisation ||= CapsuleCRM::Organisation.find(organisation_id)
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# nodoc
|
54
|
+
def save
|
55
|
+
new_record?? create : update
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
|
62
|
+
# nodoc
|
63
|
+
def create
|
64
|
+
path = '/api/person'
|
65
|
+
options = {:root => 'person', :path => path}
|
66
|
+
new_id = self.class.create dirty_attributes, options
|
67
|
+
unless new_id
|
68
|
+
errors << self.class.last_response.response.message
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
@errors = []
|
72
|
+
changed_attributes.clear
|
73
|
+
self.id = new_id
|
74
|
+
self
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# nodoc
|
79
|
+
def dirty_attributes
|
80
|
+
Hash[attributes.select { |k,v| changed.include? k.to_s }]
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
# nodoc
|
85
|
+
def update
|
86
|
+
path = '/api/person/' + id.to_s
|
87
|
+
options = {:root => 'person', :path => path}
|
88
|
+
success = self.class.update id, dirty_attributes, options
|
89
|
+
changed_attributes.clear if success
|
90
|
+
success
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# -- Class methods --
|
95
|
+
|
96
|
+
|
97
|
+
# nodoc
|
98
|
+
def self.init_many(response)
|
99
|
+
data = response['parties']['person']
|
100
|
+
CapsuleCRM::Collection.new(self, data)
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
# nodoc
|
105
|
+
def self.init_one(response)
|
106
|
+
data = response['person']
|
107
|
+
new(attributes_from_xml_hash(data))
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
# nodoc
|
112
|
+
def self.xml_map
|
113
|
+
map = {
|
114
|
+
'about' => 'about',
|
115
|
+
'firstName' => 'first_name',
|
116
|
+
'jobTitle' => 'job_title',
|
117
|
+
'lastName' => 'last_name',
|
118
|
+
'organisationId' => 'organisation_id',
|
119
|
+
'title' => 'title'
|
120
|
+
}
|
121
|
+
super.merge map
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
class CapsuleCRM::RecordNotFound < StandardError; end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
class CreatePersonTest < Test::Unit::TestCase
|
3
|
+
|
4
|
+
# nodoc
|
5
|
+
def setup
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
# nodoc
|
10
|
+
def test_success
|
11
|
+
VCR.use_cassette('create_person') do
|
12
|
+
|
13
|
+
# save a new object, check for the id
|
14
|
+
person = CapsuleCRM::Person.new
|
15
|
+
person.first_name = 'Homer'
|
16
|
+
person.last_name = 'Simpson'
|
17
|
+
assert person.save
|
18
|
+
assert !person.id.nil?
|
19
|
+
|
20
|
+
|
21
|
+
# check it was persisted
|
22
|
+
person = CapsuleCRM::Person.find person.id
|
23
|
+
assert_equal 'Homer', person.first_name
|
24
|
+
assert_equal 'Simpson', person.last_name
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# nodoc
|
31
|
+
def teardown
|
32
|
+
WebMock.reset!
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :post
|
5
|
+
uri: https://[API-TOKEN]:x@[ACCOUNT-NAME].capsulecrm.com:443/api/person
|
6
|
+
body: |
|
7
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
8
|
+
<person>
|
9
|
+
<lastName>Simpson</lastName>
|
10
|
+
<firstName>Homer</firstName>
|
11
|
+
</person>
|
12
|
+
|
13
|
+
headers:
|
14
|
+
content-type:
|
15
|
+
- text/xml
|
16
|
+
response: !ruby/struct:VCR::Response
|
17
|
+
status: !ruby/struct:VCR::ResponseStatus
|
18
|
+
code: 201
|
19
|
+
message: Created
|
20
|
+
headers:
|
21
|
+
location:
|
22
|
+
- https://[ACCOUNT-NAME].capsulecrm.com/api/party/10256313
|
23
|
+
content-type:
|
24
|
+
- text/plain; charset=UTF-8
|
25
|
+
server:
|
26
|
+
- Apache
|
27
|
+
date:
|
28
|
+
- Tue, 12 Apr 2011 12:28:36 GMT
|
29
|
+
content-length:
|
30
|
+
- "0"
|
31
|
+
set-cookie:
|
32
|
+
- "[SESSION-COOKIE]"
|
33
|
+
body:
|
34
|
+
http_version: "1.1"
|
35
|
+
- !ruby/struct:VCR::HTTPInteraction
|
36
|
+
request: !ruby/struct:VCR::Request
|
37
|
+
method: :get
|
38
|
+
uri: https://[API-TOKEN]:x@[ACCOUNT-NAME].capsulecrm.com:443/api/party/10256313
|
39
|
+
body:
|
40
|
+
headers:
|
41
|
+
user-agent:
|
42
|
+
- CapsuleCRM ruby gem
|
43
|
+
response: !ruby/struct:VCR::Response
|
44
|
+
status: !ruby/struct:VCR::ResponseStatus
|
45
|
+
code: 200
|
46
|
+
message: OK
|
47
|
+
headers:
|
48
|
+
content-type:
|
49
|
+
- "*/*"
|
50
|
+
server:
|
51
|
+
- Apache
|
52
|
+
date:
|
53
|
+
- Tue, 12 Apr 2011 12:28:38 GMT
|
54
|
+
content-length:
|
55
|
+
- "268"
|
56
|
+
set-cookie:
|
57
|
+
- "[SESSION-COOKIE]"
|
58
|
+
body: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><person><id>10256313</id><contacts/><pictureURL>https://d365sd3k9yw37.cloudfront.net/a/543325/theme/default/images/person_avatar_70.png</pictureURL><firstName>Homer</firstName><lastName>Simpson</lastName></person>
|
59
|
+
http_version: "1.1"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :get
|
5
|
+
uri: https://[API-TOKEN]:x@[ACCOUNT-NAME].capsulecrm.com:443/api/party?
|
6
|
+
body:
|
7
|
+
headers:
|
8
|
+
user-agent:
|
9
|
+
- CapsuleCRM ruby gem
|
10
|
+
response: !ruby/struct:VCR::Response
|
11
|
+
status: !ruby/struct:VCR::ResponseStatus
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
content-type:
|
16
|
+
- "*/*"
|
17
|
+
server:
|
18
|
+
- Apache
|
19
|
+
date:
|
20
|
+
- Tue, 12 Apr 2011 12:31:18 GMT
|
21
|
+
content-length:
|
22
|
+
- "3305"
|
23
|
+
set-cookie:
|
24
|
+
- "[SESSION-COOKIE]"
|
25
|
+
body: |-
|
26
|
+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><parties size="8"><person><id>9719416</id><contacts><email><id>17716757</id><emailAddress>at@example.com</emailAddress></email></contacts><pictureURL>https://d365sd3k9yw37.cloudfront.net/a/543325/theme/default/images/person_avatar_70.png</pictureURL><title>Prof</title><firstName>Alan</firstName><lastName>Turing</lastName></person><person><id>10185304</id><contacts><email><id>18565226</id><emailAddress>cd@example.com</emailAddress></email></contacts><pictureURL>https://d365sd3k9yw37.cloudfront.net/a/543325/theme/default/images/person_avatar_70.png</pictureURL><title>Dr</title><firstName>Charles</firstName><lastName>Darwin</lastName></person><person><id>10185257</id><contacts><address><id>18565068</id><type>Office</type><street>10 Downing Street</street><city>London</city><zip>SW1A 2AA</zip><country>United Kingdom</country></address><email><id>18565066</id><type>Work</type><emailAddress>pm@example.com</emailAddress></email><phone><id>18566503</id><phoneNumber>12345 67890</phoneNumber></phone><website><id>18565067</id><webAddress>http://www.number10.gov.uk/</webAddress><webService>URL</webService><url>http://www.number10.gov.uk/</url></website></contacts><pictureURL>https://d365sd3k9yw37.cloudfront.net/a/543325/theme/default/images/person_avatar_70.png</pictureURL><title>Mr</title><firstName>David</firstName><lastName>Cameron</lastName><jobTitle>Prime Minister</jobTitle><organisationId>10185256</organisationId><organisationName>UK Government</organisationName></person><organisation><id>10185222</id><contacts/><pictureURL>https://d365sd3k9yw37.cloudfront.net/a/543325/theme/default/images/org_avatar_70.png</pictureURL><name>foo.com</name></organisation><person><id>10185308</id><contacts><email><id>18565231</id><emailAddress>mc@example.com</emailAddress></email></contacts><pictureURL>https://d365sd3k9yw37.cloudfront.net/a/543325/theme/default/images/person_avatar_70.png</pictureURL><title>Ms</title><firstName>Marie</firstName><lastName>Curie</lastName></person><person><id>10185261</id><contacts><address><id>18565115</id><type>Office</type><street>Deputy Prime Minister's Office
|
27
|
+
70 Whitehall</street><city>London</city><zip>SW1A 2AS</zip><country>United Kingdom</country></address><email><id>18565116</id><type>Work</type><emailAddress>dpm@example.com</emailAddress></email></contacts><pictureURL>https://d365sd3k9yw37.cloudfront.net/a/543325/theme/default/images/person_avatar_70.png</pictureURL><title>Mr</title><firstName>Nick</firstName><lastName>Clegg</lastName><jobTitle>Deputy Prime Minister</jobTitle><organisationId>10185256</organisationId><organisationName>UK Government</organisationName></person><person><id>9851220</id><contacts><email><id>18565224</id><emailAddress>tbl@example.com</emailAddress></email></contacts><pictureURL>https://d365sd3k9yw37.cloudfront.net/a/543325/theme/default/images/person_avatar_70.png</pictureURL><title>Prof</title><firstName>Tim</firstName><lastName>Berners-Lee</lastName></person><organisation><id>10185256</id><contacts><email><id>18583945</id><emailAddress>gov@example.com</emailAddress></email></contacts><pictureURL>https://d365sd3k9yw37.cloudfront.net/a/543325/theme/default/images/org_avatar_70.png</pictureURL><name>UK Government</name></organisation></parties>
|
28
|
+
http_version: "1.1"
|