rubyzoho 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +15 -3
- data/Gemfile +14 -18
- data/README.rdoc +47 -7
- data/VERSION +1 -1
- data/lib/ruby_zoho.rb +57 -188
- data/lib/zoho_api.rb +55 -13
- data/rubyzoho.gemspec +27 -32
- data/spec/ruby_zoho_spec.rb +76 -11
- data/spec/zoho_api_spec.rb +96 -9
- metadata +31 -49
- data/Gemfile.lock +0 -88
- data/rubyzoho-0.1.1.gem +0 -0
data/.travis.yml
CHANGED
@@ -1,5 +1,17 @@
|
|
1
|
+
---
|
1
2
|
language: ruby
|
2
3
|
rvm:
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
- 1.9.3
|
5
|
+
# - jruby
|
6
|
+
|
7
|
+
matrix:
|
8
|
+
allow-failures:
|
9
|
+
- rvm: jruby
|
10
|
+
|
11
|
+
env:
|
12
|
+
global:
|
13
|
+
- secure: ! 'E2ZilvytrU4gPdPZna7EMJmrDHQPfjo7KLnY4geip1coSrmISaf3VhKlGMDY
|
14
|
+
|
15
|
+
NubPbNdM6K98F98hQfMszGjt7YJz8y5dJrpwT4847ZL9k0FLN8XsjdxW7gH4
|
16
|
+
|
17
|
+
Dqocd1v5HY2gK60quwr0YPza10bgw6XseYXlrMtVgpTFOYv5HTg='
|
data/Gemfile
CHANGED
@@ -1,25 +1,21 @@
|
|
1
|
-
source
|
2
|
-
|
3
|
-
gem 'httmultiparty'
|
4
|
-
gem 'roxml'
|
1
|
+
source 'http://rubygems.org'
|
5
2
|
|
3
|
+
gem 'httmultiparty', '>= 0.3.8'
|
4
|
+
gem 'roxml', '>= 3.3.1'
|
5
|
+
gem 'multipart-post'
|
6
6
|
|
7
7
|
group :test do
|
8
|
-
gem '
|
9
|
-
gem '
|
10
|
-
gem
|
11
|
-
gem 'xml-simple'
|
12
|
-
gem 'simplecov', :require => false, :group => :test
|
8
|
+
gem 'rspec', '>= 2.12.0'
|
9
|
+
gem 'xml-simple', '>=1.1.2'
|
10
|
+
gem 'simplecov', '>= 0.7.1', :require => false, :group => :test
|
13
11
|
end
|
14
12
|
|
15
13
|
group :development do
|
16
|
-
gem
|
17
|
-
gem 'cucumber'
|
18
|
-
gem
|
19
|
-
gem 'relish'
|
20
|
-
gem
|
21
|
-
gem 'rspec',
|
22
|
-
gem
|
23
|
-
gem 'xml-simple'
|
24
|
-
gem 'simplecov', :require => false, :group => :test
|
14
|
+
gem 'bundler', '>= 1.2'
|
15
|
+
gem 'cucumber', '>= 1.2.1'
|
16
|
+
gem 'jeweler', '~> 1.8.4'
|
17
|
+
gem 'relish', '>= 0.6'
|
18
|
+
gem 'rdoc', '>= 3.12.1'
|
19
|
+
gem 'rspec', '>= 2.12.0'
|
20
|
+
gem 'xml-simple', '>=1.1.2'
|
25
21
|
end
|
data/README.rdoc
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
= rubyzoho
|
6
6
|
|
7
7
|
Abstracting Zoho's API into a set of Ruby classes, with reflection of Zoho's fields using a more familiar
|
8
|
-
ActiveRecord lifecycle but without ActiveRecord.
|
8
|
+
ActiveRecord lifecycle, but without ActiveRecord. Current focus is on Zoho CRM.
|
9
9
|
|
10
10
|
== Install
|
11
11
|
gem install rubyzoho
|
@@ -32,11 +32,12 @@ Make sure the following block is executed prior to making calls to the gem.
|
|
32
32
|
RubyZoho.configure do |config|
|
33
33
|
config.api_key = '<< API Key from Zoho>>'
|
34
34
|
# config.crm_modules = ['Accounts', 'Contacts', 'Leads', 'Potentials'] # Defaults to free edition if not set
|
35
|
-
# config.crm_modules = ['
|
35
|
+
# config.crm_modules = ['Quotes', 'SalesOrders', 'Invoices'] # Depending on what kind of account you've got, adds to free edition modules
|
36
|
+
# Currently only Quotes are suported
|
36
37
|
end
|
37
38
|
|
38
39
|
Please be aware that Zoho limits API calls. So running tests repeatedly will quickly exhaust
|
39
|
-
your daily allowance.
|
40
|
+
your daily allowance. See below for some optimizations during development and testing.
|
40
41
|
|
41
42
|
|
42
43
|
|
@@ -81,6 +82,11 @@ To get a list of all accounts:
|
|
81
82
|
pp account.account_name
|
82
83
|
end
|
83
84
|
|
85
|
+
Or for all task subjects:
|
86
|
+
|
87
|
+
t = RubyZoho::Crm::Task.all
|
88
|
+
pp t.collect { |task| task.subject }
|
89
|
+
|
84
90
|
Or for all quotes:
|
85
91
|
|
86
92
|
q = RubyZoho::Crm::Quote.all
|
@@ -134,7 +140,7 @@ To add a contact to an existing account:
|
|
134
140
|
)
|
135
141
|
c.save
|
136
142
|
|
137
|
-
To update a record:
|
143
|
+
To update a record (<b>Note, that the attribute is :id</b>):
|
138
144
|
l = RubyZoho::Crm::Lead.find_by_email('email@domain.com')
|
139
145
|
RubyZoho::Crm::Lead.update(
|
140
146
|
:id => l.first.leadid,
|
@@ -152,11 +158,44 @@ Objects currently supported are:
|
|
152
158
|
RubyZoho::Crm::Quote
|
153
159
|
RubyZoho::Crm::User
|
154
160
|
|
161
|
+
== Error Handling
|
162
|
+
Errors, i.e. situations where the Zoho API either returns an http code something other than 200
|
163
|
+
or where the Zoho API sends back an explicit error code which <b>isn't</b> in the set
|
164
|
+
|
165
|
+
['4422', '5000']
|
166
|
+
|
167
|
+
a standard Ruby +RuntimeError+ exception is raised with the Zoho API message.
|
168
|
+
|
169
|
+
== Optimizations for Development and Testing
|
170
|
+
Set <tt>config.cache_fields = true</tt> in the configuration block. This caches \module field
|
171
|
+
lists and is useful during development and testing, to reduce total API calls during start up.
|
172
|
+
Defaults to false. We <b>do not</b> recommend use of this in production. The gem will need
|
173
|
+
write access to its own directory for this to work.
|
174
|
+
|
175
|
+
RubyZoho.configure do |config|
|
176
|
+
# Other stuff for initialization
|
177
|
+
config.cache_fields = true
|
178
|
+
end
|
179
|
+
|
180
|
+
== Idiosyncractic Behavior
|
181
|
+
From freedictionary.com
|
182
|
+
id·i·o·syn·cra·sy ( d - -s ng kr -s ). n. pl. id·i·o·syn·cra·sies.
|
183
|
+
1. A structural or behavioral characteristic peculiar to an individual or group.
|
184
|
+
|
185
|
+
|
186
|
+
The Zoho API is definitely opinionated. And we have yet to be able plumb the depths of its
|
187
|
+
views. If it behaves unexpectedly, try the Zoho forums before opening an issue here. It
|
188
|
+
just may be the way the API works...
|
189
|
+
|
190
|
+
An example of this is retrieving related records. You would think that since a Task can
|
191
|
+
be related to an Account or a Potential etc. that you should be able to retrieve it by
|
192
|
+
either the related \module's record id, which is stored with the Task. But no, can't be done.
|
155
193
|
|
156
|
-
==Bugs and
|
194
|
+
== Bugs and Enhancements
|
157
195
|
Please open an issue on GitHub. Or better yet, send in a pull request with the fix or enhancement!
|
158
196
|
|
159
|
-
|
197
|
+
=== Known Bugs
|
198
|
+
1. Caching is causing a problem with Quotes.
|
160
199
|
|
161
200
|
== Contributing to rubyzoho
|
162
201
|
|
@@ -169,12 +208,13 @@ Please open an issue on GitHub. Or better yet, send in a pull request with the f
|
|
169
208
|
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
170
209
|
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
171
210
|
|
211
|
+
---
|
212
|
+
|
172
213
|
== Trademarks
|
173
214
|
|
174
215
|
Zoho, the Zoho suite and related applications are owned, trademarked and copyrighted by the Zoho Corporation Pvt. Ltd.
|
175
216
|
This software is not associated in anyway with the Zoho Corporation Pvt. Ltd.
|
176
217
|
|
177
|
-
|
178
218
|
== Copyright
|
179
219
|
|
180
220
|
Copyright (c) 2013 amalc. Released under the MIT license. See LICENSE.txt for
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/lib/ruby_zoho.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
require 'zoho_api'
|
2
2
|
require 'api_utils'
|
3
|
+
require 'yaml'
|
3
4
|
|
4
5
|
|
5
6
|
module RubyZoho
|
6
7
|
|
7
8
|
class Configuration
|
8
|
-
attr_accessor :api, :api_key, :crm_modules
|
9
|
+
attr_accessor :api, :api_key, :cache_fields, :crm_modules
|
9
10
|
|
10
11
|
def initialize
|
11
12
|
self.api_key = nil
|
12
13
|
self.api = nil
|
14
|
+
self.cache_fields = false
|
13
15
|
self.crm_modules = nil
|
14
16
|
end
|
15
17
|
end
|
@@ -22,10 +24,25 @@ module RubyZoho
|
|
22
24
|
self.configuration ||= Configuration.new
|
23
25
|
yield(configuration) if block_given?
|
24
26
|
self.configuration.crm_modules ||= []
|
25
|
-
self.configuration.
|
27
|
+
self.configuration.crm_modules = %w[Accounts Calls Contacts Events Leads Potentials Tasks].concat(
|
28
|
+
self.configuration.crm_modules).uniq
|
29
|
+
self.configuration.api = init_api(self.configuration.api_key,
|
30
|
+
self.configuration.crm_modules, self.configuration.cache_fields)
|
31
|
+
RubyZoho::Crm.setup_classes()
|
26
32
|
end
|
27
33
|
|
28
|
-
|
34
|
+
def self.init_api(api_key, modules, cache_fields)
|
35
|
+
base_path = File.join(File.dirname(__FILE__), '..', 'spec', 'fixtures')
|
36
|
+
if File.exists?(File.join(base_path, 'fields.snapshot')) && cache_fields == true
|
37
|
+
fields = YAML.load(File.read(File.join(base_path, 'fields.snapshot')))
|
38
|
+
zoho = ZohoApi::Crm.new(api_key, modules, fields)
|
39
|
+
else
|
40
|
+
zoho = ZohoApi::Crm.new(api_key, modules)
|
41
|
+
fields = zoho.module_fields
|
42
|
+
File.open(File.join(base_path, 'fields.snapshot'), 'wb') { |file| file.write(fields.to_yaml) } if cache_fields == true
|
43
|
+
end
|
44
|
+
zoho
|
45
|
+
end
|
29
46
|
|
30
47
|
class Crm
|
31
48
|
|
@@ -44,6 +61,8 @@ module RubyZoho
|
|
44
61
|
m = e.message.slice(/`(.*?)=/)
|
45
62
|
unless m.nil?
|
46
63
|
m.gsub!('`', '')
|
64
|
+
m.gsub!('(', '')
|
65
|
+
m.gsub!(')', '')
|
47
66
|
RubyZoho::Crm.create_accessor(self.class, [m.chop])
|
48
67
|
end
|
49
68
|
retry_counter -= 1
|
@@ -52,7 +71,6 @@ module RubyZoho
|
|
52
71
|
self
|
53
72
|
end
|
54
73
|
|
55
|
-
|
56
74
|
def attr_writers
|
57
75
|
self.methods.grep(/\w=$/)
|
58
76
|
end
|
@@ -137,192 +155,42 @@ module RubyZoho
|
|
137
155
|
RubyZoho.configuration.api.update_record(Crm.module_name, id, object_attribute_hash)
|
138
156
|
end
|
139
157
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
def initialize(object_attribute_hash = {})
|
174
|
-
Crm.module_name = 'Contacts'
|
175
|
-
super
|
176
|
-
end
|
177
|
-
|
178
|
-
def self.all
|
179
|
-
Crm.module_name = 'Contacts'
|
180
|
-
super
|
181
|
-
end
|
182
|
-
|
183
|
-
def self.method_missing(meth, *args, &block)
|
184
|
-
Crm.module_name = 'Contacts'
|
185
|
-
super
|
186
|
-
end
|
187
|
-
|
188
|
-
def self.delete(id)
|
189
|
-
Crm.module_name = 'Contacts'
|
190
|
-
super
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
|
195
|
-
class Event < RubyZoho::Crm
|
196
|
-
include RubyZoho
|
197
|
-
attr_reader :fields
|
198
|
-
Crm.module_name = 'Events'
|
199
|
-
|
200
|
-
def initialize(object_attribute_hash = {})
|
201
|
-
Crm.module_name = 'Events'
|
202
|
-
super
|
203
|
-
end
|
204
|
-
|
205
|
-
def self.all
|
206
|
-
Crm.module_name = 'Events'
|
207
|
-
super
|
208
|
-
end
|
209
|
-
|
210
|
-
def self.delete(id)
|
211
|
-
Crm.module_name = 'Events'
|
212
|
-
super
|
213
|
-
end
|
214
|
-
|
215
|
-
def self.method_missing(meth, *args, &block)
|
216
|
-
Crm.module_name = 'Events'
|
217
|
-
super
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
class Lead < RubyZoho::Crm
|
222
|
-
include RubyZoho
|
223
|
-
attr_reader :fields
|
224
|
-
Crm.module_name = 'Leads'
|
225
|
-
|
226
|
-
def initialize(object_attribute_hash = {})
|
227
|
-
Crm.module_name = 'Leads'
|
228
|
-
super
|
229
|
-
end
|
230
|
-
|
231
|
-
def self.all
|
232
|
-
Crm.module_name = 'Leads'
|
233
|
-
super
|
234
|
-
end
|
235
|
-
|
236
|
-
def self.delete(id)
|
237
|
-
Crm.module_name = 'Leads'
|
238
|
-
super
|
239
|
-
end
|
240
|
-
|
241
|
-
def self.method_missing(meth, *args, &block)
|
242
|
-
Crm.module_name = 'Leads'
|
243
|
-
super
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
class Potential < RubyZoho::Crm
|
248
|
-
include RubyZoho
|
249
|
-
attr_reader :fields
|
250
|
-
Crm.module_name = 'Potentials'
|
251
|
-
|
252
|
-
def initialize(object_attribute_hash = {})
|
253
|
-
Crm.module_name = 'Potentials'
|
254
|
-
super
|
255
|
-
end
|
256
|
-
|
257
|
-
def self.all
|
258
|
-
Crm.module_name = 'Potentials'
|
259
|
-
super
|
260
|
-
end
|
261
|
-
|
262
|
-
def self.delete(id)
|
263
|
-
Crm.module_name = 'Potentials'
|
264
|
-
super
|
265
|
-
end
|
266
|
-
|
267
|
-
def self.method_missing(meth, *args, &block)
|
268
|
-
Crm.module_name = 'Potentials'
|
269
|
-
super
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
class Task < RubyZoho::Crm
|
274
|
-
include RubyZoho
|
275
|
-
attr_reader :fields
|
276
|
-
Crm.module_name = 'Tasks'
|
277
|
-
|
278
|
-
def initialize(object_attribute_hash = {})
|
279
|
-
Crm.module_name = 'Tasks'
|
280
|
-
super
|
281
|
-
end
|
282
|
-
|
283
|
-
def self.all
|
284
|
-
Crm.module_name = 'Tasks'
|
285
|
-
super
|
286
|
-
end
|
287
|
-
|
288
|
-
def self.delete(id)
|
289
|
-
Crm.module_name = 'Tasks'
|
290
|
-
super
|
291
|
-
end
|
292
|
-
|
293
|
-
def self.method_missing(meth, *args, &block)
|
294
|
-
Crm.module_name = 'Tasks'
|
295
|
-
super
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
class Quote < RubyZoho::Crm
|
300
|
-
include RubyZoho
|
301
|
-
attr_reader :fields
|
302
|
-
Crm.module_name = 'Quotes'
|
303
|
-
|
304
|
-
def initialize(object_attribute_hash = {})
|
305
|
-
Crm.module_name = 'Quotes'
|
306
|
-
super
|
307
|
-
end
|
308
|
-
|
309
|
-
def self.all
|
310
|
-
Crm.module_name = 'Quotes'
|
311
|
-
super
|
312
|
-
end
|
313
|
-
|
314
|
-
def self.delete(id)
|
315
|
-
Crm.module_name = 'Quotes'
|
316
|
-
super
|
317
|
-
end
|
318
|
-
|
319
|
-
def self.method_missing(meth, *args, &block)
|
320
|
-
Crm.module_name = 'Quotes'
|
321
|
-
super
|
158
|
+
def self.setup_classes
|
159
|
+
RubyZoho.configuration.crm_modules.each do |module_name|
|
160
|
+
klass_name = module_name.chop
|
161
|
+
c = Class.new(RubyZoho::Crm) do
|
162
|
+
include RubyZoho
|
163
|
+
attr_reader :fields
|
164
|
+
|
165
|
+
def initialize(object_attribute_hash = {})
|
166
|
+
klass = self.class.to_s
|
167
|
+
Crm.module_name = klass.slice(klass.rindex('::') + 2, klass.length) + 's'
|
168
|
+
super
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.all
|
172
|
+
klass = self.to_s
|
173
|
+
Crm.module_name = klass.slice(klass.rindex('::') + 2, klass.length) + 's'
|
174
|
+
super
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.delete(id)
|
178
|
+
klass = self.to_s
|
179
|
+
Crm.module_name = klass.slice(klass.rindex('::') + 2, klass.length) + 's'
|
180
|
+
super
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.method_missing(meth, *args, &block)
|
184
|
+
klass = self.to_s
|
185
|
+
Crm.module_name = klass.slice(klass.rindex('::') + 2, klass.length) + 's'
|
186
|
+
super
|
187
|
+
end
|
188
|
+
end
|
189
|
+
const_set(klass_name, c)
|
322
190
|
end
|
323
191
|
end
|
324
192
|
|
325
|
-
|
193
|
+
c = Class.new(RubyZoho::Crm) do
|
326
194
|
def initialize(object_attribute_hash = {})
|
327
195
|
Crm.module_name = 'Users'
|
328
196
|
super
|
@@ -353,6 +221,7 @@ module RubyZoho
|
|
353
221
|
end
|
354
222
|
end
|
355
223
|
|
356
|
-
|
224
|
+
Kernel.const_set 'User', c
|
357
225
|
|
226
|
+
end
|
358
227
|
end
|
data/lib/zoho_api.rb
CHANGED
@@ -24,10 +24,10 @@ module ZohoApi
|
|
24
24
|
|
25
25
|
attr_reader :auth_token, :module_fields
|
26
26
|
|
27
|
-
def initialize(auth_token, modules)
|
27
|
+
def initialize(auth_token, modules, fields = nil)
|
28
28
|
@auth_token = auth_token
|
29
29
|
@modules = %w(Accounts Contacts Events Leads Potentials Tasks Users).concat(modules).uniq
|
30
|
-
@module_fields = reflect_module_fields
|
30
|
+
@module_fields = fields.nil? ? reflect_module_fields : fields
|
31
31
|
end
|
32
32
|
|
33
33
|
def add_record(module_name, fields_values_hash)
|
@@ -35,6 +35,7 @@ module ZohoApi
|
|
35
35
|
element = x.add_element module_name
|
36
36
|
row = element.add_element 'row', { 'no' => '1'}
|
37
37
|
fields_values_hash.each_pair { |k, v| add_field(row, ApiUtils.symbol_to_string(k), v) }
|
38
|
+
#pp x.to_s
|
38
39
|
r = self.class.post(create_url(module_name, 'insertRecords'),
|
39
40
|
:query => { :newFormat => 1, :authtoken => @auth_token,
|
40
41
|
:scope => 'crmapi', :xmlData => x },
|
@@ -56,8 +57,6 @@ module ZohoApi
|
|
56
57
|
:scope => 'crmapi',
|
57
58
|
:id => record_id, :content => File.open(file_path) },
|
58
59
|
:headers => { 'Content-length' => '0' })
|
59
|
-
pp r.code
|
60
|
-
pp r.body
|
61
60
|
raise(RuntimeError, 'Attaching file failed.', r.body.to_s) unless r.response.code == '200'
|
62
61
|
r.code
|
63
62
|
end
|
@@ -65,7 +64,6 @@ module ZohoApi
|
|
65
64
|
def add_file(module_name, record_id, file_path)
|
66
65
|
url = URI.parse(create_url(module_name, 'uploadFile'))
|
67
66
|
r = nil
|
68
|
-
pp record_id
|
69
67
|
mime_type = (MIME::Types.type_for(file_path)[0] || MIME::Types["application/octet-stream"][0])
|
70
68
|
f = File.open(file_path)
|
71
69
|
req = Net::HTTP::Post::Multipart.new url.path,
|
@@ -74,9 +72,7 @@ module ZohoApi
|
|
74
72
|
'content' => UploadIO.new(f, mime_type, File.basename(file_path)) }
|
75
73
|
http = Net::HTTP.new(url.host, url.port)
|
76
74
|
http.use_ssl = true
|
77
|
-
pp req.to_hash
|
78
75
|
r = http.start { |http| http.request(req) }
|
79
|
-
pp r.body.to_s
|
80
76
|
(r.nil? or r.body.nil? or r.body.empty?) ? nil : REXML::Document.new(r.body).to_s
|
81
77
|
end
|
82
78
|
|
@@ -129,12 +125,14 @@ module ZohoApi
|
|
129
125
|
|
130
126
|
def find_records(module_name, field, condition, value)
|
131
127
|
sc_field = ApiUtils.symbol_to_string(field)
|
132
|
-
|
128
|
+
return find_record_by_related_id(module_name, sc_field, value) if related_id?(module_name, sc_field)
|
129
|
+
primary_key?(module_name, sc_field) == false ? find_record_by_field(module_name, sc_field, condition, value) :
|
133
130
|
find_record_by_id(module_name, value)
|
134
131
|
end
|
135
132
|
|
136
133
|
def find_record_by_field(module_name, sc_field, condition, value)
|
137
|
-
|
134
|
+
field = sc_field.rindex('id') ? sc_field.downcase : sc_field
|
135
|
+
search_condition = '(' + field + '|' + condition + '|' + value + ')'
|
138
136
|
r = self.class.get(create_url("#{module_name}", 'getSearchRecords'),
|
139
137
|
:query => {:newFormat => 1, :authtoken => @auth_token, :scope => 'crmapi',
|
140
138
|
:selectColumns => 'All', :searchCondition => search_condition,
|
@@ -154,10 +152,57 @@ module ZohoApi
|
|
154
152
|
to_hash(x)
|
155
153
|
end
|
156
154
|
|
155
|
+
def find_record_by_related_id(module_name, sc_field, value)
|
156
|
+
raise(RuntimeError, "[RubyZoho] Not a valid query field #{sc_field} for module #{module_name}") unless
|
157
|
+
valid_related?(module_name, sc_field)
|
158
|
+
field = sc_field.downcase
|
159
|
+
r = self.class.get(create_url("#{module_name}", 'getSearchRecordsByPDC'),
|
160
|
+
:query => { :newFormat => 1, :authtoken => @auth_token, :scope => 'crmapi',
|
161
|
+
:selectColumns => 'All', :version => 2, :searchColumn => field,
|
162
|
+
:searchValue => value})
|
163
|
+
check_for_errors(r)
|
164
|
+
x = REXML::Document.new(r.body).elements.to_a("/response/result/#{module_name}/row")
|
165
|
+
to_hash(x)
|
166
|
+
end
|
167
|
+
|
168
|
+
def valid_related?(module_name, field)
|
169
|
+
valid_relationships = {
|
170
|
+
'Leads' => %w(email),
|
171
|
+
'Accounts' => %w(accountid accountname),
|
172
|
+
'Contacts' => %w(contactid accountid vendorid email),
|
173
|
+
'Potentials' => %w(potentialid accountid campaignid contactid potentialname),
|
174
|
+
'Campaigns' => %w(campaignid campaignname),
|
175
|
+
'Cases' => %w(caseid productid accountid potentialid),
|
176
|
+
'Solutions' => %w(solutionid productid),
|
177
|
+
'Products' => %w(productid vendorid productname),
|
178
|
+
'Purchase Order' => %w(purchaseorderid contactid vendorid),
|
179
|
+
'Quotes' => %w(quoteid potentialid accountid contactid),
|
180
|
+
'Sales Orders' => %w(salesorderid potentialid accountid contactid quoteid),
|
181
|
+
'Invoices' => %w(invoiceid accountid salesorderid contactid),
|
182
|
+
'Vendors' => %w(vendorid vendorname),
|
183
|
+
'Tasks' => %w(taskid),
|
184
|
+
'Events' => %w(eventid),
|
185
|
+
'Notes' => %w(notesid)
|
186
|
+
}
|
187
|
+
valid_relationships[module_name].index(field.downcase)
|
188
|
+
end
|
189
|
+
|
190
|
+
def related_id?(module_name, field_name)
|
191
|
+
field = field_name.to_s
|
192
|
+
return false if field.rindex('id').nil?
|
193
|
+
return false if %w[Calls Events Tasks].index(module_name) && field_name.downcase == 'activityid'
|
194
|
+
field.downcase.gsub('id', '') != module_name.chop.downcase
|
195
|
+
end
|
196
|
+
|
157
197
|
def method_name?(n)
|
158
198
|
return /[@$"]/ !~ n.inspect
|
159
199
|
end
|
160
200
|
|
201
|
+
def primary_key?(module_name, field_name)
|
202
|
+
return true if %w[Calls Events Tasks].index(module_name) && field_name.downcase == 'activityid'
|
203
|
+
field_name.downcase.gsub('id', '') == module_name.chop.downcase
|
204
|
+
end
|
205
|
+
|
161
206
|
def reflect_module_fields
|
162
207
|
@modules.each { |m| fields(m) }
|
163
208
|
@@module_fields
|
@@ -168,11 +213,8 @@ module ZohoApi
|
|
168
213
|
:query => { :newFormat => 1, :authtoken => @auth_token, :scope => 'crmapi',
|
169
214
|
:parentModule => parent_module, :id => parent_record_id})
|
170
215
|
|
171
|
-
pp r.body
|
172
216
|
x = REXML::Document.new(r.body).elements.to_a("/response/result/#{parent_module}/row")
|
173
|
-
|
174
|
-
pp check_for_errors(r)
|
175
|
-
return nil unless check_for_errors(r).nil?
|
217
|
+
check_for_errors(r)
|
176
218
|
end
|
177
219
|
|
178
220
|
def some(module_name, index = 1, number_of_records = nil)
|
data/rubyzoho.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "rubyzoho"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["amalc"]
|
12
|
-
s.date = "2013-02-
|
12
|
+
s.date = "2013-02-19"
|
13
13
|
s.description = ""
|
14
14
|
s.email = ""
|
15
15
|
s.extra_rdoc_files = [
|
@@ -22,7 +22,6 @@ Gem::Specification.new do |s|
|
|
22
22
|
".rvmrc",
|
23
23
|
".travis.yml",
|
24
24
|
"Gemfile",
|
25
|
-
"Gemfile.lock",
|
26
25
|
"LICENSE.txt",
|
27
26
|
"README.rdoc",
|
28
27
|
"Rakefile",
|
@@ -30,7 +29,6 @@ Gem::Specification.new do |s|
|
|
30
29
|
"lib/api_utils.rb",
|
31
30
|
"lib/ruby_zoho.rb",
|
32
31
|
"lib/zoho_api.rb",
|
33
|
-
"rubyzoho-0.1.1.gem",
|
34
32
|
"rubyzoho.gemspec",
|
35
33
|
"spec/api_utils_spec.rb",
|
36
34
|
"spec/fixtures/sample.pdf",
|
@@ -46,49 +44,46 @@ Gem::Specification.new do |s|
|
|
46
44
|
s.homepage = "http://github.com/amalc/rubyzoho"
|
47
45
|
s.licenses = ["MIT"]
|
48
46
|
s.require_paths = ["lib"]
|
49
|
-
s.rubygems_version = "1.8.
|
47
|
+
s.rubygems_version = "1.8.24"
|
50
48
|
s.summary = "A set of Ruby classes supporting the ActiveRecord lifecycle for the Zoho API."
|
51
49
|
|
52
50
|
if s.respond_to? :specification_version then
|
53
51
|
s.specification_version = 3
|
54
52
|
|
55
53
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
56
|
-
s.add_runtime_dependency(%q<httmultiparty>, [">= 0"])
|
57
|
-
s.add_runtime_dependency(%q<roxml>, [">=
|
58
|
-
s.
|
59
|
-
s.add_development_dependency(%q<
|
54
|
+
s.add_runtime_dependency(%q<httmultiparty>, [">= 0.3.8"])
|
55
|
+
s.add_runtime_dependency(%q<roxml>, [">= 3.3.1"])
|
56
|
+
s.add_runtime_dependency(%q<multipart-post>, [">= 0"])
|
57
|
+
s.add_development_dependency(%q<bundler>, [">= 1.2"])
|
58
|
+
s.add_development_dependency(%q<cucumber>, [">= 1.2.1"])
|
60
59
|
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
61
|
-
s.add_development_dependency(%q<relish>, [">= 0"])
|
62
|
-
s.add_development_dependency(%q<rdoc>, [">=
|
60
|
+
s.add_development_dependency(%q<relish>, [">= 0.6"])
|
61
|
+
s.add_development_dependency(%q<rdoc>, [">= 3.12.1"])
|
63
62
|
s.add_development_dependency(%q<rspec>, [">= 2.12.0"])
|
64
|
-
s.add_development_dependency(%q<
|
65
|
-
s.add_development_dependency(%q<xml-simple>, [">= 0"])
|
66
|
-
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
63
|
+
s.add_development_dependency(%q<xml-simple>, [">= 1.1.2"])
|
67
64
|
else
|
68
|
-
s.add_dependency(%q<httmultiparty>, [">= 0"])
|
69
|
-
s.add_dependency(%q<roxml>, [">=
|
70
|
-
s.add_dependency(%q<
|
71
|
-
s.add_dependency(%q<
|
65
|
+
s.add_dependency(%q<httmultiparty>, [">= 0.3.8"])
|
66
|
+
s.add_dependency(%q<roxml>, [">= 3.3.1"])
|
67
|
+
s.add_dependency(%q<multipart-post>, [">= 0"])
|
68
|
+
s.add_dependency(%q<bundler>, [">= 1.2"])
|
69
|
+
s.add_dependency(%q<cucumber>, [">= 1.2.1"])
|
72
70
|
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
73
|
-
s.add_dependency(%q<relish>, [">= 0"])
|
74
|
-
s.add_dependency(%q<rdoc>, [">=
|
71
|
+
s.add_dependency(%q<relish>, [">= 0.6"])
|
72
|
+
s.add_dependency(%q<rdoc>, [">= 3.12.1"])
|
75
73
|
s.add_dependency(%q<rspec>, [">= 2.12.0"])
|
76
|
-
s.add_dependency(%q<
|
77
|
-
s.add_dependency(%q<xml-simple>, [">= 0"])
|
78
|
-
s.add_dependency(%q<simplecov>, [">= 0"])
|
74
|
+
s.add_dependency(%q<xml-simple>, [">= 1.1.2"])
|
79
75
|
end
|
80
76
|
else
|
81
|
-
s.add_dependency(%q<httmultiparty>, [">= 0"])
|
82
|
-
s.add_dependency(%q<roxml>, [">=
|
83
|
-
s.add_dependency(%q<
|
84
|
-
s.add_dependency(%q<
|
77
|
+
s.add_dependency(%q<httmultiparty>, [">= 0.3.8"])
|
78
|
+
s.add_dependency(%q<roxml>, [">= 3.3.1"])
|
79
|
+
s.add_dependency(%q<multipart-post>, [">= 0"])
|
80
|
+
s.add_dependency(%q<bundler>, [">= 1.2"])
|
81
|
+
s.add_dependency(%q<cucumber>, [">= 1.2.1"])
|
85
82
|
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
86
|
-
s.add_dependency(%q<relish>, [">= 0"])
|
87
|
-
s.add_dependency(%q<rdoc>, [">=
|
83
|
+
s.add_dependency(%q<relish>, [">= 0.6"])
|
84
|
+
s.add_dependency(%q<rdoc>, [">= 3.12.1"])
|
88
85
|
s.add_dependency(%q<rspec>, [">= 2.12.0"])
|
89
|
-
s.add_dependency(%q<
|
90
|
-
s.add_dependency(%q<xml-simple>, [">= 0"])
|
91
|
-
s.add_dependency(%q<simplecov>, [">= 0"])
|
86
|
+
s.add_dependency(%q<xml-simple>, [">= 1.1.2"])
|
92
87
|
end
|
93
88
|
end
|
94
89
|
|
data/spec/ruby_zoho_spec.rb
CHANGED
@@ -14,6 +14,7 @@ describe RubyZoho::Crm do
|
|
14
14
|
#config.api_key = 'e194b2951fb238e26bc096de9d0cf5f8'
|
15
15
|
config.api_key = '62cedfe9427caef8afb9ea3b5bf68154'
|
16
16
|
config.crm_modules = %w(Quotes)
|
17
|
+
config.cache_fields = false
|
17
18
|
end
|
18
19
|
#r = RubyZoho::Crm::Contact.find_by_last_name('Smithereens')
|
19
20
|
#r.each { |m| RubyZoho::Crm::Contact.delete(m.contactid) } unless r.nil?
|
@@ -92,9 +93,14 @@ describe RubyZoho::Crm do
|
|
92
93
|
c.attr_writers.count.should be >= 14
|
93
94
|
end
|
94
95
|
|
96
|
+
it 'should get a list of attr_writers for tasks' do
|
97
|
+
c = RubyZoho::Crm::Task.new
|
98
|
+
c.attr_writers.count.should be >= 14
|
99
|
+
end
|
100
|
+
|
95
101
|
it 'should get a list of attr_writers for quotes' do
|
96
102
|
c = RubyZoho::Crm::Quote.new
|
97
|
-
c.attr_writers.count.should be >= 18
|
103
|
+
c.attr_writers.count.should be >= 18 unless c.nil?
|
98
104
|
end
|
99
105
|
|
100
106
|
it 'should get a list of accounts' do
|
@@ -103,6 +109,12 @@ describe RubyZoho::Crm do
|
|
103
109
|
r.map { |r| r.class.should eq(RubyZoho::Crm::Account) }
|
104
110
|
end
|
105
111
|
|
112
|
+
it 'should get a list of calls' do
|
113
|
+
r = RubyZoho::Crm::Call.all
|
114
|
+
r.count.should be > 1
|
115
|
+
r.map { |r| r.class.should eq(RubyZoho::Crm::Call) }
|
116
|
+
end
|
117
|
+
|
106
118
|
it 'should get a list of contacts' do
|
107
119
|
r = RubyZoho::Crm::Contact.all
|
108
120
|
r.count.should be > 1
|
@@ -149,12 +161,6 @@ describe RubyZoho::Crm do
|
|
149
161
|
r.each { |c| RubyZoho::Crm::Contact.delete(c.contactid) }
|
150
162
|
end
|
151
163
|
|
152
|
-
it 'should sort contact records' do
|
153
|
-
r = RubyZoho::Crm::Contact.all
|
154
|
-
sorted = r.sort {|a, b| a.last_name <=> b.last_name }
|
155
|
-
sorted.collect { |c| c.last_name }.should_not eq(nil)
|
156
|
-
end
|
157
|
-
|
158
164
|
it 'should save a lead record' do
|
159
165
|
l = RubyZoho::Crm::Lead.new(
|
160
166
|
:first_name => 'Raj',
|
@@ -167,21 +173,80 @@ describe RubyZoho::Crm do
|
|
167
173
|
r.each { |c| RubyZoho::Crm::Lead.delete(c.leadid) }
|
168
174
|
end
|
169
175
|
|
170
|
-
it 'should save a potential record' do
|
176
|
+
it 'should save and retrieve a potential record' do
|
171
177
|
accounts = RubyZoho::Crm::Account.all
|
172
|
-
|
178
|
+
h = {
|
173
179
|
:potential_name => 'A very big potential INDEED!!!!!!!!!!!!!',
|
174
180
|
:accountid => accounts.first.accountid,
|
175
181
|
:account_name => accounts.first.account_name,
|
176
182
|
:closing_date => '1/1/2014',
|
177
183
|
:type => 'New Business',
|
178
|
-
:stage => 'Needs Analysis'
|
184
|
+
:stage => 'Needs Analysis'}
|
185
|
+
r = RubyZoho::Crm::Potential.find_by_potential_name(h[:potential_name])
|
186
|
+
r.each { |c| RubyZoho::Crm::Potential.delete(c.potentialid) } unless r.nil?
|
187
|
+
p = RubyZoho::Crm::Potential.new(h)
|
179
188
|
p.save
|
180
189
|
r = RubyZoho::Crm::Potential.find_by_potential_name(p.potential_name)
|
181
|
-
r.first.potential_name.should eq(
|
190
|
+
r.first.potential_name.should eq(h[:potential_name])
|
191
|
+
potential = RubyZoho::Crm::Potential.find_by_potentialid(r.first.potentialid)
|
192
|
+
potential.first.potentialid.should eq(r.first.potentialid)
|
193
|
+
p_by_account_id = RubyZoho::Crm::Potential.find_by_accountid(accounts.first.accountid)
|
194
|
+
p_found = p_by_account_id.map { |pn| pn if pn.potential_name == h[:potential_name]}.compact
|
195
|
+
p_found.first.potentialid.should eq(r.first.potentialid)
|
182
196
|
r.each { |c| RubyZoho::Crm::Potential.delete(c.potentialid) }
|
183
197
|
end
|
184
198
|
|
199
|
+
it 'should save and retrieve a task record' do
|
200
|
+
accounts = RubyZoho::Crm::Account.all
|
201
|
+
h = {
|
202
|
+
:subject => 'Test Task',
|
203
|
+
:due_date => Date.today.to_s + '23:59',
|
204
|
+
:semodule => 'Accounts',
|
205
|
+
:relatedtoid => accounts.first.accountid,
|
206
|
+
:related_to => accounts.first.account_name,
|
207
|
+
:priority => 'Low' }
|
208
|
+
r = RubyZoho::Crm::Task.find_by_subject(h[:subject])
|
209
|
+
r.each { |t| RubyZoho::Crm::Task.delete(t.activityid) } unless r.nil?
|
210
|
+
t = RubyZoho::Crm::Task.new(h)
|
211
|
+
t.save
|
212
|
+
r = RubyZoho::Crm::Task.find_by_subject(h[:subject])
|
213
|
+
r.first.subject.should eq(h[:subject])
|
214
|
+
tasks = RubyZoho::Crm::Task.find_by_activityid(r.first.activityid)
|
215
|
+
tasks.first.activityid.should eq(r.first.activityid)
|
216
|
+
r.each { |c| RubyZoho::Crm::Task.delete(c.activityid) }
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should save an event record' do
|
220
|
+
pending
|
221
|
+
#accounts = RubyZoho::Crm::Account.all
|
222
|
+
#pp a = accounts.first
|
223
|
+
#events = RubyZoho::Crm::Event.all
|
224
|
+
#pp ev = events.first
|
225
|
+
#RubyZoho::Crm::Event.update(
|
226
|
+
# :id => ev.activityid,
|
227
|
+
# :subject => "Hello Dolly #{Time.now}.to_s"
|
228
|
+
#)
|
229
|
+
pp e = RubyZoho::Crm::Event.new(
|
230
|
+
:event_owner => 'Wayne Giles',
|
231
|
+
:smownerid => '748054000000056023',
|
232
|
+
:start_datetime => '2013-02-16 16:00:00',
|
233
|
+
:end_datetime => '2014-02-16 16:00:00',
|
234
|
+
:subject => 'Test Event',
|
235
|
+
:related_to => "Potential One",
|
236
|
+
:relatedtoid => '748054000000123057',
|
237
|
+
:semodule => "Potentials",
|
238
|
+
:contact_name => "Wayne Smith",
|
239
|
+
:contactid => "748054000000097043"
|
240
|
+
)
|
241
|
+
e.save
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should sort contact records' do
|
245
|
+
r = RubyZoho::Crm::Contact.all
|
246
|
+
sorted = r.sort {|a, b| a.last_name <=> b.last_name }
|
247
|
+
sorted.collect { |c| c.last_name }.should_not eq(nil)
|
248
|
+
end
|
249
|
+
|
185
250
|
it 'should update a lead record' do
|
186
251
|
l = RubyZoho::Crm::Lead.new(
|
187
252
|
:first_name => 'Raj',
|
data/spec/zoho_api_spec.rb
CHANGED
@@ -3,6 +3,7 @@ $:.unshift File.join('..', File.dirname(__FILE__), 'lib')
|
|
3
3
|
require 'spec_helper'
|
4
4
|
require 'zoho_api'
|
5
5
|
require 'xmlsimple'
|
6
|
+
require 'yaml'
|
6
7
|
|
7
8
|
describe ZohoApi do
|
8
9
|
|
@@ -18,6 +19,17 @@ describe ZohoApi do
|
|
18
19
|
@zoho.delete_record('Contacts', c[0][:contactid]) unless c == []
|
19
20
|
end
|
20
21
|
|
22
|
+
def init_api(api_key, base_path, modules)
|
23
|
+
if File.exists?(File.join(base_path, 'fields.snapshot'))
|
24
|
+
fields = YAML.load(File.read(File.join(base_path, 'fields.snapshot')))
|
25
|
+
zoho = ZohoApi::Crm.new(api_key, modules, fields)
|
26
|
+
else
|
27
|
+
zoho = ZohoApi::Crm.new(api_key, modules)
|
28
|
+
fields = zoho.module_fields
|
29
|
+
File.open(File.join(base_path, 'fields.snapshot'), 'wb') { |file| file.write(fields.to_yaml) }
|
30
|
+
end
|
31
|
+
zoho
|
32
|
+
end
|
21
33
|
|
22
34
|
before(:all) do
|
23
35
|
base_path = File.join(File.dirname(__FILE__), 'fixtures')
|
@@ -27,9 +39,9 @@ describe ZohoApi do
|
|
27
39
|
@sample_pdf = File.join(base_path, 'sample.pdf')
|
28
40
|
modules = ['Accounts', 'Contacts', 'Events', 'Leads', 'Tasks', 'Potentials']
|
29
41
|
#api_key = '783539943dc16d7005b0f3b78367d5d2'
|
30
|
-
|
31
|
-
api_key = '62cedfe9427caef8afb9ea3b5bf68154'
|
32
|
-
@zoho =
|
42
|
+
api_key = 'e194b2951fb238e26bc096de9d0cf5f8'
|
43
|
+
#api_key = '62cedfe9427caef8afb9ea3b5bf68154'
|
44
|
+
@zoho = init_api(api_key, base_path, modules)
|
33
45
|
@h_smith = { :first_name => 'Robert',
|
34
46
|
:last_name => 'Smith',
|
35
47
|
:email => 'rsmith@smithereens.com',
|
@@ -37,8 +49,8 @@ describe ZohoApi do
|
|
37
49
|
:phone => '13452129087',
|
38
50
|
:mobile => '12341238790'
|
39
51
|
}
|
40
|
-
|
41
|
-
|
52
|
+
contacts = @zoho.find_records('Contacts', :email, '=', @h_smith[:email])
|
53
|
+
contacts.each { |c| @zoho.delete_record('Contacts', c[:contactid]) } unless contacts.nil?
|
42
54
|
end
|
43
55
|
|
44
56
|
it 'should add a new contact' do
|
@@ -48,6 +60,26 @@ describe ZohoApi do
|
|
48
60
|
contacts.should_not eq(nil)
|
49
61
|
contacts.count.should eq(1)
|
50
62
|
end
|
63
|
+
|
64
|
+
it 'should add a new event' do
|
65
|
+
pending
|
66
|
+
h = { :event_owner => 'Wayne Giles',
|
67
|
+
:smownerid => '748054000000056023',
|
68
|
+
:start_datetime => '2013-02-16 16:00:00',
|
69
|
+
:end_datetime => '2014-02-16 16:00:00',
|
70
|
+
:subject => 'Test Event',
|
71
|
+
:related_to => 'Potential One',
|
72
|
+
:relatedtoid => '748054000000123057',
|
73
|
+
:semodule => 'Potentials',
|
74
|
+
:contact_name => 'Wayne Smith',
|
75
|
+
:contactid => '748054000000097043' }
|
76
|
+
@zoho.add_record('Events', h)
|
77
|
+
events = @zoho.some('Events')
|
78
|
+
pp events
|
79
|
+
#@zoho.delete_record('Contacts', contacts[0][:contactid])
|
80
|
+
events.should_not eq(nil)
|
81
|
+
events.count.should eq(1)
|
82
|
+
end
|
51
83
|
|
52
84
|
it 'should attach a file to a contact record' do
|
53
85
|
pending
|
@@ -80,6 +112,33 @@ describe ZohoApi do
|
|
80
112
|
delete_dummy_contact
|
81
113
|
end
|
82
114
|
|
115
|
+
it 'should find by a potential by name, id and related id' do
|
116
|
+
accounts = @zoho.some('Accounts')
|
117
|
+
p = {
|
118
|
+
:potential_name => 'A very big potential INDEED!!!!!!!!!!!!!',
|
119
|
+
:accountid => accounts.first[:accountid],
|
120
|
+
:account_name => accounts.first[:account_name],
|
121
|
+
:closing_date => '1/1/2014',
|
122
|
+
:type => 'New Business',
|
123
|
+
:stage => 'Needs Analysis'
|
124
|
+
}
|
125
|
+
potentials = @zoho.find_records('Potentials', :potential_name, '=', p[:potential_name])
|
126
|
+
potentials.map { |r| @zoho.delete_record('Potentials', r[:potentialid])} unless potentials.nil?
|
127
|
+
|
128
|
+
@zoho.add_record('Potentials', p)
|
129
|
+
p1 = @zoho.find_records('Potentials', :potential_name, '=', p[:potential_name])
|
130
|
+
p1.should_not eq(nil)
|
131
|
+
|
132
|
+
p2 = @zoho.find_records('Potentials', :potentialid, '=', p1.first[:potentialid])
|
133
|
+
p2.first[:potentialid].should eq(p1.first[:potentialid])
|
134
|
+
|
135
|
+
p_related = @zoho.find_records('Potentials', :accountid, '=', p[:accountid])
|
136
|
+
p_related.first[:accountid].should eq(p[:accountid])
|
137
|
+
|
138
|
+
potentials = @zoho.find_records('Potentials', :potential_name, '=', p[:potential_name])
|
139
|
+
potentials.map { |r| @zoho.delete_record('Potentials', r[:potentialid])} unless potentials.nil?
|
140
|
+
end
|
141
|
+
|
83
142
|
it 'should get a list of fields for a module' do
|
84
143
|
r = @zoho.fields('Accounts')
|
85
144
|
r.count.should >= 30
|
@@ -116,26 +175,54 @@ describe ZohoApi do
|
|
116
175
|
related = @zoho.related_records('Accounts', r[:accountid], 'Attachments')
|
117
176
|
end
|
118
177
|
|
178
|
+
it 'should return calls' do
|
179
|
+
r = @zoho.some('Calls').first
|
180
|
+
r.should_not eq(nil)
|
181
|
+
end
|
182
|
+
|
119
183
|
it 'should return events' do
|
120
184
|
r = @zoho.some('Events').first
|
121
185
|
r.should_not eq(nil)
|
122
186
|
end
|
123
187
|
|
188
|
+
it 'should return tasks' do
|
189
|
+
r = @zoho.some('Tasks').first
|
190
|
+
r.should_not eq(nil)
|
191
|
+
end
|
192
|
+
|
124
193
|
it 'should return users' do
|
125
194
|
r = @zoho.users
|
126
195
|
r.should_not eq(nil)
|
127
196
|
end
|
128
197
|
|
198
|
+
it 'should test for a primary key' do
|
199
|
+
@zoho.primary_key?('Accounts', 'accountid').should eq(true)
|
200
|
+
@zoho.primary_key?('Accounts', 'potentialid').should eq(false)
|
201
|
+
@zoho.primary_key?('Accounts', 'Potential Name').should eq(false)
|
202
|
+
@zoho.primary_key?('Accounts', 'Account Name').should eq(false)
|
203
|
+
@zoho.primary_key?('Accounts', 'account_name').should eq(false)
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should test for a related id' do
|
207
|
+
@zoho.related_id?('Potentials', 'Account Name').should eq(false)
|
208
|
+
@zoho.related_id?('Potentials', 'Accountid').should eq(true)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'should test for a valid related field' do
|
212
|
+
@zoho.valid_related?('Accounts', 'accountid').should_not eq(nil)
|
213
|
+
@zoho.valid_related?('Notes', 'notesid').should_not eq(nil)
|
214
|
+
@zoho.valid_related?('Accounts', 'email').should eq(nil)
|
215
|
+
end
|
216
|
+
|
129
217
|
it 'should do a full CRUD lifecycle on tasks' do
|
130
|
-
pending
|
131
218
|
mod_name = 'Tasks'
|
132
219
|
fields = @zoho.fields(mod_name)
|
133
220
|
fields.count >= 10
|
134
221
|
fields.index(:task_owner).should_not eq(nil)
|
135
|
-
@zoho.add_record(mod_name, {:task_owner => 'Task Owner', :subject => 'Test Task', :due_date => '1/1
|
136
|
-
r = @zoho.
|
137
|
-
pp r
|
222
|
+
@zoho.add_record(mod_name, {:task_owner => 'Task Owner', :subject => 'Test Task', :due_date => '2100/1/1'})
|
223
|
+
r = @zoho.find_record_by_field('Tasks', 'Subject', '=', 'Test Task')
|
138
224
|
r.should_not eq(nil)
|
225
|
+
r.map { |t| @zoho.delete_record('Tasks', t[:activityid]) }
|
139
226
|
end
|
140
227
|
|
141
228
|
it 'should update a contact' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubyzoho
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httmultiparty
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 0.3.8
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,9 +26,25 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 0.3.8
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: roxml
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.3.1
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.3.1
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: multipart-post
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
33
49
|
none: false
|
34
50
|
requirements:
|
@@ -50,7 +66,7 @@ dependencies:
|
|
50
66
|
requirements:
|
51
67
|
- - ! '>='
|
52
68
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
69
|
+
version: '1.2'
|
54
70
|
type: :development
|
55
71
|
prerelease: false
|
56
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +74,7 @@ dependencies:
|
|
58
74
|
requirements:
|
59
75
|
- - ! '>='
|
60
76
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
77
|
+
version: '1.2'
|
62
78
|
- !ruby/object:Gem::Dependency
|
63
79
|
name: cucumber
|
64
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +82,7 @@ dependencies:
|
|
66
82
|
requirements:
|
67
83
|
- - ! '>='
|
68
84
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
85
|
+
version: 1.2.1
|
70
86
|
type: :development
|
71
87
|
prerelease: false
|
72
88
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +90,7 @@ dependencies:
|
|
74
90
|
requirements:
|
75
91
|
- - ! '>='
|
76
92
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
93
|
+
version: 1.2.1
|
78
94
|
- !ruby/object:Gem::Dependency
|
79
95
|
name: jeweler
|
80
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,7 +114,7 @@ dependencies:
|
|
98
114
|
requirements:
|
99
115
|
- - ! '>='
|
100
116
|
- !ruby/object:Gem::Version
|
101
|
-
version: '0'
|
117
|
+
version: '0.6'
|
102
118
|
type: :development
|
103
119
|
prerelease: false
|
104
120
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -106,7 +122,7 @@ dependencies:
|
|
106
122
|
requirements:
|
107
123
|
- - ! '>='
|
108
124
|
- !ruby/object:Gem::Version
|
109
|
-
version: '0'
|
125
|
+
version: '0.6'
|
110
126
|
- !ruby/object:Gem::Dependency
|
111
127
|
name: rdoc
|
112
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,7 +130,7 @@ dependencies:
|
|
114
130
|
requirements:
|
115
131
|
- - ! '>='
|
116
132
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
133
|
+
version: 3.12.1
|
118
134
|
type: :development
|
119
135
|
prerelease: false
|
120
136
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -122,7 +138,7 @@ dependencies:
|
|
122
138
|
requirements:
|
123
139
|
- - ! '>='
|
124
140
|
- !ruby/object:Gem::Version
|
125
|
-
version:
|
141
|
+
version: 3.12.1
|
126
142
|
- !ruby/object:Gem::Dependency
|
127
143
|
name: rspec
|
128
144
|
requirement: !ruby/object:Gem::Requirement
|
@@ -139,22 +155,6 @@ dependencies:
|
|
139
155
|
- - ! '>='
|
140
156
|
- !ruby/object:Gem::Version
|
141
157
|
version: 2.12.0
|
142
|
-
- !ruby/object:Gem::Dependency
|
143
|
-
name: shoulda
|
144
|
-
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
|
-
requirements:
|
147
|
-
- - ! '>='
|
148
|
-
- !ruby/object:Gem::Version
|
149
|
-
version: '0'
|
150
|
-
type: :development
|
151
|
-
prerelease: false
|
152
|
-
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
|
-
requirements:
|
155
|
-
- - ! '>='
|
156
|
-
- !ruby/object:Gem::Version
|
157
|
-
version: '0'
|
158
158
|
- !ruby/object:Gem::Dependency
|
159
159
|
name: xml-simple
|
160
160
|
requirement: !ruby/object:Gem::Requirement
|
@@ -162,7 +162,7 @@ dependencies:
|
|
162
162
|
requirements:
|
163
163
|
- - ! '>='
|
164
164
|
- !ruby/object:Gem::Version
|
165
|
-
version:
|
165
|
+
version: 1.1.2
|
166
166
|
type: :development
|
167
167
|
prerelease: false
|
168
168
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -170,23 +170,7 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - ! '>='
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
174
|
-
- !ruby/object:Gem::Dependency
|
175
|
-
name: simplecov
|
176
|
-
requirement: !ruby/object:Gem::Requirement
|
177
|
-
none: false
|
178
|
-
requirements:
|
179
|
-
- - ! '>='
|
180
|
-
- !ruby/object:Gem::Version
|
181
|
-
version: '0'
|
182
|
-
type: :development
|
183
|
-
prerelease: false
|
184
|
-
version_requirements: !ruby/object:Gem::Requirement
|
185
|
-
none: false
|
186
|
-
requirements:
|
187
|
-
- - ! '>='
|
188
|
-
- !ruby/object:Gem::Version
|
189
|
-
version: '0'
|
173
|
+
version: 1.1.2
|
190
174
|
description: ''
|
191
175
|
email: ''
|
192
176
|
executables: []
|
@@ -200,7 +184,6 @@ files:
|
|
200
184
|
- .rvmrc
|
201
185
|
- .travis.yml
|
202
186
|
- Gemfile
|
203
|
-
- Gemfile.lock
|
204
187
|
- LICENSE.txt
|
205
188
|
- README.rdoc
|
206
189
|
- Rakefile
|
@@ -208,7 +191,6 @@ files:
|
|
208
191
|
- lib/api_utils.rb
|
209
192
|
- lib/ruby_zoho.rb
|
210
193
|
- lib/zoho_api.rb
|
211
|
-
- rubyzoho-0.1.1.gem
|
212
194
|
- rubyzoho.gemspec
|
213
195
|
- spec/api_utils_spec.rb
|
214
196
|
- spec/fixtures/sample.pdf
|
@@ -241,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
241
223
|
version: '0'
|
242
224
|
requirements: []
|
243
225
|
rubyforge_project:
|
244
|
-
rubygems_version: 1.8.
|
226
|
+
rubygems_version: 1.8.24
|
245
227
|
signing_key:
|
246
228
|
specification_version: 3
|
247
229
|
summary: A set of Ruby classes supporting the ActiveRecord lifecycle for the Zoho
|
data/Gemfile.lock
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
activesupport (3.2.12)
|
5
|
-
i18n (~> 0.6)
|
6
|
-
multi_json (~> 1.0)
|
7
|
-
archive-tar-minitar (0.5.2)
|
8
|
-
bourne (1.1.2)
|
9
|
-
mocha (= 0.10.5)
|
10
|
-
builder (3.1.4)
|
11
|
-
cucumber (1.2.1)
|
12
|
-
builder (>= 2.1.2)
|
13
|
-
diff-lcs (>= 1.1.3)
|
14
|
-
gherkin (~> 2.11.0)
|
15
|
-
json (>= 1.4.6)
|
16
|
-
diff-lcs (1.1.3)
|
17
|
-
gherkin (2.11.6)
|
18
|
-
json (>= 1.7.6)
|
19
|
-
git (1.2.5)
|
20
|
-
httmultiparty (0.3.8)
|
21
|
-
httparty (>= 0.7.3)
|
22
|
-
multipart-post
|
23
|
-
httparty (0.10.2)
|
24
|
-
multi_json (~> 1.0)
|
25
|
-
multi_xml (>= 0.5.2)
|
26
|
-
i18n (0.6.1)
|
27
|
-
jeweler (1.8.4)
|
28
|
-
bundler (~> 1.0)
|
29
|
-
git (>= 1.2.5)
|
30
|
-
rake
|
31
|
-
rdoc
|
32
|
-
json (1.7.7)
|
33
|
-
metaclass (0.0.1)
|
34
|
-
mime-types (1.21)
|
35
|
-
mocha (0.10.5)
|
36
|
-
metaclass (~> 0.0.1)
|
37
|
-
multi_json (1.5.1)
|
38
|
-
multi_xml (0.5.3)
|
39
|
-
multipart-post (1.1.5)
|
40
|
-
nokogiri (1.5.6)
|
41
|
-
rake (10.0.3)
|
42
|
-
rdoc (3.12.1)
|
43
|
-
json (~> 1.4)
|
44
|
-
relish (0.6)
|
45
|
-
archive-tar-minitar (>= 0.5.2)
|
46
|
-
json (>= 1.4.6)
|
47
|
-
rest-client (>= 1.6.1)
|
48
|
-
rest-client (1.6.7)
|
49
|
-
mime-types (>= 1.16)
|
50
|
-
roxml (3.3.1)
|
51
|
-
activesupport (>= 2.3.0)
|
52
|
-
nokogiri (>= 1.3.3)
|
53
|
-
rspec (2.12.0)
|
54
|
-
rspec-core (~> 2.12.0)
|
55
|
-
rspec-expectations (~> 2.12.0)
|
56
|
-
rspec-mocks (~> 2.12.0)
|
57
|
-
rspec-core (2.12.2)
|
58
|
-
rspec-expectations (2.12.1)
|
59
|
-
diff-lcs (~> 1.1.3)
|
60
|
-
rspec-mocks (2.12.2)
|
61
|
-
shoulda (3.3.2)
|
62
|
-
shoulda-context (~> 1.0.1)
|
63
|
-
shoulda-matchers (~> 1.4.1)
|
64
|
-
shoulda-context (1.0.2)
|
65
|
-
shoulda-matchers (1.4.2)
|
66
|
-
activesupport (>= 3.0.0)
|
67
|
-
bourne (~> 1.1.2)
|
68
|
-
simplecov (0.7.1)
|
69
|
-
multi_json (~> 1.0)
|
70
|
-
simplecov-html (~> 0.7.1)
|
71
|
-
simplecov-html (0.7.1)
|
72
|
-
xml-simple (1.1.2)
|
73
|
-
|
74
|
-
PLATFORMS
|
75
|
-
ruby
|
76
|
-
|
77
|
-
DEPENDENCIES
|
78
|
-
bundler
|
79
|
-
cucumber
|
80
|
-
httmultiparty
|
81
|
-
jeweler (~> 1.8.4)
|
82
|
-
rdoc
|
83
|
-
relish
|
84
|
-
roxml
|
85
|
-
rspec (>= 2.12.0)
|
86
|
-
shoulda
|
87
|
-
simplecov
|
88
|
-
xml-simple
|
data/rubyzoho-0.1.1.gem
DELETED
Binary file
|