connectwise_sdk 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -9
- data/lib/connectwise/company.rb +21 -0
- data/lib/connectwise/connection.rb +1 -5
- data/lib/connectwise/contact.rb +15 -40
- data/lib/connectwise/errors.rb +7 -0
- data/lib/connectwise/member.rb +3 -9
- data/lib/connectwise/model.rb +68 -3
- data/lib/connectwise/opportunity.rb +33 -0
- data/lib/connectwise/ticket.rb +46 -0
- data/lib/connectwise/version.rb +1 -1
- data/lib/connectwise_sdk.rb +2 -4
- data/spec/integration/opportunity_spec.rb +17 -0
- data/spec/lib/connectwise/company_spec.rb +27 -18
- data/spec/lib/connectwise/contact_spec.rb +47 -32
- data/spec/lib/connectwise/opportunity_spec.rb +40 -8
- data/spec/lib/connectwise/ticket_spec.rb +44 -6
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 546290353531e430d7605b8aa51830e260bdf854
|
4
|
+
data.tar.gz: f096307dc3cdba0adbba01d627b0cfdaa3d13a18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f9f715f5715707d14842c54a0b5f05f5b5f7fdc070710903b463411b51b4c437001506cd3596e19dd4d61316575c6f8b08abe80d3b1bf16c5f27c4f9c33a915
|
7
|
+
data.tar.gz: 8b4943f39a85fc48a69700aedbc7839a76a4ee6227e3336470f33ec1becfe22eb68d223b3d57eccd8a9c48ae2953f1f05991d4b134b8186bc31a22aefcdd7cd1
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# ConnectwiseSdk
|
2
2
|
|
3
|
-
An SDK
|
3
|
+
An SDK simplifying integration with the Connectwise API.
|
4
|
+
|
5
|
+
The Connectwise (CW) XML Api can be a challenge to work with. This Sdk aims to simplify this interaction with objects mirroring the CW objects, and applying the standard Ruby conventions to that naming. While much of the heavy lifting is done by using Savon, there are a number of inconsistecies which this Sdk aims to smooth over.
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -56,13 +58,18 @@ Note how `contact` is lower case, while `FirstName` and the other fields are cam
|
|
56
58
|
|
57
59
|
## Current progress and TODOs
|
58
60
|
|
59
|
-
Currently
|
61
|
+
Currently the low level `Connection.call` method is working, as well as basic Member, Contact, Company, and Opportunity creation, and search.
|
62
|
+
|
63
|
+
Remaining items include:
|
60
64
|
|
61
|
-
1.
|
62
|
-
2.
|
63
|
-
|
64
|
-
|
65
|
-
|
65
|
+
1. Ticket class
|
66
|
+
2. Support Notes for Opportunities (submitting them)
|
67
|
+
2. Creating a Facade layer so that the connection object doesn't need to be passed to each object
|
68
|
+
3. Supporting a late binding way of accessing internal objects (accessing the company object within an opportunity for example)
|
69
|
+
4. Supporting an intuitive way of accessing lists of phone numbers, addresses, and email addresses, while still allowing simple access to the first one of each.
|
70
|
+
5. Better support for the difference between a find (summary info only) and a get (full object). This should be hidden by the api
|
71
|
+
6. A reload facitily to requery for the data.
|
72
|
+
7. Remaining api
|
66
73
|
|
67
74
|
## Contributing
|
68
75
|
|
@@ -75,7 +82,7 @@ Currently only the `Member.where` method, and the low level `Connection.call` me
|
|
75
82
|
### Adding support for other Connectwise Classes
|
76
83
|
|
77
84
|
There is a `Connectwise::Model` module that incorporates the core of what it is to be
|
78
|
-
connectwise model. Every Model should include this class.
|
85
|
+
connectwise model. Every Model should include this class. See below for a description of it's capabilities.
|
79
86
|
|
80
87
|
Then it's a matter of figuring out the following for each class:
|
81
88
|
- What fields are returned from a find call
|
@@ -85,4 +92,23 @@ Then it's a matter of figuring out the following for each class:
|
|
85
92
|
|
86
93
|
Some issues that need to be resolved:
|
87
94
|
- How best to handle nested data structures (A contact has an email address list, a phone number list, etc.)
|
88
|
-
- How best to handle nested objects
|
95
|
+
- How best to handle nested objects. These are handled for object creation, but accessing them should lazily load the object, making the query against CW only when necessary.
|
96
|
+
- How best to handle the difference between find and get calls. With CW, a find returns a stub object returned by a get call. For example, a find on a contact may return an email address, but the get call will return an array of connection objects, each with a different email address in it. Currently these lists are ignored, but we'll need to deal with them eventually. The initial implementation can make the first email address in the list be returned from an email call, while emails will return the full list.
|
97
|
+
|
98
|
+
### Connectwise::Model
|
99
|
+
|
100
|
+
The connectwise model centralizes the common actions that are supported by each model object, and creates a small DSL for creating. These actions include support for `.where`, `.find`, `.save`, `.destroy`, and `.persisted?`. In general the key to supporting these follows a common pattern:
|
101
|
+
|
102
|
+
1. Place the api call using the correct model name ('XXXApi' for example, 'ContactApi' for a Contact object).
|
103
|
+
2. Place the api call using the correct method name ('add_or_update_XXX' for example, 'add_or_update_contact' for a Contact object).
|
104
|
+
3. Place the parameters inside the correct parent object (e.g. contact: {FirstName: 'first', LastName: 'Last'}}
|
105
|
+
4. The where clause does a search converting thobject, and one that is generally inconsistent with the e hash parameters into a query string, and then removing the root element from the return hash.
|
106
|
+
5. The find clause does a get using an id.
|
107
|
+
6. The save calls use the 'add_or_update_XXX' actions, while the destroy calls use the 'delete_XXX' calls.
|
108
|
+
7. Persistence is determined by the presence of an id.
|
109
|
+
|
110
|
+
The main challenge is getting this to work is allowing enough hooks to customize the model name, plural form of the model name, and the specific api method names in the rare cases that require it.
|
111
|
+
|
112
|
+
The final piece is translating the data returned by CW to the data in this API. For the most part the conversion is straight forward, but part of the purpose of the high level api is to remove the inconsistencies as much as possible.
|
113
|
+
|
114
|
+
So while getting a member's email is done with `.email_address`, a contact's email is retrieved with `.email`. This should be consistent, or better yet, both should work in either case.
|
data/lib/connectwise/company.rb
CHANGED
@@ -1,5 +1,26 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module Connectwise
|
2
4
|
class Company
|
3
5
|
include Model
|
6
|
+
plural :companies
|
7
|
+
attr_accessor :id, :status, :type, :market, :territory, :web_site, :fax_number, :phone_number, :company_name, :company_id
|
8
|
+
|
9
|
+
def self.transform(attrs)
|
10
|
+
attrs[:company_name] ||= attrs.delete(:name)
|
11
|
+
attrs
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(connection, attrs)
|
15
|
+
super
|
16
|
+
@company_id ||= SecureRandom.hex(12)
|
17
|
+
@status ||= 'Active'
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_cw_h
|
21
|
+
attrs = super
|
22
|
+
attrs['CompanyID'] = attrs.delete('CompanyId')
|
23
|
+
attrs
|
24
|
+
end
|
4
25
|
end
|
5
26
|
end
|
@@ -1,9 +1,4 @@
|
|
1
1
|
module Connectwise
|
2
|
-
class ConnectionError < StandardError; end
|
3
|
-
class UnknownHostError < ConnectionError; end
|
4
|
-
class UnknownCompanyError < ConnectionError; end
|
5
|
-
class BadCredentialsError < ConnectionError; end
|
6
|
-
|
7
2
|
class Connection
|
8
3
|
attr_reader :host, :custom_api_mapping
|
9
4
|
attr_accessor :log
|
@@ -12,6 +7,7 @@ module Connectwise
|
|
12
7
|
@custom_api_mapping = custom_api_mapping
|
13
8
|
@host = host
|
14
9
|
@credentials = {CompanyId: company_name, IntegratorLoginId: integrator_login_id, IntegratorPassword: integrator_password}
|
10
|
+
HTTPI.adapter = :net_http
|
15
11
|
end
|
16
12
|
|
17
13
|
def call(api, action, message, options: {}, &err_handler)
|
data/lib/connectwise/contact.rb
CHANGED
@@ -3,54 +3,29 @@ module Connectwise
|
|
3
3
|
include Model
|
4
4
|
#TODO - email or email_address - Member uses email_address, while here it's email - normalize
|
5
5
|
attr_accessor :id, :first_name, :last_name, :company_name, :phone, :email, :type, :relationship, :default_flag, :address_line1, :address_line2, :city, :state, :zip, :country,
|
6
|
-
:portal_security_level, :portal_security_caption, :disable_portal_login, :last_update
|
6
|
+
:portal_security_level, :portal_security_caption, :disable_portal_login, :last_update, :company_id
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def save
|
14
|
-
#message = message.merge(CompanyId: company_id) if company_id
|
15
|
-
attrs = connection.call 'ContactApi', :add_or_update_contact, {contact: to_cw_h}
|
16
|
-
p attrs
|
17
|
-
self.class.cw_save_to_model(connection, attrs)
|
18
|
-
end
|
19
|
-
|
20
|
-
def destroy
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def persisted?
|
25
|
-
!!@id
|
8
|
+
#TODO - add company accessor and make use of company rec id - either run another query to create it, or find a way to defer until company is asked for
|
9
|
+
def company=(company)
|
10
|
+
@company = company
|
26
11
|
end
|
27
12
|
|
28
13
|
private
|
29
|
-
def self.
|
30
|
-
id
|
31
|
-
|
32
|
-
company_id = attrs.delete(:company_rec_id)
|
33
|
-
self.new(conn, id: id, **attrs)
|
14
|
+
def self.find_transform(attrs)
|
15
|
+
attrs[:id] ||= attrs.delete(:contact_rec_id)
|
16
|
+
attrs
|
34
17
|
end
|
35
18
|
|
36
|
-
def self.
|
37
|
-
|
19
|
+
def self.save_transform(attrs)
|
20
|
+
attrs[:id] ||= attrs.delete(:contact_rec_id)
|
21
|
+
attrs
|
38
22
|
end
|
39
23
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
Phone: contact.phone,
|
46
|
-
}
|
47
|
-
message = message.merge(CompanyId: company_id) if company_id
|
48
|
-
connection.call 'ContactApi', :add_or_update_contact, {contact: message}, &err_handler
|
24
|
+
def to_cw_h
|
25
|
+
h = super
|
26
|
+
h.delete(:company_id)
|
27
|
+
h = h.merge(CompanyId: @company.company_id) if @company
|
28
|
+
h
|
49
29
|
end
|
50
|
-
|
51
|
-
def delete_contact(contact, &err_handler)
|
52
|
-
connection.call 'ContactApi', :delete_contact, {id: contact.id}, &err_handler
|
53
|
-
end
|
54
|
-
|
55
30
|
end
|
56
31
|
end
|
data/lib/connectwise/member.rb
CHANGED
@@ -3,15 +3,9 @@ module Connectwise
|
|
3
3
|
include Model
|
4
4
|
attr_accessor :email_address, :first_name, :last_name, :id
|
5
5
|
|
6
|
-
def self.
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
def self.cw_to_model(conn, attrs)
|
13
|
-
id = attrs.delete(:member_id)
|
14
|
-
self.new(conn, id: id, **attrs)
|
6
|
+
def self.find_transform(attrs)
|
7
|
+
attrs[:id] = attrs.delete(:member_id)
|
8
|
+
attrs
|
15
9
|
end
|
16
10
|
end
|
17
11
|
end
|
data/lib/connectwise/model.rb
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
module Connectwise
|
2
2
|
module Model
|
3
3
|
module ClassMethods
|
4
|
+
def where(connection, *args, **attrs)
|
5
|
+
conditions = attrs ? attrs_to_query(transform(attrs)) : args.join(' ')
|
6
|
+
resp = connection.call cw_api_name, "find_#{plural_class_name}".to_sym, {conditions: conditions}
|
7
|
+
resp ? Array(remove_root_node(resp)).map {|attrs| self.new(connection, find_transform(attrs)) } : []
|
8
|
+
end
|
9
|
+
|
10
|
+
def find(connection, id)
|
11
|
+
if (attrs = connection.call(cw_api_name, "get_#{cw_api_name}".to_sym, {id: id}))
|
12
|
+
self.new(connection, find_transform(attrs))
|
13
|
+
else
|
14
|
+
fail RecordNotFound
|
15
|
+
end
|
16
|
+
rescue ConnectionError
|
17
|
+
raise RecordNotFound
|
18
|
+
end
|
19
|
+
|
20
|
+
def plural(plural)
|
21
|
+
@plural_form = plural
|
22
|
+
end
|
23
|
+
|
4
24
|
def attrs_to_query(attrs)
|
5
25
|
attrs.map do |k,v|
|
6
26
|
str = k.to_s
|
@@ -8,6 +28,40 @@ module Connectwise
|
|
8
28
|
"#{str.camelize} like '#{v}'"
|
9
29
|
end.join(' and ')
|
10
30
|
end
|
31
|
+
|
32
|
+
def cw_api_name
|
33
|
+
base_class_name.downcase.to_sym
|
34
|
+
end
|
35
|
+
|
36
|
+
def plural_class_name
|
37
|
+
ending = base_class_name[/[aeiou]$/] ? 'es' : 's'
|
38
|
+
@plural_form ||= "#{base_class_name.downcase}#{ending}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_transform(attrs)
|
42
|
+
attrs
|
43
|
+
end
|
44
|
+
|
45
|
+
def save_transform(attrs)
|
46
|
+
attrs
|
47
|
+
end
|
48
|
+
|
49
|
+
def transform(attrs)
|
50
|
+
attrs
|
51
|
+
end
|
52
|
+
|
53
|
+
def model_name(model_name = self.name)
|
54
|
+
@model_name ||= model_name
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def base_class_name
|
59
|
+
model_name.split('::').last
|
60
|
+
end
|
61
|
+
|
62
|
+
def remove_root_node(resp)
|
63
|
+
resp.values.first
|
64
|
+
end
|
11
65
|
end
|
12
66
|
|
13
67
|
def self.included(klass)
|
@@ -16,13 +70,23 @@ module Connectwise
|
|
16
70
|
|
17
71
|
def initialize(connection, **attributes)
|
18
72
|
@connection = connection
|
19
|
-
attributes.each do |attr, value|
|
20
|
-
public_send
|
73
|
+
self.class.transform(attributes).each do |attr, value|
|
74
|
+
public_send("#{attr}=", value) if respond_to?("#{attr}=")
|
21
75
|
end
|
22
76
|
end
|
23
77
|
|
78
|
+
def save
|
79
|
+
attrs = connection.call self.class.cw_api_name, "add_or_update_#{self.class.cw_api_name}".to_sym, {self.class.cw_api_name => to_cw_h}
|
80
|
+
self.class.new(connection, self.class.save_transform(attrs))
|
81
|
+
end
|
82
|
+
|
83
|
+
def destroy
|
84
|
+
connection.call self.class.cw_api_name, "delete_#{self.class.cw_api_name}".to_sym, {id: id}
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
24
88
|
def persisted?
|
25
|
-
|
89
|
+
!!id
|
26
90
|
end
|
27
91
|
|
28
92
|
def to_h
|
@@ -37,6 +101,7 @@ module Connectwise
|
|
37
101
|
instance_vars = instance_variables.map {|name| name.to_s.gsub(/@/, '').to_sym}
|
38
102
|
public_methods.select{|method| instance_vars.include?(method) }
|
39
103
|
end
|
104
|
+
|
40
105
|
protected
|
41
106
|
def connection
|
42
107
|
@connection
|
@@ -1,5 +1,38 @@
|
|
1
1
|
module Connectwise
|
2
2
|
class Opportunity
|
3
3
|
include Model
|
4
|
+
plural :opportunities
|
5
|
+
|
6
|
+
attr_accessor :id, :opportunity_name, :source, :rating, :stage_name, :type, :status, :closed, :won, :lost, :close_probablity, :expected_close_date, :primary_sales_rep, :secondary_sales_rep,
|
7
|
+
:marketing_campaign_name, :location, :business_unit, :age, :estimated_total, :recurring_total, :won_amount, :lost_amount, :open_amount, :margin, :product_amount, :service_amount
|
8
|
+
|
9
|
+
def company=(company)
|
10
|
+
@company = company
|
11
|
+
end
|
12
|
+
|
13
|
+
def contact=(contact)
|
14
|
+
@contact = contact
|
15
|
+
end
|
16
|
+
|
17
|
+
def company_id
|
18
|
+
@company
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def to_cw_h
|
24
|
+
attrs = super
|
25
|
+
attrs.delete('CompanyId')
|
26
|
+
attrs.delete('ContactId')
|
27
|
+
attrs['Company'] = {'CompanyID' => @company.company_id} if @company
|
28
|
+
attrs['Contact'] = {'Id' => @contact.id} if @contact
|
29
|
+
attrs
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.transform(attrs)
|
33
|
+
name = attrs.delete(:name) || attrs.delete(:opportunity_name)
|
34
|
+
attrs[:opportunity_name] = name if name
|
35
|
+
attrs
|
36
|
+
end
|
4
37
|
end
|
5
38
|
end
|
data/lib/connectwise/ticket.rb
CHANGED
@@ -1,5 +1,51 @@
|
|
1
1
|
module Connectwise
|
2
2
|
class Ticket
|
3
3
|
include Model
|
4
|
+
model_name 'service_ticket'
|
5
|
+
attr_accessor :id, :summary, :problem_description, :status_name, :board, :site_name, :status, :resolution, :remote_internal_company_name, :priority, :source, :severity, :impact,
|
6
|
+
|
7
|
+
#TODO - The use of SrServiceRecid and TicketNumber instead of id - may want to configure these
|
8
|
+
# but this is so inconsistent for tickets that it may not be worth it unless other calls do the same thing
|
9
|
+
def self.find(connection, id)
|
10
|
+
if (attrs = connection.call(cw_api_name, "get_#{cw_api_name}".to_sym, {SrServiceRecid: id}))
|
11
|
+
self.new(connection, find_transform(attrs))
|
12
|
+
else
|
13
|
+
fail RecordNotFound
|
14
|
+
end
|
15
|
+
rescue ConnectionError
|
16
|
+
raise RecordNotFound
|
17
|
+
end
|
18
|
+
|
19
|
+
def status_name
|
20
|
+
@status_name ||= 'New'
|
21
|
+
end
|
22
|
+
|
23
|
+
def company=(company)
|
24
|
+
@company = company
|
25
|
+
end
|
26
|
+
|
27
|
+
def save
|
28
|
+
return false unless @company
|
29
|
+
attrs = {companyId: @company.company_id, 'serviceTicket' => to_cw_h}
|
30
|
+
attrs = connection.call self.class.cw_api_name, "add_or_update_#{self.class.cw_api_name}_via_company_id".to_sym, attrs
|
31
|
+
self.class.new(connection, self.class.save_transform(attrs))
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
connection.call self.class.cw_api_name, "delete_#{self.class.cw_api_name}".to_sym, {SrServiceRecid: id}
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def self.save_transform(attrs)
|
41
|
+
attrs[:id] = attrs.delete(:ticket_number)
|
42
|
+
attrs
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_cw_h
|
46
|
+
attrs = super
|
47
|
+
attrs['TicketNumber'] = attrs[:id] || 0
|
48
|
+
attrs
|
49
|
+
end
|
4
50
|
end
|
5
51
|
end
|
data/lib/connectwise/version.rb
CHANGED
data/lib/connectwise_sdk.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'savon'
|
2
2
|
require "connectwise/version"
|
3
3
|
require 'connectwise/extensions'
|
4
|
+
require 'connectwise/errors'
|
4
5
|
require 'connectwise/connection'
|
5
6
|
require 'connectwise/model'
|
6
7
|
require 'connectwise/member'
|
7
|
-
require 'connectwise/contact'
|
8
8
|
require 'connectwise/company'
|
9
|
+
require 'connectwise/contact'
|
9
10
|
require 'connectwise/opportunity'
|
10
11
|
require 'connectwise/ticket'
|
11
|
-
|
12
|
-
module Connectwise
|
13
|
-
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Opportunity' do
|
4
|
+
let(:credentials) { connectwise_credentials }
|
5
|
+
let(:conn) { Connectwise::Connection.new(credentials) }
|
6
|
+
let(:contact_attrs) { {first_name: 'Malcom', last_name: 'Reynolds'} }
|
7
|
+
let(:company_attrs) { {name: 'Blue Sun'} }
|
8
|
+
|
9
|
+
it 'creates a company and a contact and connects them' do
|
10
|
+
new_company = Connectwise::Company.new(conn, name: 'Blue Sun').save
|
11
|
+
new_contact = Connectwise::Contact.new(conn, contact_attrs)
|
12
|
+
new_contact.company = new_company
|
13
|
+
new_contact = new_contact.save
|
14
|
+
resp = Connectwise::Contact.find(conn, new_contact.id)
|
15
|
+
expect(resp.company_id).to eq new_company.company_id
|
16
|
+
end
|
17
|
+
end
|
@@ -1,35 +1,44 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Connectwise::Company do
|
4
|
+
let(:credentials) { connectwise_credentials }
|
5
|
+
let(:conn) { Connectwise::Connection.new(credentials) }
|
6
|
+
let(:company) { OpenStruct.new name: 'Blue Sun'}
|
7
|
+
subject {Connectwise::Company.new(conn, company.to_h)}
|
8
|
+
|
4
9
|
it 'creates a company' do
|
5
|
-
|
10
|
+
new_company = subject.save
|
11
|
+
expect(new_company.persisted?).to eq true
|
12
|
+
expect(new_company.id).not_to be_empty
|
13
|
+
expect(new_company.status).to eq 'Active'
|
6
14
|
end
|
7
15
|
|
8
16
|
it 'fails to create a company' do
|
9
|
-
|
10
|
-
expect {subject.
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'fails to create company and throws error' do
|
14
|
-
company.id = nil
|
15
|
-
expect {subject.create_company(company) do |err|
|
16
|
-
fail ArgumentError
|
17
|
-
end}.to raise_error ArgumentError
|
17
|
+
subject.company_id = nil
|
18
|
+
expect {subject.save}.to raise_error Connectwise::ConnectionError
|
18
19
|
end
|
19
20
|
|
20
21
|
it 'deletes a company' do
|
21
|
-
new_company = subject.
|
22
|
-
|
22
|
+
new_company = subject.save
|
23
|
+
instance = new_company.destroy
|
24
|
+
expect {Connectwise::Company.find(conn, new_company.id) }.to raise_error Connectwise::RecordNotFound
|
25
|
+
expect(instance).to eq new_company
|
23
26
|
end
|
24
27
|
|
25
|
-
it 'finds a company' do
|
26
|
-
|
28
|
+
it 'finds a company with search' do
|
29
|
+
subject.save
|
30
|
+
resp = Connectwise::Company.where(conn, company_name: 'Blue Sun')
|
27
31
|
expect(resp).not_to be_empty
|
28
32
|
end
|
29
33
|
|
30
|
-
it '
|
31
|
-
new_company = subject.
|
32
|
-
resp =
|
33
|
-
expect(resp
|
34
|
+
it 'finds a company with id', focus:true do
|
35
|
+
new_company = subject.save
|
36
|
+
resp = Connectwise::Company.find(conn, new_company.id)
|
37
|
+
expect(resp).not_to be_nil
|
38
|
+
expect(resp.id).to eq new_company.id
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'finds no company with in id' do
|
42
|
+
expect {Connectwise::Company.find(conn, 234234)}.to raise_error Connectwise::RecordNotFound
|
34
43
|
end
|
35
44
|
end
|
@@ -1,39 +1,54 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
it 'creates a contact' do
|
10
|
-
contact_id = contact.id
|
11
|
-
new_contact = subject.save
|
12
|
-
expect(new_contact.persisted?).to be_true
|
13
|
-
expect(new_contact.id).not_to be_empty
|
14
|
-
expect(contact_id).not_to eq new_contact.id
|
15
|
-
end
|
3
|
+
module Connectwise
|
4
|
+
describe Contact do
|
5
|
+
let(:credentials) { connectwise_credentials }
|
6
|
+
let(:conn) { Connectwise::Connection.new(credentials) }
|
7
|
+
let(:contact) { OpenStruct.new first_name: 'Malcom', last_name: 'Reynolds' }
|
8
|
+
subject {Connectwise::Contact.new(conn, contact.to_h)}
|
16
9
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
found_contacts = Connectwise::Contact.where(conn, first_name: new_contact.first_name, last_name: new_contact.last_name)
|
21
|
-
expect(found_contacts).not_to be_empty
|
22
|
-
end
|
10
|
+
before :each do
|
11
|
+
#conn.log = true
|
12
|
+
end
|
23
13
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
14
|
+
it 'creates a contact' do
|
15
|
+
new_contact = subject.save
|
16
|
+
expect(new_contact.persisted?).to eq true
|
17
|
+
expect(new_contact.id).not_to be_empty
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'finds a contact' do
|
21
|
+
new_contact = subject.save
|
22
|
+
new_contact = contact
|
23
|
+
found_contacts = Connectwise::Contact.where(conn, first_name: new_contact.first_name, last_name: new_contact.last_name)
|
24
|
+
expect(found_contacts).not_to be_empty
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'finds no contact' do
|
28
|
+
new_contact = subject.save
|
29
|
+
found_contacts = Connectwise::Contact.where(conn, first_name: 'gobledy', last_name: 'gook')
|
30
|
+
expect(found_contacts).to be_empty
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'finds a contact with id' do
|
34
|
+
new_contact = subject.save
|
35
|
+
resp = Connectwise::Contact.find(conn, new_contact.id)
|
36
|
+
expect(resp).not_to be_nil
|
37
|
+
expect(resp.id).to eq new_contact.id
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'finds no contact with in id' do
|
41
|
+
expect {Connectwise::Contact.find(conn, 234234)}.to raise_error Connectwise::RecordNotFound
|
42
|
+
end
|
29
43
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
44
|
+
it 'deletes a contact' do
|
45
|
+
new_contact = subject.save
|
46
|
+
found_contacts = Connectwise::Contact.where(conn, first_name: new_contact.first_name, last_name: new_contact.last_name)
|
47
|
+
current_count = found_contacts.count
|
48
|
+
deleted_contact = found_contacts.first.destroy
|
49
|
+
expect(deleted_contact).not_to be_nil
|
50
|
+
found_contacts = Connectwise::Contact.where(conn, first_name: new_contact.first_name, last_name: new_contact.last_name)
|
51
|
+
expect(current_count - found_contacts.count).to eq 1
|
52
|
+
end
|
38
53
|
end
|
39
54
|
end
|
@@ -1,17 +1,49 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Connectwise::Opportunity do
|
4
|
+
let(:credentials) { connectwise_credentials }
|
5
|
+
let(:conn) { Connectwise::Connection.new(credentials) }
|
6
|
+
let(:company_attrs) { {name: 'Blue Sun'} }
|
7
|
+
let(:contact_attrs) { {first_name: 'Malcom', last_name: 'Reynolds'} }
|
8
|
+
let(:opp_attrs) { {name: 'Something', source: 'EOP', primary_sales_rep: 'Admin1'} }
|
9
|
+
let(:full_op) {
|
10
|
+
new_company = Connectwise::Company.new(conn, company_attrs).save
|
11
|
+
new_contact = Connectwise::Contact.new(conn, contact_attrs.merge(company: new_company)).save
|
12
|
+
Connectwise::Opportunity.new(conn, opp_attrs.merge(company: new_company, contact: new_contact)).save
|
13
|
+
}
|
14
|
+
subject {Connectwise::Opportunity}
|
15
|
+
|
4
16
|
it 'creates an opportunity' do
|
5
|
-
new_company =
|
6
|
-
new_contact =
|
7
|
-
resp = subject.
|
8
|
-
expect(resp
|
17
|
+
new_company = Connectwise::Company.new(conn, company_attrs).save
|
18
|
+
new_contact = Connectwise::Contact.new(conn, contact_attrs.merge(company: new_company)).save
|
19
|
+
resp = subject.new(conn, opp_attrs.merge(company: new_company, contact: new_contact)).save
|
20
|
+
expect(resp.persisted?).to eq true
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'finds opportunities' do
|
24
|
+
new_opp = full_op
|
25
|
+
found_opps = Connectwise::Opportunity.where(conn, opp_attrs.delete_if {|k, v| k == :source})
|
26
|
+
expect(found_opps).not_to be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'finds no opportunities' do
|
30
|
+
found_opps = Connectwise::Opportunity.where(conn, name: 'Non-existent name')
|
31
|
+
expect(found_opps).to be_empty
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'gets an opportunity' do
|
35
|
+
new_opp = full_op
|
36
|
+
found_opp = Connectwise::Opportunity.find(conn, new_opp.id)
|
37
|
+
expect(found_opp.id).not_to be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'fails to find an opportunity' do
|
41
|
+
expect { Connectwise::Opportunity.find(conn, 123123123) }.to raise_error Connectwise::RecordNotFound
|
9
42
|
end
|
10
43
|
|
11
44
|
it 'deletes an opportunity' do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
expect(subject.delete_opportunity(OpenStruct.new(id: new_opp[:id]))).to be_nil
|
45
|
+
new_opp = full_op
|
46
|
+
new_opp.destroy
|
47
|
+
expect {Connectwise::Opportunity.find(conn, new_opp.id)}.to raise_error Connectwise::RecordNotFound
|
16
48
|
end
|
17
49
|
end
|
@@ -1,16 +1,54 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Connectwise::Ticket do
|
4
|
+
let(:credentials) { connectwise_credentials }
|
5
|
+
let(:conn) { Connectwise::Connection.new(credentials) }
|
6
|
+
let(:company_attrs) { {name: 'Pandorica'} }
|
7
|
+
let(:ticket_attrs) { {summary: 'Help me', problem_description: 'I need the doctor!'} }
|
8
|
+
let(:company) { Connectwise::Company.new(conn, company_attrs) }
|
9
|
+
subject {Connectwise::Ticket.new(conn, ticket_attrs)}
|
10
|
+
|
4
11
|
it 'creates a ticket' do
|
5
|
-
|
6
|
-
|
7
|
-
expect(
|
12
|
+
subject.company = company.save
|
13
|
+
new_ticket = subject.save
|
14
|
+
expect(new_ticket.persisted?).to eq true
|
8
15
|
end
|
9
16
|
|
10
17
|
it 'finds a service ticket' do
|
11
|
-
|
12
|
-
new_ticket = subject.
|
13
|
-
resp =
|
18
|
+
subject.company = company.save
|
19
|
+
new_ticket = subject.save
|
20
|
+
resp = Connectwise::Ticket.where(conn, summary: 'Help me')
|
14
21
|
expect(resp).not_to be_empty
|
15
22
|
end
|
23
|
+
|
24
|
+
it 'finds no ticket' do
|
25
|
+
subject.company = company.save
|
26
|
+
new_ticket = subject.save
|
27
|
+
found_tickets = Connectwise::Ticket.where(conn, summary: 'gobledy-gook')
|
28
|
+
expect(found_tickets).to be_empty
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'finds a ticket with id' do
|
32
|
+
subject.company = company.save
|
33
|
+
new_ticket = subject.save
|
34
|
+
p new_ticket.id
|
35
|
+
resp = Connectwise::Ticket.find(conn, new_ticket.id)
|
36
|
+
expect(resp).not_to be_nil
|
37
|
+
expect(resp.id).to eq new_ticket.id
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'finds no ticket with in id' do
|
41
|
+
expect {Connectwise::Ticket.find(conn, 234234)}.to raise_error Connectwise::RecordNotFound
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'deletes a ticket' do
|
45
|
+
subject.company = company.save
|
46
|
+
new_ticket = subject.save
|
47
|
+
found_ticket = Connectwise::Ticket.find(conn, new_ticket.id)
|
48
|
+
expect(found_ticket).not_to be_nil
|
49
|
+
deleted_ticket = found_tickets.first.destroy
|
50
|
+
expect(deleted_ticket).not_to be_nil
|
51
|
+
found_ticket = Connectwise::ticket.find(conn, new_ticket.id)
|
52
|
+
expect(found_ticket).to be_nil
|
53
|
+
end
|
16
54
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: connectwise_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emery A. Miller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -83,6 +83,7 @@ files:
|
|
83
83
|
- lib/connectwise/connection.rb
|
84
84
|
- lib/connectwise/connectwise.rb
|
85
85
|
- lib/connectwise/contact.rb
|
86
|
+
- lib/connectwise/errors.rb
|
86
87
|
- lib/connectwise/extensions.rb
|
87
88
|
- lib/connectwise/member.rb
|
88
89
|
- lib/connectwise/model.rb
|
@@ -91,6 +92,7 @@ files:
|
|
91
92
|
- lib/connectwise/version.rb
|
92
93
|
- lib/connectwise_sdk.rb
|
93
94
|
- spec/credentials.yml.sample
|
95
|
+
- spec/integration/opportunity_spec.rb
|
94
96
|
- spec/lib/connectwise/company_spec.rb
|
95
97
|
- spec/lib/connectwise/connection_spec.rb
|
96
98
|
- spec/lib/connectwise/contact_spec.rb
|
@@ -125,6 +127,7 @@ specification_version: 4
|
|
125
127
|
summary: A Connectwise SDK for Ruby
|
126
128
|
test_files:
|
127
129
|
- spec/credentials.yml.sample
|
130
|
+
- spec/integration/opportunity_spec.rb
|
128
131
|
- spec/lib/connectwise/company_spec.rb
|
129
132
|
- spec/lib/connectwise/connection_spec.rb
|
130
133
|
- spec/lib/connectwise/contact_spec.rb
|