rubyzoho 0.1.7 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTYwNTBjNmI5YTEzZDQzNjQwZjExOTc0YzkxNDRlZjIxODA1ZDFlNQ==
5
+ data.tar.gz: !binary |-
6
+ MzY4ZmVlZTY2ZjlmMjdkZjE0Njc3YWRjMmFkZWZmM2Q5NTBkYTYzYw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YmQ5MzBhODczNzA1Yzk0ZTAyYjRlZTAwNWRmYWYxNTc0ZWE5ODA0ZTczZmUz
10
+ YTlhYjdlZDA3YWQ1MjlkOTg0MDYwMWUyOThkODhkZDM0ZTgwNTIxOGRhZDVi
11
+ ZjlmMzMwNDJlMWExYTUyZmMzOTYyNDRkMmVhZTQ1NmM2NGJlN2Y=
12
+ data.tar.gz: !binary |-
13
+ ODg2YjA0YTU0MjE2NTcwYTZkN2MzMDYwZjQ0M2NjNDY4MGFmOWJkZjgxNzQ0
14
+ NDYxOWJjMDRkZjAwOTNjNGI0OWE1NGZlZGM0N2ZjYTljYTU5ZjI4Y2U3ZjBl
15
+ ZWY0NTQ3ODE4YjI4MDMzMGU2NjgyMWVjZjZkOTA4YjBlOTU4Mjc=
data/.coverall.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ rubyzoho
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3
data/.travis.yml CHANGED
@@ -7,8 +7,4 @@ matrix:
7
7
  - rvm: jruby
8
8
  env:
9
9
  global:
10
- - secure: ! 'Es86LRVpGFcxK8Ay0NzjtPgL1a7GQ25WRq4FgixHplZ8BbB2g/LGm2hFFnrD
11
-
12
- TQHNvTttEhrXDRXvYqv0ePTSb2I4Tn6xOzBZTIwZlmNDl6uj/5ZL9C9I3LQb
13
-
14
- 1MP0XFN0GfkOpw4DqVerdzDDoRzQw7AbTBttaOVyO3Nhiddtc3E='
10
+ - secure: "Z9gYY+iN1CB6+6KOG9zhCFHqNoUpeDrO0asn6ocpsaAVpQ+5L1ehdLcneZR+c/8fEyplC1sPtPQaq3u1/xrZ8dluev6iRoDZvEAS3GDg594lIB9owBJXXQKKGddyKfdCcp6xcNphJtcgSNtuxfNmhQyTvSBp0TjBgVvknoa1dNE="
data/Gemfile CHANGED
@@ -1,13 +1,15 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- gem 'httmultiparty', '>= 0.3.8'
4
- gem 'roxml', '>= 3.3.1'
3
+ gem 'activemodel'
4
+ gem 'httmultiparty'
5
+ gem 'roxml'
5
6
  gem 'multipart-post'
6
7
 
7
8
  group :test do
8
9
  gem 'rspec', '>= 2.12.0'
9
10
  gem 'xml-simple', '>=1.1.2'
10
11
  gem 'simplecov', '>= 0.7.1', :require => false, :group => :test
12
+ gem 'coveralls', require: false
11
13
  end
12
14
 
13
15
  group :development do
data/README.rdoc CHANGED
@@ -1,4 +1,4 @@
1
- = rubyzoho {<img src="https://travis-ci.org/amalc/rubyzoho.png?branch=master" alt="Build Status" />}[https://travis-ci.org/amalc/rubyzoho] {<img src="https://gemnasium.com/amalc/rubyzoho.png" alt="Dependency Status" />}[https://gemnasium.com/amalc/rubyzoho] {<img src="https://codeclimate.com/github/amalc/rubyzoho.png" />}[https://codeclimate.com/github/amalc/rubyzoho]
1
+ = rubyzoho {<img src="https://travis-ci.org/amalc/rubyzoho.png?branch=master" alt="Build Status" />}[https://travis-ci.org/amalc/rubyzoho] {<img src="https://gemnasium.com/amalc/rubyzoho.png" alt="Dependency Status" />}[https://gemnasium.com/amalc/rubyzoho] {<img src="https://codeclimate.com/github/amalc/rubyzoho.png" />}[https://codeclimate.com/github/amalc/rubyzoho] {<img src="https://coveralls.io/repos/amalc/rubyzoho/badge.png?branch=master" alt="Coverage Status" />}[https://coveralls.io/r/amalc/rubyzoho] {<img src="https://badge.fury.io/rb/rubyzoho.png" alt="Gem Version" />}[http://badge.fury.io/rb/rubyzoho]
2
2
 
3
3
 
4
4
 
@@ -22,7 +22,8 @@ Put the following in an initializer (e.g. <tt><RAILS_ROOT>/config/initializers/z
22
22
  config.api_key = '<< API Key from Zoho>>'
23
23
  # config.crm_modules = ['Accounts', 'Contacts', 'Leads', 'Potentials'] # Defaults to free edition if not set
24
24
  # config.crm_modules = ['Quotes', 'SalesOrders', 'Invoices'] # Depending on what kind of account you've got, adds to free edition modules
25
- # Currently only Quotes are suported
25
+ # config.ignore_fields_with_bad_names = true # Ignores field with special characters in the name (Release 1.8)
26
+ # Currently only Quotes are supported
26
27
  end
27
28
 
28
29
  === Ruby
@@ -34,6 +35,7 @@ Make sure the following block is executed prior to making calls to the gem.
34
35
  config.api_key = '<< API Key from Zoho>>'
35
36
  # config.crm_modules = ['Accounts', 'Contacts', 'Leads', 'Potentials'] # Defaults to free edition if not set
36
37
  # config.crm_modules = ['Quotes', 'SalesOrders', 'Invoices'] # Depending on what kind of account you've got, adds to free edition modules
38
+ # config.ignore_fields_with_bad_names = true # Ignores field with special characters in the name (Release 1.8)
37
39
  # Currently only Quotes are suported
38
40
  end
39
41
 
@@ -44,7 +46,7 @@ your daily allowance. See below for some optimizations during development and te
44
46
 
45
47
  == Use
46
48
  RubyZoho attempts to follow the ActiveRecord lifecycle, i.e. new, save, update and delete.
47
- See examples below.
49
+ See examples below. (<b>N.B. Fields _cannot_ have special characters in them.</b>)
48
50
 
49
51
  To get a list of supported attributes for a Zoho CRM contact:
50
52
 
@@ -241,8 +243,15 @@ Please open an issue on GitHub. Or better yet, send in a pull request with the f
241
243
  Giant buckets of Gratitude to the giants, sung and unsung heroes who put together and support the Open Source movement,
242
244
  Linux, Ruby and Rails. We stand on the shoulders of giants. Thank you.
243
245
 
244
- == Credits
245
- wcgiles@github (\@\waynecgiles) for professional and patient debugging and continued debugging of this gem.
246
+ == Credits and Contributions
247
+ Thanks to a growing and wonderful community!
248
+ @aeldaly
249
+ @fheemeyer
250
+ @qume
251
+ @tjsousa
252
+ @wcgiles
253
+
254
+ Drop me a line if I've left anybody out and my advance apologies.
246
255
 
247
256
  == Trademarks
248
257
  Zoho, the Zoho suite and related applications are owned, trademarked and copyrighted by the Zoho Corporation Pvt. Ltd.
@@ -253,18 +262,24 @@ Copyright (c) 2013 amalc (\@\amalc). Released under the MIT license. See LICENSE
253
262
 
254
263
  ---
255
264
  = Releases
256
- == Release Candidates
265
+ == Release Candidates (Uses {Semantic Versioning}[http://semver.org/])
257
266
 
258
267
  == Development
259
- [0.1.8]
268
+ [0.1.12]
260
269
  1. Modules Supported: Accounts, Contacts, Leads, Potentials, Quotes, Tasks and Users
261
270
  2. ActiveRecord style syntax for Class.\new, Class.delete, Class.find, Class.update, Object.save
262
271
  3. << syntax for Account/Tasks on Master/Detail relationships
272
+ 4. Option in config to ignore fields with improper field names
273
+
274
+ [0.1.11] (Current master branch)
275
+ 1. Incorporate fix to namespace collision between Devise and RubyZoho, User renamed to CRMUser thanks to @qume.
276
+ 2. Other fixes from @tjsousa, @aeldaly and @fheemeyer.
277
+ 3. Refactor of the code base to improve modularization and test coverage.
278
+ == Released
263
279
  [0.1.7]
264
280
  1. Bug for attach_file method, respect the file_name parameter.
265
- 2. \:\id is the primary key across all classes in addition to Zoho's existing convention.
281
+ 2. \:\id is the primary key across all Zoho related classes (modules) in addition to Zoho's existing convention.
266
282
 
267
- == Released
268
283
  [0.1.1 - 0.1.6] Alpha Releases
269
284
  1. Configuration block signature changed
270
285
  [0.0.1 - 0.0.5] Alpha Releases
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.7
1
+ 0.1.11
data/lib/api_utils.rb CHANGED
@@ -11,6 +11,7 @@ module ApiUtils
11
11
  end
12
12
 
13
13
  def self.string_to_symbol(s)
14
+ s.gsub!(/[()%]*/, '')
14
15
  s.gsub(' ', '_').downcase.to_sym
15
16
  end
16
17
 
data/lib/crm.rb ADDED
@@ -0,0 +1,112 @@
1
+ require 'active_model'
2
+ require 'crud_methods'
3
+ require 'zoho_crm_utils'
4
+
5
+ class RubyZoho::Crm
6
+
7
+ class << self
8
+ attr_accessor :module_name
9
+ end
10
+ @module_name = 'Crm'
11
+
12
+ include CrudMethods
13
+ include ZohoCrmUtils
14
+
15
+ def initialize(object_attribute_hash = {})
16
+ @fields = object_attribute_hash == {} ? RubyZoho.configuration.api.fields(self.class.module_name) :
17
+ object_attribute_hash.keys
18
+ create_accessor(self.class, @fields)
19
+ create_accessor(self.class, [:module_name])
20
+ public_send(:module_name=, self.class.module_name)
21
+ update_or_create_attrs(object_attribute_hash)
22
+ self
23
+ end
24
+
25
+ def self.method_missing(meth, *args, &block)
26
+ if meth.to_s =~ /^find_by_(.+)$/
27
+ run_find_by_method($1, *args, &block)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def method_missing(meth, *args, &block)
34
+ if [:seid=, :semodule=].index(meth)
35
+ run_create_accessor(self.class, meth)
36
+ self.send(meth, args[0])
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+ def self.run_find_by_method(attrs, *args, &block)
43
+ attrs = attrs.split('_and_')
44
+ conditions = Array.new(args.size, '=')
45
+ h = RubyZoho.configuration.api.find_records(
46
+ self.module_name, ApiUtils.string_to_symbol(attrs[0]), conditions[0], args[0]
47
+ )
48
+ return h.collect { |r| new(r) } unless h.nil?
49
+ nil
50
+ end
51
+
52
+ def << object
53
+ object.semodule = self.module_name
54
+ object.seid = self.id
55
+ object.fields << :seid
56
+ object.fields << :semodule
57
+ save_object(object)
58
+ end
59
+
60
+ def primary_key
61
+ RubyZoho.configuration.api.primary_key(self.class.module_name)
62
+ end
63
+
64
+ def self.setup_classes
65
+ RubyZoho.configuration.crm_modules.each do |module_name|
66
+ klass_name = module_name.chop
67
+ c = Class.new(self) do
68
+ include RubyZoho
69
+ include ActiveModel
70
+ extend ActiveModel::Naming
71
+
72
+ attr_reader :fields
73
+ @module_name = module_name
74
+ end
75
+ const_set(klass_name, c)
76
+ end
77
+ end
78
+
79
+ c = Class.new(self) do
80
+ def initialize(object_attribute_hash = {})
81
+ module_name = 'Users'
82
+ super
83
+ end
84
+
85
+ def self.delete(id)
86
+ raise 'Cannot delete users through API'
87
+ end
88
+
89
+ def save
90
+ raise 'Cannot delete users through API'
91
+ end
92
+
93
+ def self.all
94
+ result = RubyZoho.configuration.api.users('AllUsers')
95
+ result.collect { |r| new(r) }
96
+ end
97
+
98
+ def self.find_by_email(email)
99
+ r = []
100
+ self.all.index { |u| r << u if u.email == email }
101
+ r
102
+ end
103
+
104
+ def self.method_missing(meth, *args, &block)
105
+ Crm.module_name = 'Users'
106
+ super
107
+ end
108
+ end
109
+
110
+ Kernel.const_set 'CRMUser', c
111
+
112
+ end
@@ -0,0 +1,76 @@
1
+ module CrudMethods
2
+
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+
9
+ def first
10
+ r = RubyZoho.configuration.api.first(self.module_name)
11
+ new(r[0])
12
+ end
13
+
14
+ def all #TODO Refactor into low level API
15
+ max_records = 200
16
+ result = []
17
+ i = 1
18
+ batch = []
19
+ until batch.nil?
20
+ batch = RubyZoho.configuration.api.some(self.module_name, i, max_records)
21
+ result.concat(batch) unless batch.nil?
22
+ break if !batch.nil? && batch.count < max_records
23
+ i += max_records
24
+ end
25
+ result.collect { |r| new(r) }
26
+ end
27
+
28
+ def find(id)
29
+ self.find_by_id(id)
30
+ end
31
+
32
+ def delete(id)
33
+ RubyZoho.configuration.api.delete_record(self.module_name, id)
34
+ end
35
+
36
+ def update(object_attribute_hash)
37
+ raise(RuntimeError, 'No ID found', object_attribute_hash.to_s) if object_attribute_hash[:id].nil?
38
+ id = object_attribute_hash[:id]
39
+ object_attribute_hash.delete(:id)
40
+ r = RubyZoho.configuration.api.update_record(self.module_name, id, object_attribute_hash)
41
+ new(object_attribute_hash.merge!(r))
42
+ end
43
+
44
+ end
45
+
46
+ def attach_file(file_path, file_name)
47
+ RubyZoho.configuration.api.attach_file(self.class.module_name, self.send(primary_key), file_path, file_name)
48
+ end
49
+
50
+ def create(object_attribute_hash)
51
+ initialize(object_attribute_hash)
52
+ save
53
+ end
54
+
55
+ def save
56
+ h = {}
57
+ @fields.each { |f| h.merge!({ f => eval("self.#{f.to_s}") }) }
58
+ h.delete_if { |k, v| v.nil? }
59
+ r = RubyZoho.configuration.api.add_record(self.class.module_name, h)
60
+ up_date(r)
61
+ end
62
+
63
+ def save_object(object)
64
+ h = {}
65
+ object.fields.each { |f| h.merge!({ f => object.send(f) }) }
66
+ h.delete_if { |k, v| v.nil? }
67
+ r = RubyZoho.configuration.api.add_record(object.module_name, h)
68
+ up_date(r)
69
+ end
70
+
71
+ def up_date(object_attribute_hash)
72
+ update_or_create_attrs(object_attribute_hash)
73
+ self
74
+ end
75
+
76
+ end
data/lib/ruby_zoho.rb CHANGED
@@ -2,17 +2,17 @@ require 'zoho_api'
2
2
  require 'api_utils'
3
3
  require 'yaml'
4
4
 
5
-
6
5
  module RubyZoho
7
6
 
8
7
  class Configuration
9
- attr_accessor :api, :api_key, :cache_fields, :crm_modules
8
+ attr_accessor :api, :api_key, :cache_fields, :crm_modules, :ignore_fields_with_bad_names
10
9
 
11
10
  def initialize
12
11
  self.api_key = nil
13
12
  self.api = nil
14
13
  self.cache_fields = false
15
14
  self.crm_modules = nil
15
+ self.ignore_fields_with_bad_names = true
16
16
  end
17
17
  end
18
18
 
@@ -27,7 +27,7 @@ module RubyZoho
27
27
  self.configuration.crm_modules = %w[Accounts Calls Contacts Events Leads Potentials Tasks].concat(
28
28
  self.configuration.crm_modules).uniq
29
29
  self.configuration.api = init_api(self.configuration.api_key,
30
- self.configuration.crm_modules, self.configuration.cache_fields)
30
+ self.configuration.crm_modules, self.configuration.cache_fields)
31
31
  RubyZoho::Crm.setup_classes()
32
32
  end
33
33
 
@@ -35,234 +35,16 @@ module RubyZoho
35
35
  base_path = File.join(File.dirname(__FILE__), '..', 'spec', 'fixtures')
36
36
  if File.exists?(File.join(base_path, 'fields.snapshot')) && cache_fields == true
37
37
  fields = YAML.load(File.read(File.join(base_path, 'fields.snapshot')))
38
- zoho = ZohoApi::Crm.new(api_key, modules, fields)
38
+ zoho = ZohoApi::Crm.new(api_key, modules,
39
+ self.configuration.ignore_fields_with_bad_names, fields)
39
40
  else
40
- zoho = ZohoApi::Crm.new(api_key, modules)
41
+ zoho = ZohoApi::Crm.new(api_key, modules, self.configuration.ignore_fields_with_bad_names)
41
42
  fields = zoho.module_fields
42
43
  File.open(File.join(base_path, 'fields.snapshot'), 'wb') { |file| file.write(fields.to_yaml) } if cache_fields == true
43
44
  end
44
45
  zoho
45
46
  end
46
47
 
47
- class Crm
48
-
49
- class << self
50
- attr_accessor :module_name
51
- end
52
- @module_name = 'Crm'
53
-
54
- def initialize(object_attribute_hash = {})
55
- @fields = object_attribute_hash == {} ? RubyZoho.configuration.api.fields(self.class.module_name) :
56
- object_attribute_hash.keys
57
- RubyZoho::Crm.create_accessor(self.class, @fields)
58
- RubyZoho::Crm.create_accessor(self.class, [:module_name])
59
- public_send(:module_name=, self.class.module_name)
60
- update_or_create_attrs(object_attribute_hash)
61
- self
62
- end
63
-
64
- def update_or_create_attrs(object_attribute_hash)
65
- retry_counter = object_attribute_hash.count
66
- begin
67
- object_attribute_hash.map { |(k, v)| public_send("#{k}=", v) }
68
- rescue NoMethodError => e
69
- m = e.message.slice(/`(.*?)=/)
70
- RubyZoho::Crm.create_accessor(self.class, [m.gsub(/[`()]*/, '').chop]) unless m.nil?
71
- retry_counter -= 1
72
- retry if retry_counter > 0
73
- end
74
- end
75
-
76
- def attr_writers
77
- self.methods.grep(/\w=$/)
78
- end
79
-
80
- def self.create_accessor(klass, names)
81
- names.each do |name|
82
- n = name
83
- n = name.to_s if name.class == Symbol
84
- raise(RuntimeError, "Bad field name: #{name}") unless method_name?(name)
85
- create_getter(klass, n)
86
- create_setter(klass, n)
87
- end
88
- names
89
- end
90
-
91
- def self.method_name?(n)
92
- name = n.class == String ? ApiUtils.string_to_symbol(n) : n
93
- return /[@$"]/ !~ name.inspect
94
- end
95
-
96
- def self.create_getter(klass, *names)
97
- names.each do |name|
98
- klass.send(:define_method, "#{name}") { instance_variable_get("@#{name}") }
99
- end
100
- end
101
-
102
- def self.create_setter(klass, *names)
103
- names.each do |name|
104
- klass.send(:define_method, "#{name}=") { |val| instance_variable_set("@#{name}", val) }
105
- end
106
- end
107
-
108
- def self.find(id)
109
- self.find_by_id(id)
110
- end
111
-
112
- def self.method_missing(meth, *args, &block)
113
- if meth.to_s =~ /^find_by_(.+)$/
114
- run_find_by_method($1, *args, &block)
115
- else
116
- super
117
- end
118
- end
119
-
120
- def method_missing(meth, *args, &block)
121
- if [:seid=, :semodule=].index(meth)
122
- run_create_accessor(self.class, meth)
123
- self.send(meth, args[0])
124
- else
125
- super
126
- end
127
- end
128
-
129
- def self.method_is_module?(str_or_sym)
130
- return nil if str_or_sym.nil?
131
- s = str_or_sym.class == String ? str_or_sym : ApiUtils.symbol_to_string(str_or_sym)
132
- possible_module = s[s.length - 1].downcase == 's' ? s : s + 's'
133
- i = RubyZoho.configuration.crm_modules.index(possible_module.capitalize)
134
- return str_or_sym unless i.nil?
135
- nil
136
- end
137
-
138
- def run_create_accessor(klass, meth)
139
- method = meth.to_s.chop.to_sym
140
- RubyZoho::Crm.create_accessor(klass, [method])
141
- nil
142
- end
143
-
144
- def self.run_find_by_method(attrs, *args, &block)
145
- attrs = attrs.split('_and_')
146
- conditions = Array.new(args.size, '=')
147
- h = RubyZoho.configuration.api.find_records(
148
- self.module_name, ApiUtils.string_to_symbol(attrs[0]), conditions[0], args[0]
149
- )
150
- return h.collect { |r| new(r) } unless h.nil?
151
- nil
152
- end
153
-
154
- def self.all #TODO Refactor into low level API
155
- max_records = 200
156
- result = []
157
- i = 1
158
- batch = []
159
- until batch.nil?
160
- batch = RubyZoho.configuration.api.some(self.module_name, i, max_records)
161
- result.concat(batch) unless batch.nil?
162
- break if !batch.nil? && batch.count < max_records
163
- i += max_records
164
- end
165
- result.collect { |r| new(r) }
166
- end
167
-
168
- def << object
169
- object.semodule = self.module_name
170
- object.seid = self.id
171
- object.fields << :seid
172
- object.fields << :semodule
173
- save_object(object)
174
- end
175
-
176
- def attach_file(file_path, file_name)
177
- RubyZoho.configuration.api.attach_file(self.class.module_name, self.send(primary_key), file_path, file_name)
178
- end
179
-
180
- def create(object_attribute_hash)
181
- initialize(object_attribute_hash)
182
- save
183
- end
184
-
185
- def self.delete(id)
186
- RubyZoho.configuration.api.delete_record(self.module_name, id)
187
- end
188
-
189
- def primary_key
190
- RubyZoho.configuration.api.primary_key(self.class.module_name)
191
- end
192
-
193
- def save
194
- h = {}
195
- @fields.each { |f| h.merge!({ f => eval("self.#{f.to_s}") }) }
196
- h.delete_if { |k, v| v.nil? }
197
- r = RubyZoho.configuration.api.add_record(self.class.module_name, h)
198
- up_date(r)
199
- end
200
-
201
- def save_object(object)
202
- h = {}
203
- object.fields.each { |f| h.merge!({ f => object.send(f) }) }
204
- h.delete_if { |k, v| v.nil? }
205
- r = RubyZoho.configuration.api.add_record(object.module_name, h)
206
- up_date(r)
207
- end
48
+ require 'crm'
208
49
 
209
- def self.update(object_attribute_hash)
210
- raise(RuntimeError, 'No ID found', object_attribute_hash.to_s) if object_attribute_hash[:id].nil?
211
- id = object_attribute_hash[:id]
212
- object_attribute_hash.delete(:id)
213
- r = RubyZoho.configuration.api.update_record(self.module_name, id, object_attribute_hash)
214
- new(object_attribute_hash.merge!(r))
215
- end
216
-
217
- def up_date(object_attribute_hash)
218
- update_or_create_attrs(object_attribute_hash)
219
- self
220
- end
221
-
222
- def self.setup_classes
223
- RubyZoho.configuration.crm_modules.each do |module_name|
224
- klass_name = module_name.chop
225
- c = Class.new(RubyZoho::Crm) do
226
- include RubyZoho
227
- attr_reader :fields
228
- @module_name = module_name
229
- end
230
- const_set(klass_name, c)
231
- end
232
- end
233
-
234
- c = Class.new(RubyZoho::Crm) do
235
- def initialize(object_attribute_hash = {})
236
- Crm.module_name = 'Users'
237
- super
238
- end
239
-
240
- def self.delete(id)
241
- raise 'Cannot delete users through API'
242
- end
243
-
244
- def save
245
- raise 'Cannot delete users through API'
246
- end
247
-
248
- def self.all
249
- result = RubyZoho.configuration.api.users('AllUsers')
250
- result.collect { |r| new(r) }
251
- end
252
-
253
- def self.find_by_email(email)
254
- r = []
255
- self.all.index { |u| r << u if u.email == email }
256
- r
257
- end
258
-
259
- def self.method_missing(meth, *args, &block)
260
- Crm.module_name = 'Users'
261
- super
262
- end
263
- end
264
-
265
- Kernel.const_set 'User', c
266
-
267
- end
268
50
  end