insightly 0.1.8 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +8 -1
- data/lib/insightly.rb +13 -0
- data/lib/insightly/address.rb +20 -0
- data/lib/insightly/address_helper.rb +21 -0
- data/lib/insightly/base.rb +3 -1
- data/lib/insightly/base_data.rb +49 -0
- data/lib/insightly/contact.rb +42 -0
- data/lib/insightly/contact_info.rb +61 -0
- data/lib/insightly/contact_info_helper.rb +14 -0
- data/lib/insightly/link.rb +32 -0
- data/lib/insightly/link_helper.rb +14 -0
- data/lib/insightly/opportunity.rb +7 -3
- data/lib/insightly/organisation.rb +45 -0
- data/lib/insightly/read_only.rb +0 -1
- data/lib/insightly/read_write.rb +8 -2
- data/lib/insightly/task.rb +29 -28
- data/lib/insightly/task_link.rb +28 -5
- data/lib/insightly/task_link_helper.rb +14 -0
- data/lib/insightly/version.rb +2 -2
- data/spec/unit/address_spec.rb +81 -0
- data/spec/unit/contact_spec.rb +255 -0
- data/spec/unit/link_spec.rb +98 -0
- data/spec/unit/opportunity_spec.rb +58 -1
- data/spec/unit/organisation_spec.rb +239 -0
- data/spec/unit/task_link_spec.rb +1 -0
- data/spec/unit/task_spec.rb +96 -0
- metadata +19 -5
data/README.md
CHANGED
@@ -47,7 +47,14 @@ The API allows you to change the state of an opportunity directly by modifying t
|
|
47
47
|
that the opportunity state was changed. In order to store the reason, you have to PUT to OpportunityStateChange with a valid OpportunityStateReason.
|
48
48
|
OpportunityStateReasons can only be created manually in the web interface and then referred to via the API.
|
49
49
|
|
50
|
-
This is important if you want to have it show you the state changes in the
|
50
|
+
This is important if you want to have it show you the state changes in the Opportunity details. Direct modifications don't create a log entry.
|
51
51
|
Whereas the log entry is created if you do create them. In order for your code to work, you need to make sure you have valid Opportunity State Reasons for all the states.
|
52
52
|
|
53
53
|
We default to creating two for open - "Created by API", and "Reopened by API". This allows us to set those as reasons if they exist.
|
54
|
+
|
55
|
+
|
56
|
+
Organisation? Organization
|
57
|
+
===========
|
58
|
+
|
59
|
+
The documentation for Insight.ly the mixes the use of Organization and Organisation. Insight.ly spells it Organisation in urls and in the API - so we
|
60
|
+
only use that spelling in the library.
|
data/lib/insightly.rb
CHANGED
@@ -4,11 +4,24 @@ require 'logger'
|
|
4
4
|
require 'insightly/configuration'
|
5
5
|
require "active_support/core_ext" #Needed for Hash.from_xml
|
6
6
|
|
7
|
+
require 'insightly/address_helper'
|
8
|
+
require 'insightly/contact_info_helper'
|
9
|
+
require 'insightly/link_helper'
|
10
|
+
require 'insightly/task_link_helper'
|
11
|
+
|
12
|
+
|
7
13
|
require 'insightly/base'
|
14
|
+
require 'insightly/base_data'
|
8
15
|
require 'insightly/read_write'
|
9
16
|
require 'insightly/read_only'
|
17
|
+
require "insightly/address"
|
18
|
+
require "insightly/contact_info"
|
19
|
+
require 'insightly/contact'
|
10
20
|
require 'insightly/task'
|
11
21
|
require 'insightly/task_link'
|
12
22
|
require 'insightly/comment'
|
13
23
|
require 'insightly/opportunity_state_reason'
|
14
24
|
require 'insightly/opportunity'
|
25
|
+
require 'insightly/organisation'
|
26
|
+
require "insightly/link"
|
27
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Insightly
|
2
|
+
class Address < BaseData
|
3
|
+
api_field "ADDRESS_ID",
|
4
|
+
"ADDRESS_TYPE",
|
5
|
+
"STREET",
|
6
|
+
"CITY",
|
7
|
+
"STATE",
|
8
|
+
"POSTCODE",
|
9
|
+
"COUNTRY"
|
10
|
+
|
11
|
+
def same_address?(other)
|
12
|
+
self.address_type == other.address_type &&
|
13
|
+
self.street == other.street &&
|
14
|
+
self.city == other.city &&
|
15
|
+
self.state == other.state &&
|
16
|
+
self.postcode == other.postcode &&
|
17
|
+
self.country == other.country
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Insightly
|
2
|
+
module AddressHelper
|
3
|
+
def addresses
|
4
|
+
@data["ADDRESSES"].collect {|a| Insightly::Address.build(a)}
|
5
|
+
end
|
6
|
+
def addresses=(list)
|
7
|
+
@data["ADDRESSES"] = list.collect {|a| a.remote_data}
|
8
|
+
end
|
9
|
+
def add_address(address)
|
10
|
+
|
11
|
+
@data["ADDRESSES"].each do |a|
|
12
|
+
if address.same_address?(Insightly::Address.build(a))
|
13
|
+
|
14
|
+
return false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@data["ADDRESSES"] << address.remote_data
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/insightly/base.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Insightly
|
2
|
+
class BaseData
|
3
|
+
class << self
|
4
|
+
attr_accessor :api_fields
|
5
|
+
end
|
6
|
+
self.api_fields = []
|
7
|
+
|
8
|
+
|
9
|
+
def self.api_field(*args)
|
10
|
+
args.each do |field|
|
11
|
+
self.api_fields = [] if !self.api_fields
|
12
|
+
self.api_fields << field
|
13
|
+
method_name = field.downcase.to_sym
|
14
|
+
send :define_method, method_name do
|
15
|
+
@data[field]
|
16
|
+
end
|
17
|
+
method_name = "#{field.downcase}=".to_sym
|
18
|
+
send :define_method, method_name do |value|
|
19
|
+
@data[field] = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@data = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_json
|
29
|
+
@data.to_json
|
30
|
+
end
|
31
|
+
|
32
|
+
def build(data)
|
33
|
+
@data = data
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.build(data)
|
38
|
+
self.new.build(data)
|
39
|
+
end
|
40
|
+
|
41
|
+
def ==(other)
|
42
|
+
self.remote_data == other.remote_data
|
43
|
+
end
|
44
|
+
|
45
|
+
def remote_data
|
46
|
+
@data
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Insightly
|
2
|
+
class Contact < ReadWrite
|
3
|
+
include Insightly::AddressHelper
|
4
|
+
include Insightly::ContactInfoHelper
|
5
|
+
include Insightly::LinkHelper
|
6
|
+
self.url_base = "Contacts"
|
7
|
+
CUSTOM_FIELD_PREFIX = "CONTACT_FIELD"
|
8
|
+
api_field "CONTACT_ID",
|
9
|
+
"SALUTATION",
|
10
|
+
"FIRST_NAME",
|
11
|
+
"LAST_NAME",
|
12
|
+
"BACKGROUND",
|
13
|
+
"CONTACT_FIELD_1",
|
14
|
+
"CONTACT_FIELD_2",
|
15
|
+
"CONTACT_FIELD_3",
|
16
|
+
"CONTACT_FIELD_4",
|
17
|
+
"CONTACT_FIELD_5",
|
18
|
+
"CONTACT_FIELD_6",
|
19
|
+
"CONTACT_FIELD_7",
|
20
|
+
"CONTACT_FIELD_8",
|
21
|
+
"CONTACT_FIELD_9",
|
22
|
+
"CONTACT_FIELD_10",
|
23
|
+
"DATE_CREATED_UTC",
|
24
|
+
"DATE_UPDATED_UTC",
|
25
|
+
"VISIBLE_TO",
|
26
|
+
"VISIBLE_TEAM_ID"
|
27
|
+
|
28
|
+
def initialize(id = nil)
|
29
|
+
@data = {}
|
30
|
+
@data["ADDRESSES"] = []
|
31
|
+
load(id) if id
|
32
|
+
end
|
33
|
+
def remote_id
|
34
|
+
contact_id
|
35
|
+
end
|
36
|
+
def fix_for_link(link)
|
37
|
+
#This needs to auto set the org id on the item
|
38
|
+
link.contact_id = self.remote_id
|
39
|
+
link
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Insightly
|
2
|
+
class ContactInfo
|
3
|
+
def initialize
|
4
|
+
@data = {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_json
|
8
|
+
@data.to_json
|
9
|
+
end
|
10
|
+
def build(data)
|
11
|
+
@data = data
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.build(data)
|
16
|
+
self.new.build(data)
|
17
|
+
end
|
18
|
+
|
19
|
+
def ==(other)
|
20
|
+
self.remote_data == other.remote_data
|
21
|
+
end
|
22
|
+
|
23
|
+
def remote_data
|
24
|
+
@data
|
25
|
+
end
|
26
|
+
def contact_info_id
|
27
|
+
@data["CONTACT_INFO_ID"]
|
28
|
+
|
29
|
+
end
|
30
|
+
def type
|
31
|
+
@data["TYPE"]
|
32
|
+
end
|
33
|
+
def subtype
|
34
|
+
@data["SUBTYPE"]
|
35
|
+
end
|
36
|
+
def label
|
37
|
+
@data["LABEL"]
|
38
|
+
end
|
39
|
+
def detail
|
40
|
+
@data["DETAIL"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def contact_info_id=(value)
|
44
|
+
@data["CONTACT_INFO_ID"] = value
|
45
|
+
|
46
|
+
end
|
47
|
+
def type=(value)
|
48
|
+
@data["TYPE"] = value
|
49
|
+
end
|
50
|
+
def subtype=(value)
|
51
|
+
@data["SUBTYPE"] = value
|
52
|
+
end
|
53
|
+
def label=(value)
|
54
|
+
@data["LABEL"] = value
|
55
|
+
end
|
56
|
+
def detail=(value)
|
57
|
+
@data["DETAIL"] = value
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Insightly
|
2
|
+
module ContactInfoHelper
|
3
|
+
def contact_infos
|
4
|
+
@data["CONTACTINFOS"].collect {|a| Insightly::ContactInfo.build(a)}
|
5
|
+
end
|
6
|
+
def contact_infos=(list)
|
7
|
+
@data["CONTACTINFOS"] = list.collect {|a| a.remote_data}
|
8
|
+
end
|
9
|
+
def add_contact_info(contact_info)
|
10
|
+
@data["CONTACTINFOS"] << contact_info.remote_data
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Insightly
|
2
|
+
class Link < BaseData
|
3
|
+
api_field "LINK_ID",
|
4
|
+
"PROJECT_ID",
|
5
|
+
"CONTACT_ID",
|
6
|
+
"ROLE",
|
7
|
+
"OPPORTUNITY_ID",
|
8
|
+
"DETAILS",
|
9
|
+
"ORGANISATION_ID"
|
10
|
+
def self.add_contact(id,role = nil,detail = nil)
|
11
|
+
item = Link.new
|
12
|
+
item.contact_id = id
|
13
|
+
item.role = role
|
14
|
+
item.details = detail
|
15
|
+
item
|
16
|
+
end
|
17
|
+
def self.add_opportunity(id,role = nil,detail = nil)
|
18
|
+
item = Link.new
|
19
|
+
item.opportunity_id = id
|
20
|
+
item.role = role
|
21
|
+
item.details = detail
|
22
|
+
item
|
23
|
+
end
|
24
|
+
def self.add_organisation(id,role = nil,detail = nil)
|
25
|
+
item = Link.new
|
26
|
+
item.organisation_id = id
|
27
|
+
item.role = role
|
28
|
+
item.details = detail
|
29
|
+
item
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Insightly
|
2
|
+
module LinkHelper
|
3
|
+
def links
|
4
|
+
@data["LINKS"].collect {|a| Insightly::Link.build(a)}
|
5
|
+
end
|
6
|
+
def links=(list)
|
7
|
+
@data["LINKS"] = list.collect {|a| fix_for_link(a).remote_data}
|
8
|
+
end
|
9
|
+
def add_link(link)
|
10
|
+
@data["LINKS"] << fix_for_link(link).remote_data
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
|
-
|
2
|
-
#METODO Confirm that we can create an opportunity
|
3
1
|
module Insightly
|
4
2
|
class Opportunity < ReadWrite
|
3
|
+
include Insightly::LinkHelper
|
5
4
|
self.url_base = "Opportunities"
|
6
5
|
CUSTOM_FIELD_PREFIX = "OPPORTUNITY_FIELD"
|
7
6
|
api_field "OPPORTUNITY_FIELD_10",
|
@@ -35,7 +34,6 @@ module Insightly
|
|
35
34
|
"OPPORTUNITY_NAME",
|
36
35
|
"OPPORTUNITY_ID",
|
37
36
|
"VISIBLE_USER_IDS",
|
38
|
-
"LINKS",
|
39
37
|
"RESPONSIBLE_USER_ID",
|
40
38
|
"OPPORTUNITY_DETAILS"
|
41
39
|
|
@@ -111,5 +109,11 @@ module Insightly
|
|
111
109
|
end
|
112
110
|
|
113
111
|
end
|
112
|
+
def fix_for_link(link)
|
113
|
+
#This needs to auto set the org id on the item
|
114
|
+
link.opportunity_id = self.remote_id
|
115
|
+
link
|
116
|
+
end
|
114
117
|
end
|
118
|
+
|
115
119
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Insightly
|
2
|
+
class Organisation < ReadWrite
|
3
|
+
include Insightly::AddressHelper
|
4
|
+
include Insightly::ContactInfoHelper
|
5
|
+
include Insightly::LinkHelper
|
6
|
+
self.url_base = "Organisations"
|
7
|
+
CUSTOM_FIELD_PREFIX = "ORGANISATION_FIELD"
|
8
|
+
api_field "ORGANISATION_ID",
|
9
|
+
"ORGANISATION_NAME",
|
10
|
+
"BACKGROUND",
|
11
|
+
"ORGANISATION_FIELD_1",
|
12
|
+
"ORGANISATION_FIELD_2",
|
13
|
+
"ORGANISATION_FIELD_3",
|
14
|
+
"ORGANISATION_FIELD_4",
|
15
|
+
"ORGANISATION_FIELD_5",
|
16
|
+
"ORGANISATION_FIELD_6",
|
17
|
+
"ORGANISATION_FIELD_7",
|
18
|
+
"ORGANISATION_FIELD_8",
|
19
|
+
"ORGANISATION_FIELD_9",
|
20
|
+
"ORGANISATION_FIELD_10",
|
21
|
+
"OWNER_USER_ID",
|
22
|
+
"DATE_CREATED_UTC",
|
23
|
+
"DATE_UPDATED_UTC",
|
24
|
+
"VISIBLE_TO",
|
25
|
+
"VISIBLE_TEAM_ID"
|
26
|
+
|
27
|
+
def initialize(id = nil)
|
28
|
+
@data = {}
|
29
|
+
@data["ADDRESSES"] = []
|
30
|
+
load(id) if id
|
31
|
+
end
|
32
|
+
|
33
|
+
def remote_id
|
34
|
+
organisation_id
|
35
|
+
end
|
36
|
+
|
37
|
+
def fix_for_link(link)
|
38
|
+
#This needs to auto set the org id on the item
|
39
|
+
link.organisation_id = self.remote_id
|
40
|
+
link
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/lib/insightly/read_only.rb
CHANGED
data/lib/insightly/read_write.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
module Insightly
|
2
2
|
class ReadWrite < Base
|
3
|
+
def to_json
|
4
|
+
@data.to_json
|
5
|
+
end
|
6
|
+
def update_data(data)
|
7
|
+
@data = data
|
8
|
+
end
|
3
9
|
def save
|
4
10
|
if !remote_id
|
5
|
-
|
11
|
+
update_data(post_collection("#{url_base}", self.to_json))
|
6
12
|
else
|
7
13
|
|
8
|
-
|
14
|
+
update_data(put_collection("#{url_base}/#{remote_id}", self.to_json))
|
9
15
|
|
10
16
|
end
|
11
17
|
|
data/lib/insightly/task.rb
CHANGED
@@ -1,8 +1,28 @@
|
|
1
|
-
#METODO Find a way to link a task to an opportunity
|
2
|
-
|
3
1
|
module Insightly
|
4
2
|
class Task < ReadWrite
|
3
|
+
include Insightly::TaskLinkHelper
|
5
4
|
self.url_base = "Tasks"
|
5
|
+
api_field "TASK_ID",
|
6
|
+
"TITLE",
|
7
|
+
"CATEGORY_ID",
|
8
|
+
"DUE_DATE",
|
9
|
+
"COMPLETED_DATE_UTC",
|
10
|
+
"PUBLICLY_VISIBLE",
|
11
|
+
"COMPLETED",
|
12
|
+
"PROJECT_ID",
|
13
|
+
"DETAILS",
|
14
|
+
"STATUS",
|
15
|
+
"PRIORITY",
|
16
|
+
"PERCENT_COMPLETE",
|
17
|
+
"START_DATE",
|
18
|
+
"ASSIGNED_BY_USER_ID",
|
19
|
+
"PARENT_TASK_ID",
|
20
|
+
"RECURRENCE",
|
21
|
+
"RESPONSIBLE_USER_ID",
|
22
|
+
"OWNER_USER_ID",
|
23
|
+
"DATE_CREATED_UTC",
|
24
|
+
"DATE_UPDATED_UTC",
|
25
|
+
"TASKLINKS"
|
6
26
|
|
7
27
|
def comments
|
8
28
|
list = []
|
@@ -11,33 +31,13 @@ module Insightly
|
|
11
31
|
end
|
12
32
|
list
|
13
33
|
end
|
34
|
+
|
14
35
|
def comment_on(body)
|
15
|
-
comment = Insightly::Comment.new.build({
|
36
|
+
comment = Insightly::Comment.new.build({"BODY" => body})
|
16
37
|
result = post_collection("#{url_base}/#{task_id}/comments", comment.remote_data.to_json)
|
17
38
|
comment.build(result)
|
18
39
|
end
|
19
|
-
#def comment_on(body)
|
20
|
-
# user_id = 226277
|
21
|
-
# xml_data = '<?xml version="1.0" encoding="utf-8"?><Comment xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><BODY><p>&nbsp;Hello Nurse</p></BODY><OWNER_USER_ID>226277</OWNER_USER_ID><FILE_ATTACHMENTS/></Comment>'
|
22
|
-
#
|
23
|
-
#
|
24
|
-
# post_collection("#{url_base}/#{task_id}/comments", xml_data, :xml)
|
25
|
-
#end
|
26
|
-
#
|
27
|
-
#def comments
|
28
|
-
# data = get_collection("#{url_base}/#{task_id}/Comments")
|
29
|
-
# list = []
|
30
|
-
# data.each do |x|
|
31
|
-
# end
|
32
|
-
# list
|
33
|
-
#end
|
34
40
|
|
35
|
-
def status
|
36
|
-
@data["STATUS"]
|
37
|
-
end
|
38
|
-
def status=(new_status)
|
39
|
-
@data["STATUS"] = new_status
|
40
|
-
end
|
41
41
|
def not_started?
|
42
42
|
status == "NOT STARTED"
|
43
43
|
end
|
@@ -58,15 +58,16 @@ module Insightly
|
|
58
58
|
status == "DEFERRED"
|
59
59
|
end
|
60
60
|
|
61
|
-
def task_id
|
62
|
-
@data["TASK_ID"]
|
63
|
-
end
|
64
61
|
|
65
62
|
def remote_id
|
66
63
|
task_id
|
67
64
|
end
|
68
65
|
|
69
|
-
|
66
|
+
def fix_for_link(link)
|
67
|
+
#This needs to auto set the org id on the item
|
68
|
+
link.task_id = self.remote_id
|
69
|
+
link
|
70
|
+
end
|
70
71
|
|
71
72
|
end
|
72
73
|
end
|