capsule_crm 0.0.4 → 0.0.5
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/README.md +3 -0
- data/capsule_crm.gemspec +1 -0
- data/lib/capsule_crm/associations/belongs_to.rb +64 -0
- data/lib/capsule_crm/associations/has_many.rb +58 -0
- data/lib/capsule_crm/associations/has_many_proxy.rb +47 -0
- data/lib/capsule_crm/associations.rb +3 -0
- data/lib/capsule_crm/opportunity.rb +41 -7
- data/lib/capsule_crm/organization.rb +9 -4
- data/lib/capsule_crm/party.rb +23 -0
- data/lib/capsule_crm/person.rb +238 -267
- data/lib/capsule_crm/version.rb +1 -1
- data/lib/capsule_crm.rb +2 -0
- data/spec/fabricators/opportunity_fabricator.rb +5 -0
- data/spec/fabricators/organization_fabricator.rb +3 -0
- data/spec/lib/capsule_crm/associations/has_many_proxy_spec.rb +71 -0
- data/spec/lib/capsule_crm/associations/has_many_spec.rb +4 -0
- data/spec/lib/capsule_crm/opportunity_spec.rb +113 -9
- data/spec/lib/capsule_crm/organization_spec.rb +24 -0
- data/spec/spec_helper.rb +5 -3
- data/spec/support/all_people.json +16 -0
- data/spec/support/deleted_opportunities.json +14 -0
- data/spec/support/organisation.json +8 -0
- metadata +35 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dca3fb5d1950b9561a1a92f28a69ed82746437c5
|
4
|
+
data.tar.gz: c44375ed1df1bf56b6fbaed31fc645220f1979f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4b8d844174f6ddfea4aa46899d22c90b9dbbcce3bb7330c5cbbd047a1fe99d05852ab659708a6282a063ce93f0a794e6eb001f6a912203e3e9684a325bc1eeb
|
7
|
+
data.tar.gz: 3ca0e9816938ad828bce082240894213e1ab19c5421afeeca6af5f1d7a9cd954ef54675801bf542823efbf2c38f340bd637a654171757c4ff3e0a069a134a2d1
|
data/README.md
CHANGED
@@ -7,6 +7,9 @@ Version](https://badge.fury.io/rb/capsule_crm.png)](http://badge.fury.io/rb/caps
|
|
7
7
|
[](https://coveralls.io/r/mattbeedle/capsule_crm)
|
9
9
|
|
10
|
+
[](https://gemnasium.com/mattbeedle/capsule_crm)
|
12
|
+
|
10
13
|
# CapsuleCRM
|
11
14
|
|
12
15
|
CapsuleCRM provides an ActiveModel compliant interface to the capsulecrm API
|
data/capsule_crm.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |gem|
|
|
25
25
|
|
26
26
|
gem.add_development_dependency('coveralls')
|
27
27
|
gem.add_development_dependency('cucumber')
|
28
|
+
gem.add_development_dependency('fabrication')
|
28
29
|
gem.add_development_dependency('guard')
|
29
30
|
gem.add_development_dependency('guard-rspec')
|
30
31
|
gem.add_development_dependency('rb-fsevent')
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module CapsuleCRM
|
2
|
+
module Associations
|
3
|
+
module BelongsTo
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
# Public: Add getter and setter methods for belongs to associations
|
9
|
+
#
|
10
|
+
# association_name - The String name of the association
|
11
|
+
# options - The Hash of additional options (default: {}):
|
12
|
+
# class_name: The String name of the associated
|
13
|
+
# class
|
14
|
+
#
|
15
|
+
# Examples
|
16
|
+
#
|
17
|
+
# class CapsuleCRM::Person
|
18
|
+
# include CapsuleCRM::Associations::BelongsTo
|
19
|
+
#
|
20
|
+
# belongs_to :organisation, class_name: 'CapsuleCRM::Organization'
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# organisation = CapsuleCRM::Organisation.find(1)
|
24
|
+
#
|
25
|
+
# person = CapsuleCRM::Person.new(organisation = organisation)
|
26
|
+
# person.organisation_id
|
27
|
+
# => 1
|
28
|
+
#
|
29
|
+
# person.organisation
|
30
|
+
# => organisation
|
31
|
+
def belongs_to(association_name, options = {})
|
32
|
+
class_eval do
|
33
|
+
attribute options[:foreign_key] ||
|
34
|
+
:"#{association_name}_id", Integer
|
35
|
+
end
|
36
|
+
|
37
|
+
(class << self; self; end).instance_eval do
|
38
|
+
define_method "_for_#{association_name}" do |id|
|
39
|
+
raise NotImplementedError
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
define_method association_name do
|
44
|
+
instance_variable_get(:"@#{association_name}") ||
|
45
|
+
if self.send("#{association_name}_id")
|
46
|
+
options[:class_name].constantize.
|
47
|
+
find(self.send("#{association_name}_id")).tap do |object|
|
48
|
+
self.send("#{association_name}=", object)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
define_method "#{association_name}=" do |associated_object|
|
56
|
+
instance_variable_set(:"@#{association_name}", associated_object)
|
57
|
+
id = associated_object ? associated_object.id : nil
|
58
|
+
self.send "#{association_name}_id=", id
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'capsule_crm/associations/has_many_proxy'
|
2
|
+
|
3
|
+
module CapsuleCRM
|
4
|
+
module Associations
|
5
|
+
module HasMany
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
# Public: Add the setter and getter methods for a has_many association.
|
11
|
+
#
|
12
|
+
# association_name - The String name of the associated collection
|
13
|
+
# options: - The Hash of options (default: {}):
|
14
|
+
# class_name: The String name of the class used in the
|
15
|
+
# association
|
16
|
+
#
|
17
|
+
# Examples
|
18
|
+
#
|
19
|
+
# class CapsuleCRM::Organizatio
|
20
|
+
# include CapsuleCRM::Associations::HasMany
|
21
|
+
#
|
22
|
+
# has_many :people, class_name: 'CapsuleCRM::Person'
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# organization = CapsuleCRM::Organization.find(1)
|
26
|
+
# organization.people
|
27
|
+
# => [CapsuleCRM::Person, CapsuleCRM::Person, ...]
|
28
|
+
#
|
29
|
+
# person = CapsuleCRM::Organization.find(5)
|
30
|
+
# organization.people= [person]
|
31
|
+
# organization.people
|
32
|
+
# => [person]
|
33
|
+
def has_many(association_name, options = {})
|
34
|
+
define_method association_name do
|
35
|
+
instance_variable_get(:"@#{association_name}") ||
|
36
|
+
CapsuleCRM::Associations::HasManyProxy.new(
|
37
|
+
self, # parent
|
38
|
+
options[:class_name].constantize, # target class
|
39
|
+
options[:class_name].constantize.
|
40
|
+
send("_for_#{self.class.to_s.demodulize.downcase}", self.id),
|
41
|
+
options[:source] # source
|
42
|
+
).tap do |proxy|
|
43
|
+
instance_variable_set :"@#{association_name}", proxy
|
44
|
+
end
|
45
|
+
instance_variable_get :"@#{association_name}"
|
46
|
+
end
|
47
|
+
|
48
|
+
define_method "#{association_name}=" do |associated_objects|
|
49
|
+
instance_variable_set :"@#{association_name}",
|
50
|
+
CapsuleCRM::Associations::HasManyProxy.new(
|
51
|
+
parent, associated_objects
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module CapsuleCRM
|
2
|
+
module Associations
|
3
|
+
class HasManyProxy < BasicObject
|
4
|
+
|
5
|
+
def initialize(parent, target_klass, target, source)
|
6
|
+
@target = target
|
7
|
+
@parent = parent
|
8
|
+
@target_klass = target_klass
|
9
|
+
@source = source
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing(name, *args, &block)
|
13
|
+
@target.send(name, *args, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def build(attributes = {})
|
17
|
+
target_klass.new(attributes).tap do |item|
|
18
|
+
item.send("#{source}=", parent)
|
19
|
+
@target << item
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def create(attributes = {})
|
24
|
+
build(attributes).save
|
25
|
+
end
|
26
|
+
|
27
|
+
def tap
|
28
|
+
yield self
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def parent
|
35
|
+
@parent
|
36
|
+
end
|
37
|
+
|
38
|
+
def target_klass
|
39
|
+
@target_klass
|
40
|
+
end
|
41
|
+
|
42
|
+
def source
|
43
|
+
@source
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -6,14 +6,15 @@ module CapsuleCRM
|
|
6
6
|
include ActiveModel::Conversion
|
7
7
|
include ActiveModel::Validations
|
8
8
|
|
9
|
+
include CapsuleCRM::Associations::BelongsTo
|
10
|
+
|
9
11
|
attribute :id, Integer
|
10
|
-
attribute :name
|
11
|
-
attribute :description
|
12
|
+
attribute :name, String
|
13
|
+
attribute :description, String
|
12
14
|
attribute :currency
|
13
15
|
attribute :value, Float
|
14
16
|
attribute :duration_basis
|
15
17
|
attribute :duration, Integer
|
16
|
-
attribute :party_id, Integer
|
17
18
|
attribute :milestone_id, Integer
|
18
19
|
attribute :expected_close_date, DateTime
|
19
20
|
attribute :actual_close_date, DateTime
|
@@ -22,9 +23,12 @@ module CapsuleCRM
|
|
22
23
|
attr_accessor :milestone, :owner
|
23
24
|
|
24
25
|
validates :name, presence: true
|
26
|
+
validates :party_id, presence: true
|
25
27
|
validates :milestone_id, presence: { unless: :milestone }
|
26
28
|
validates :milestone, presence: { unless: :milestone_id }
|
27
29
|
|
30
|
+
belongs_to :party, class_name: 'CapsuleCRM::Party'
|
31
|
+
|
28
32
|
# Public: Set the attributes of a opportunity
|
29
33
|
#
|
30
34
|
# attributes - The Hash of attributes (default: {}):
|
@@ -74,11 +78,29 @@ module CapsuleCRM
|
|
74
78
|
#
|
75
79
|
# CapsuleCRM::Opportunity.all(start: 10, limit: 20)
|
76
80
|
#
|
77
|
-
# Returns a ResultsProxy of
|
81
|
+
# Returns a ResultsProxy of opportunities
|
78
82
|
def self.all(options = {})
|
79
83
|
init_collection(
|
80
|
-
CapsuleCRM::Connection.
|
81
|
-
|
84
|
+
CapsuleCRM::Connection.get(
|
85
|
+
'/api/opportunity', options
|
86
|
+
)['opportunities']['opportunity']
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Public: Get all deleted opportunities since the specified date
|
91
|
+
#
|
92
|
+
# since - The Date to start checking for deleted opportunities
|
93
|
+
#
|
94
|
+
# Examples
|
95
|
+
#
|
96
|
+
# CapsuleCRM::Opportunity.deleted(1.week.ago)
|
97
|
+
#
|
98
|
+
# Returns a ResultsProxy of opportunities
|
99
|
+
def self.deleted(since)
|
100
|
+
init_collection(
|
101
|
+
CapsuleCRM::Connection.get(
|
102
|
+
'/api/opportunity/deleted', since: since
|
103
|
+
)['deletedOpportunities']['deletedOpportunity']
|
82
104
|
)
|
83
105
|
end
|
84
106
|
|
@@ -289,11 +311,23 @@ module CapsuleCRM
|
|
289
311
|
}.stringify_keys
|
290
312
|
end
|
291
313
|
|
314
|
+
# Public: Delete the opportunity in capsule
|
315
|
+
#
|
316
|
+
# Examples
|
317
|
+
#
|
318
|
+
# opportunity.destroy
|
319
|
+
#
|
320
|
+
# Return the CapsuleCRM::Opportunity
|
321
|
+
def destroy
|
322
|
+
self.id = nil if CapsuleCRM::Connection.delete("/api/opportunity/#{id}")
|
323
|
+
self
|
324
|
+
end
|
325
|
+
|
292
326
|
private
|
293
327
|
|
294
328
|
def create_record
|
295
329
|
self.attributes = CapsuleCRM::Connection.post(
|
296
|
-
|
330
|
+
"/api/party/#{party_id}/opportunity", to_capsule_json
|
297
331
|
)
|
298
332
|
self
|
299
333
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'active_support/core_ext'
|
2
2
|
|
3
3
|
module CapsuleCRM
|
4
|
-
class Organization
|
5
|
-
include
|
4
|
+
class Organization < CapsuleCRM::Party
|
5
|
+
include Virtus
|
6
6
|
|
7
7
|
extend ActiveModel::Naming
|
8
8
|
extend ActiveModel::Callbacks
|
@@ -10,11 +10,16 @@ module CapsuleCRM
|
|
10
10
|
include ActiveModel::Validations
|
11
11
|
include ActiveModel::Validations::Callbacks
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
include CapsuleCRM::Associations::HasMany
|
14
|
+
|
15
|
+
attribute :id, Integer
|
16
|
+
attribute :name, String
|
17
|
+
attribute :about, String
|
15
18
|
|
16
19
|
validates :name, presence: true
|
17
20
|
|
21
|
+
has_many :people, class_name: 'CapsuleCRM::Person', source: :organization
|
22
|
+
|
18
23
|
# Public: Set the attributes of an organization
|
19
24
|
#
|
20
25
|
# attributes - The Hash of attributes (default: {}):
|
data/lib/capsule_crm/party.rb
CHANGED
@@ -1,2 +1,25 @@
|
|
1
1
|
class CapsuleCRM::Party
|
2
|
+
|
3
|
+
def self.all(options = {})
|
4
|
+
attributes = CapsuleCRM::Connection.get('/api/party', options)
|
5
|
+
init_collection(
|
6
|
+
attributes['parties'].fetch('person', 'organisation')
|
7
|
+
)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.find(id)
|
11
|
+
attributes = CapsuleCRM::Connection.get("/api/party/#{id}")
|
12
|
+
party_classes[attributes.keys.first].constantize.new(
|
13
|
+
attributes[attributes.keys.first]
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def self.party_classes
|
20
|
+
{
|
21
|
+
person: 'CapsuleCRM::Person',
|
22
|
+
organisation: 'CapsuleCRM::Organization'
|
23
|
+
}.stringify_keys
|
24
|
+
end
|
2
25
|
end
|