capsule_crm 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Coverage
|
8
8
|
Status](https://coveralls.io/repos/mattbeedle/capsule_crm/badge.png?branch=master)](https://coveralls.io/r/mattbeedle/capsule_crm)
|
9
9
|
|
10
|
+
[![Dependency
|
11
|
+
Status](https://gemnasium.com/mattbeedle/capsule_crm.png)](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
|