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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f97ff9137957a443af0184ff9f5be0864b3abd0f
4
- data.tar.gz: 7348114bd346b8b314659b5006c3cd9117c61e73
3
+ metadata.gz: 546290353531e430d7605b8aa51830e260bdf854
4
+ data.tar.gz: f096307dc3cdba0adbba01d627b0cfdaa3d13a18
5
5
  SHA512:
6
- metadata.gz: a4c762a2424ccfd108bfcd55ccfb09be095ad2b9ec6abdb384711c36062dc87a045dc74949bbc3a6d67dcb9c406d97100b11000a8314febdae797702ad239a12
7
- data.tar.gz: e94651ab74d558d127b9de456fe3bf794bf4c1d3b32078008f9f291f7e6371c6dd2e40e0e74504df08a9e3fb045d8faa689d011bfbe4353563b97c0dcbc3bbc2
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 allowing integration into Connectwise
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 only the `Member.where` method, and the low level `Connection.call` method are working.
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. Complete Contact class
62
- 2. Company class
63
- 3. Opportunity class
64
- 4. Ticket class
65
- 5. Remaining api
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 (A company has a contact)
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.
@@ -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)
@@ -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
- def self.where(connection, **attrs)
9
- resp = connection.call :contact, :find_contacts, {conditions: attrs_to_query(attrs)}
10
- Array(resp[:contact_find_result]).map {|attrs| p attrs; cw_find_to_model(connection, attrs) }
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.cw_find_to_model(conn, attrs)
30
- id = attrs.delete(:contact_rec_id)
31
- #TODO - make use of company rec id - either run another query to create it, or find a way to defer until company is asked for
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.cw_save_to_model(conn, attrs)
37
-
19
+ def self.save_transform(attrs)
20
+ attrs[:id] ||= attrs.delete(:contact_rec_id)
21
+ attrs
38
22
  end
39
23
 
40
- def create_contact(contact, company_id=nil, &err_handler)
41
- message = {
42
- FirstName: contact.first_name,
43
- LastName: contact.last_name,
44
- Email: contact.email,
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
@@ -0,0 +1,7 @@
1
+ module Connectwise
2
+ class ConnectionError < StandardError; end
3
+ class UnknownHostError < ConnectionError; end
4
+ class UnknownCompanyError < ConnectionError; end
5
+ class BadCredentialsError < ConnectionError; end
6
+ class RecordNotFound < StandardError; end
7
+ end
@@ -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.where(connection, **attrs)
7
- resp = connection.call :member, :find_members, {conditions: attrs_to_query(attrs)}
8
- Array(resp[:member_find_result]).map {|attrs| cw_to_model(connection, attrs) }
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
@@ -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 "#{attr}=", value
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
- false
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Connectwise
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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
- expect(subject.create_company(company)[:id]).not_to be_empty
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
- company.id = nil
10
- expect {subject.create_company(company)}.to raise_error Connectwise::ConnectionError
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.create_company(company)
22
- expect(subject.delete_company(OpenStruct.new(id: new_company[:id]))).to be_nil
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
- resp = subject.find_company(OpenStruct.new name: 'Blue Sun', id: '6417')
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 'creates a company and a contact and connects them' do
31
- new_company = subject.create_company(company)
32
- resp = subject.create_contact(contact, new_company[:company_id])
33
- expect(resp[:company_id]).to eql new_company[:company_id]
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
- describe Connectwise::Contact do
4
- let(:credentials) { connectwise_credentials }
5
- let(:conn) { Connectwise::Connection.new(credentials) }
6
- let(:contact) { OpenStruct.new first_name: 'Malcom', last_name: 'Reynolds' }
7
- subject {Connectwise::Contact.new(conn, contact.to_h)}
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
- it 'finds a contact' do
18
- new_contact = subject.save
19
- new_contact = contact
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
- it 'finds no contact' do
25
- new_contact = subject.save
26
- found_contacts = Connectwise::Contact.where(conn, first_name: 'gobledy', last_name: 'gook')
27
- expect(found_contacts).to be_empty
28
- end
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
- it 'deletes a contact' do
31
- new_contact = subject.save
32
- found_contacts = Connectwise::Contact.where(conn, first_name: new_contact.first_name, last_name: new_contact.last_name)
33
- current_count = found_contacts.count
34
- deleted_contact = found_contacts.first.destroy
35
- expect(deleted_contact).not_to be_nil
36
- found_contacts = Connectwise::Contact.where(conn, first_name: new_contact.first_name, last_name: new_contact.last_name)
37
- expect(current_count - found_contacts.count).to eq 1
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 = subject.create_company(company)
6
- new_contact = subject.create_contact(contact, new_company[:company_id])
7
- resp = subject.create_opportunity(lead, new_company[:company_id], new_contact[:id])
8
- expect(resp[:id]).not_to be_empty
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
- new_company = subject.create_company(company)
13
- new_contact = subject.create_contact(contact, new_company[:company_id])
14
- new_opp = subject.create_opportunity(lead, new_company[:company_id], new_contact[:id])
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
- new_company = subject.create_company(company)
6
- resp = subject.create_ticket(OpenStruct.new(subject: 'help', description: 'abcd go boom'), OpenStruct.new(id: new_company[:company_id]))
7
- expect(resp[:ticket_number]).not_to be_nil
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
- new_company = subject.create_company(company)
12
- new_ticket = subject.create_ticket(OpenStruct.new(subject: 'help', description: 'abcd go boom'), OpenStruct.new(id: new_company[:company_id]))
13
- resp = subject.find_ticket(OpenStruct.new(id: new_ticket[:ticket_number]), OpenStruct.new(name: 'Gobledygook ragnok ramastrodon'))
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.1
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-09-17 00:00:00.000000000 Z
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