sugarcrm_emp 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. data/.document +5 -0
  2. data/.gitignore +29 -0
  3. data/Gemfile +14 -0
  4. data/LICENSE +20 -0
  5. data/README.rdoc +275 -0
  6. data/Rakefile +44 -0
  7. data/VERSION +1 -0
  8. data/WATCHLIST.rdoc +7 -0
  9. data/bin/sugarcrm +26 -0
  10. data/lib/rails/generators/sugarcrm/config/config_generator.rb +22 -0
  11. data/lib/rails/generators/sugarcrm/config/templates/initializer.rb +4 -0
  12. data/lib/rails/generators/sugarcrm/config/templates/sugarcrm.yml +19 -0
  13. data/lib/sugarcrm/associations/association.rb +170 -0
  14. data/lib/sugarcrm/associations/association_cache.rb +36 -0
  15. data/lib/sugarcrm/associations/association_collection.rb +141 -0
  16. data/lib/sugarcrm/associations/association_methods.rb +91 -0
  17. data/lib/sugarcrm/associations/associations.rb +61 -0
  18. data/lib/sugarcrm/associations.rb +5 -0
  19. data/lib/sugarcrm/attributes/attribute_methods.rb +203 -0
  20. data/lib/sugarcrm/attributes/attribute_serializers.rb +55 -0
  21. data/lib/sugarcrm/attributes/attribute_typecast.rb +44 -0
  22. data/lib/sugarcrm/attributes/attribute_validations.rb +62 -0
  23. data/lib/sugarcrm/attributes.rb +4 -0
  24. data/lib/sugarcrm/base.rb +355 -0
  25. data/lib/sugarcrm/config/sugarcrm.yaml +10 -0
  26. data/lib/sugarcrm/connection/api/get_available_modules.rb +22 -0
  27. data/lib/sugarcrm/connection/api/get_document_revision.rb +14 -0
  28. data/lib/sugarcrm/connection/api/get_entries.rb +23 -0
  29. data/lib/sugarcrm/connection/api/get_entries_count.rb +20 -0
  30. data/lib/sugarcrm/connection/api/get_entry.rb +23 -0
  31. data/lib/sugarcrm/connection/api/get_entry_list.rb +31 -0
  32. data/lib/sugarcrm/connection/api/get_module_fields.rb +15 -0
  33. data/lib/sugarcrm/connection/api/get_note_attachment.rb +14 -0
  34. data/lib/sugarcrm/connection/api/get_relationships.rb +30 -0
  35. data/lib/sugarcrm/connection/api/get_report_entries.rb +17 -0
  36. data/lib/sugarcrm/connection/api/get_server_info.rb +7 -0
  37. data/lib/sugarcrm/connection/api/get_user_id.rb +13 -0
  38. data/lib/sugarcrm/connection/api/get_user_team_id.rb +14 -0
  39. data/lib/sugarcrm/connection/api/login.rb +18 -0
  40. data/lib/sugarcrm/connection/api/logout.rb +15 -0
  41. data/lib/sugarcrm/connection/api/seamless_login.rb +13 -0
  42. data/lib/sugarcrm/connection/api/search_by_module.rb +25 -0
  43. data/lib/sugarcrm/connection/api/set_campaign_merge.rb +15 -0
  44. data/lib/sugarcrm/connection/api/set_document_revision.rb +35 -0
  45. data/lib/sugarcrm/connection/api/set_entries.rb +15 -0
  46. data/lib/sugarcrm/connection/api/set_entry.rb +15 -0
  47. data/lib/sugarcrm/connection/api/set_note_attachment.rb +25 -0
  48. data/lib/sugarcrm/connection/api/set_relationship.rb +27 -0
  49. data/lib/sugarcrm/connection/api/set_relationships.rb +22 -0
  50. data/lib/sugarcrm/connection/connection.rb +201 -0
  51. data/lib/sugarcrm/connection/helper.rb +50 -0
  52. data/lib/sugarcrm/connection/request.rb +61 -0
  53. data/lib/sugarcrm/connection/response.rb +91 -0
  54. data/lib/sugarcrm/connection.rb +5 -0
  55. data/lib/sugarcrm/connection_pool.rb +163 -0
  56. data/lib/sugarcrm/exceptions.rb +23 -0
  57. data/lib/sugarcrm/extensions/README.txt +23 -0
  58. data/lib/sugarcrm/finders/dynamic_finder_match.rb +41 -0
  59. data/lib/sugarcrm/finders/finder_methods.rb +243 -0
  60. data/lib/sugarcrm/finders.rb +2 -0
  61. data/lib/sugarcrm/module.rb +174 -0
  62. data/lib/sugarcrm/module_methods.rb +91 -0
  63. data/lib/sugarcrm/session.rb +218 -0
  64. data/lib/sugarcrm.rb +22 -0
  65. data/sugarcrm.gemspec +178 -0
  66. data/test/config_test.yaml +15 -0
  67. data/test/connection/test_get_available_modules.rb +9 -0
  68. data/test/connection/test_get_entries.rb +15 -0
  69. data/test/connection/test_get_entry.rb +22 -0
  70. data/test/connection/test_get_entry_list.rb +23 -0
  71. data/test/connection/test_get_module_fields.rb +11 -0
  72. data/test/connection/test_get_relationships.rb +12 -0
  73. data/test/connection/test_get_server_info.rb +9 -0
  74. data/test/connection/test_get_user_id.rb +9 -0
  75. data/test/connection/test_get_user_team_id.rb +9 -0
  76. data/test/connection/test_login.rb +9 -0
  77. data/test/connection/test_logout.rb +9 -0
  78. data/test/connection/test_set_document_revision.rb +28 -0
  79. data/test/connection/test_set_entry.rb +15 -0
  80. data/test/connection/test_set_note_attachment.rb +16 -0
  81. data/test/connection/test_set_relationship.rb +18 -0
  82. data/test/extensions_test/patch.rb +9 -0
  83. data/test/helper.rb +17 -0
  84. data/test/test_association_collection.rb +11 -0
  85. data/test/test_associations.rb +156 -0
  86. data/test/test_connection.rb +13 -0
  87. data/test/test_connection_pool.rb +40 -0
  88. data/test/test_finders.rb +201 -0
  89. data/test/test_module.rb +51 -0
  90. data/test/test_request.rb +35 -0
  91. data/test/test_response.rb +26 -0
  92. data/test/test_session.rb +136 -0
  93. data/test/test_sugarcrm.rb +213 -0
  94. metadata +266 -0
@@ -0,0 +1,355 @@
1
+ module SugarCRM; class Base
2
+
3
+ # Unset all of the instance methods we don't need.
4
+ instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$|^define_method$|^class$|^nil.$|^methods$|^instance_of.$|^respond_to)/ }
5
+
6
+ # Tracks if we have extended our class with attribute methods yet.
7
+ class_attribute :attribute_methods_generated
8
+ self.attribute_methods_generated = false
9
+
10
+ class_attribute :association_methods_generated
11
+ self.association_methods_generated = false
12
+
13
+ class_attribute :_module
14
+ self._module = nil
15
+
16
+ # the session to which we're linked
17
+ class_attribute :session
18
+ self.session = nil
19
+
20
+ # Contains a list of attributes
21
+ attr :attributes, true
22
+ attr :modified_attributes, true
23
+ attr :associations, true
24
+ attr :debug, true
25
+ attr :errors, true
26
+
27
+ class << self # Class methods
28
+ def find(*args, &block)
29
+ options = args.extract_options!
30
+ # add default sorting date (necessary for first and last methods to work)
31
+ # most modules (Contacts, Accounts, etc.) use 'date_entered' to store when the record was created
32
+ # other modules (e.g. EmailAddresses) use 'date_created'
33
+ # Here, we account for this discrepancy...
34
+ self.new # make sure the fields are loaded from SugarCRM so method_defined? will work properly
35
+ if self.method_defined? :date_entered
36
+ sort_criteria = 'date_entered'
37
+ elsif self.method_defined? :date_created
38
+ sort_criteria = 'date_created'
39
+ # Added date_modified because TeamSets doesn't have a date_created or date_entered field.
40
+ # There's no test for this because it's Pro and above only.
41
+ # Hope this doesn't break anything!
42
+ elsif self.method_defined? :date_modified
43
+ sort_criteria = 'date_modified'
44
+ else
45
+ raise InvalidAttribute, "Unable to determine record creation date for sorting criteria: expected date_entered, date_created, or date_modified attribute to be present"
46
+ end
47
+ options = {:order_by => sort_criteria}.merge(options)
48
+ validate_find_options(options)
49
+
50
+ case args.first
51
+ when :first
52
+ find_initial(options)
53
+ when :last
54
+ begin
55
+ options[:order_by] = reverse_order_clause(options[:order_by].to_s)
56
+ rescue Exception => e
57
+ raise
58
+ end
59
+ find_initial(options)
60
+ when :all
61
+ Array.wrap(find_every(options, &block)).compact
62
+ else
63
+ find_from_ids(args, options, &block)
64
+ end
65
+ end
66
+
67
+ # return the connection to the correct SugarCRM server (there can be several)
68
+ def connection
69
+ self.session.connection
70
+ end
71
+
72
+ # return the number of records satifsying the options
73
+ # note: the REST API has a bug (documented with Sugar as bug 43339) where passing custom attributes in the options will result in the
74
+ # options being ignored and '0' being returned, regardless of the existence of records satisfying the options
75
+ def count(options={})
76
+ raise InvalidAttribute, 'Conditions on custom attributes are not supported due to REST API bug' if contains_custom_attribute(options[:conditions])
77
+ query = query_from_options(options)
78
+ connection.get_entries_count(self._module.name, query, options)['result_count'].to_i
79
+ end
80
+
81
+ # A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the
82
+ # same arguments to this method as you can to <tt>find(:first)</tt>.
83
+ def first(*args, &block)
84
+ find(:first, *args, &block)
85
+ end
86
+
87
+ # A convenience wrapper for <tt>find(:last, *args)</tt>. You can pass in all the
88
+ # same arguments to this method as you can to <tt>find(:last)</tt>.
89
+ def last(*args, &block)
90
+ find(:last, *args, &block)
91
+ end
92
+
93
+ # This is an alias for find(:all). You can pass in all the same arguments to this method as you can
94
+ # to find(:all)
95
+ def all(*args, &block)
96
+ find(:all, *args, &block)
97
+ end
98
+
99
+ # Creates an object (or multiple objects) and saves it to SugarCRM if validations pass.
100
+ # The resulting object is returned whether the object was saved successfully to the database or not.
101
+ #
102
+ # The +attributes+ parameter can be either be a Hash or an Array of Hashes. These Hashes describe the
103
+ # attributes on the objects that are to be created.
104
+ #
105
+ # ==== Examples
106
+ # # Create a single new object
107
+ # User.create(:first_name => 'Jamie')
108
+ #
109
+ # # Create an Array of new objects
110
+ # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
111
+ #
112
+ # # Create a single object and pass it into a block to set other attributes.
113
+ # User.create(:first_name => 'Jamie') do |u|
114
+ # u.is_admin = false
115
+ # end
116
+ #
117
+ # # Creating an Array of new objects using a block, where the block is executed for each object:
118
+ # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
119
+ # u.is_admin = false
120
+ # end
121
+ def create(attributes = nil, &block)
122
+ if attributes.is_a?(Array)
123
+ attributes.collect { |attr| create(attr, &block) }
124
+ else
125
+ object = new(attributes)
126
+ yield(object) if block_given?
127
+ object.save
128
+ object
129
+ end
130
+ end
131
+ end
132
+
133
+ # Creates an instance of a Module Class, i.e. Account, User, Contact, etc.
134
+ def initialize(attributes={}, &block)
135
+ attributes.delete('id')
136
+ @errors = {}
137
+ @modified_attributes = {}
138
+ merge_attributes(attributes.with_indifferent_access)
139
+ clear_association_cache
140
+ define_attribute_methods
141
+ define_association_methods
142
+ typecast_attributes
143
+ self
144
+ end
145
+
146
+ def inspect
147
+ self
148
+ end
149
+
150
+ def to_s
151
+ attrs = []
152
+ @attributes.keys.sort.each do |k|
153
+ attrs << "#{k}: #{attribute_for_inspect(k)}"
154
+ end
155
+ "#<#{self.class} #{attrs.join(", ")}>"
156
+ end
157
+
158
+ # objects are considered equal if they represent the same SugarCRM record
159
+ # this behavior is required for Rails to be able to properly cast objects to json (lists, in particular)
160
+ def equal?(other)
161
+ return false unless other && other.respond_to?(:id)
162
+ self.id == other.id
163
+ end
164
+
165
+ # return variables that are defined in SugarCRM, instead of the object's actual variables (such as modified_attributes, errors, etc.)
166
+ def instance_variables
167
+ @_instance_variables ||= @attributes.keys.map{|i| ('@' + i).to_sym }
168
+ end
169
+
170
+ # override to return the value of the SugarCRM record's attributes
171
+ def instance_variable_get(name)
172
+ name = name.to_s.gsub(/^@/,'')
173
+ @attributes[name]
174
+ end
175
+
176
+ # Rails requires this to (e.g.) generate json representations of models
177
+ # this code taken directly from the Rails project
178
+ if defined?(Rails)
179
+ def instance_values
180
+ Hash[instance_variables.map { |name| [name.to_s[1..-1], instance_variable_get(name)] }]
181
+ end
182
+ end
183
+
184
+ def to_json(options={})
185
+ attributes.to_json
186
+ end
187
+
188
+ def to_xml(options={})
189
+ attributes.to_xml
190
+ end
191
+
192
+ # Saves the current object, checks that required fields are present.
193
+ # returns true or false
194
+ def save(opts={})
195
+ options = { :validate => true }.merge(opts)
196
+ return false if !(new_record? || changed?)
197
+ if options[:validate]
198
+ return false if !valid?
199
+ end
200
+ begin
201
+ save!(options)
202
+ rescue
203
+ return false
204
+ end
205
+ true
206
+ end
207
+
208
+ # Saves the current object, and any modified associations.
209
+ # Raises an exceptions if save fails for any reason.
210
+ def save!(opts={})
211
+ save_modified_attributes!(opts)
212
+ save_modified_associations!
213
+ true
214
+ end
215
+
216
+ def delete
217
+ return false if id.blank?
218
+ params = {}
219
+ params[:id] = serialize_id
220
+ params[:deleted]= {:name => "deleted", :value => "1"}
221
+ @attributes[:deleted] = (self.class.connection.set_entry(self.class._module.name, params).class == Hash)
222
+ end
223
+ alias :destroy :delete
224
+
225
+ # Returns if the record is persisted, i.e. it’s not a new record and it was not destroyed
226
+ def persisted?
227
+ !(new_record? || destroyed?)
228
+ end
229
+
230
+ # Reloads the record from SugarCRM
231
+ def reload!
232
+ self.attributes = self.class.find(self.id).attributes
233
+ end
234
+
235
+ def blank?
236
+ @attributes.empty?
237
+ end
238
+ alias :empty? :blank?
239
+
240
+ # Returns true if +comparison_object+ is the same exact object, or +comparison_object+
241
+ # is of the same type and +self+ has an ID and it is equal to +comparison_object.id+.
242
+ #
243
+ # Note that new records are different from any other record by definition, unless the
244
+ # other record is the receiver itself. Besides, if you fetch existing records with
245
+ # +select+ and leave the ID out, you're on your own, this predicate will return false.
246
+ #
247
+ # Note also that destroying a record preserves its ID in the model instance, so deleted
248
+ # models are still comparable.
249
+ def ==(comparison_object)
250
+ comparison_object.instance_of?(self.class) &&
251
+ id.present? &&
252
+ comparison_object.id == id
253
+ end
254
+ alias :eql? :==
255
+
256
+ def update_attribute!(name, value)
257
+ self.send("#{name}=".to_sym, value)
258
+ self.save!
259
+ end
260
+
261
+ def update_attribute(name, value)
262
+ begin
263
+ update_attribute!(name, value)
264
+ rescue
265
+ return false
266
+ end
267
+ true
268
+ end
269
+
270
+ def update_attributes!(attributes)
271
+ attributes.each do |name, value|
272
+ self.send("#{name}=".to_sym, value)
273
+ end
274
+ self.save!
275
+ end
276
+
277
+ def update_attributes(attributes)
278
+ begin
279
+ update_attributes!(attributes)
280
+ rescue
281
+ return false
282
+ end
283
+ true
284
+ end
285
+
286
+ # Returns the URL (in string format) where the module instance is available in CRM
287
+ def url
288
+ "#{SugarCRM.session.config[:base_url]}/index.php?module=#{self.class._module.name}&action=DetailView&record=#{self.id}"
289
+ end
290
+
291
+ # Delegates to id in order to allow two records of the same type and id to work with something like:
292
+ # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
293
+ def hash
294
+ id.hash
295
+ end
296
+
297
+ def pretty_print(pp)
298
+ pp.text self.inspect.to_s, 0
299
+ end
300
+
301
+ def attribute_methods_generated?
302
+ self.class.attribute_methods_generated
303
+ end
304
+
305
+ def association_methods_generated?
306
+ self.class.association_methods_generated
307
+ end
308
+
309
+ def to_key
310
+ new_record? ? nil : [ id ]
311
+ end
312
+
313
+ def to_param
314
+ id.to_s
315
+ end
316
+
317
+ def is_a?(klass)
318
+ superclasses.include? klass
319
+ end
320
+ alias :kind_of? :is_a?
321
+ alias :=== :is_a?
322
+
323
+ private
324
+ # returns true if the hash contains a custom attribute created in Studio (and whose name therefore ends in '_c')
325
+ def self.contains_custom_attribute(attributes)
326
+ attributes ||= {}
327
+ attributes.each_key{|k|
328
+ return true if k.to_s =~ /_c$/
329
+ }
330
+ false
331
+ end
332
+
333
+ def superclasses
334
+ return @superclasses if @superclasses
335
+ @superclasses = [self.class]
336
+ current_class = self.class
337
+ while current_class.respond_to? :superclass
338
+ @superclasses << (current_class = current_class.superclass)
339
+ end
340
+ @superclasses
341
+ end
342
+
343
+ Base.class_eval do
344
+ extend FinderMethods::ClassMethods
345
+ include AttributeMethods
346
+ extend AttributeMethods::ClassMethods
347
+ include AttributeValidations
348
+ include AttributeTypeCast
349
+ include AttributeSerializers
350
+ include AssociationMethods
351
+ extend AssociationMethods::ClassMethods
352
+ include AssociationCache
353
+ end
354
+
355
+ end; end
@@ -0,0 +1,10 @@
1
+ # below is an example configuration file
2
+ #
3
+ # to create you own configuration file, simply copy and adapt the text below, removing the '#' in front of the key-value pairs
4
+ #
5
+ # you'll find an example of a configuration file (used for tests) in test/config_test.yaml
6
+ #
7
+ # config:
8
+ # base_url: http://127.0.0.1/sugarcrm # where your SugarCRM instance is located
9
+ # username: admin
10
+ # password: letmein
@@ -0,0 +1,22 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieves the list of modules available to the current user logged into the system.
3
+ def get_available_modules
4
+ login! unless logged_in?
5
+ json = <<-EOF
6
+ {
7
+ "session": "#{@sugar_session_id}"
8
+ }
9
+ EOF
10
+
11
+ json.gsub!(/^\s{6}/,'')
12
+ mods = send!(:get_available_modules, json)["modules"]
13
+ modules = []
14
+ mods.each do |mod|
15
+ modules << Module.new(@session, mod)
16
+ end
17
+ modules
18
+ end
19
+
20
+ alias :get_modules :get_available_modules
21
+
22
+ end; end
@@ -0,0 +1,14 @@
1
+ module SugarCRM; class Connection
2
+ # Downloads a particular revision of a document.
3
+ def get_document_revision(id)
4
+ login! unless logged_in?
5
+ json = <<-EOF
6
+ {
7
+ "session": "#{@sugar_session_id}",
8
+ "id": "#{id}"
9
+ }
10
+ EOF
11
+ json.gsub!(/^\s{6}/,'')
12
+ SugarCRM::Response.handle(send!(:get_document_revision, json), @session)
13
+ end
14
+ end; end
@@ -0,0 +1,23 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieve a list of SugarBeans by ID. This method will not
3
+ # work with the report module.
4
+ def get_entries(module_name, ids, opts={})
5
+ login! unless logged_in?
6
+ options = {
7
+ :fields => [],
8
+ :link_fields => [],
9
+ }.merge! opts
10
+
11
+ json = <<-EOF
12
+ {
13
+ "session": "#{@sugar_session_id}",
14
+ "module_name": "#{module_name}",
15
+ "ids": #{ids.to_json},
16
+ "select_fields": #{resolve_fields(module_name, options[:fields])},
17
+ "link_name_to_fields_array": #{options[:link_fields].to_json}
18
+ }
19
+ EOF
20
+ json.gsub!(/^\s{6}/,'')
21
+ SugarCRM::Response.handle(send!(:get_entries, json), @session)
22
+ end
23
+ end; end
@@ -0,0 +1,20 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieves the specified number of records in a module.
3
+ def get_entries_count(module_name, query, opts={})
4
+ login! unless logged_in?
5
+ options = {
6
+ :deleted => 0
7
+ }.merge! opts
8
+
9
+ json = <<-EOF
10
+ {
11
+ "session": "#{@sugar_session_id}",
12
+ "module_name": "#{module_name}",
13
+ "query": "#{query}",
14
+ "deleted": #{options[:deleted]}
15
+ }
16
+ EOF
17
+ json.gsub!(/^\s{6}/,'')
18
+ send!(:get_entries_count, json)
19
+ end
20
+ end; end
@@ -0,0 +1,23 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieves a single SugarBean based on the ID.
3
+ def get_entry(module_name, id, opts={})
4
+ login! unless logged_in?
5
+ options = {
6
+ :fields => [],
7
+ :link_fields => [],
8
+ }.merge! opts
9
+
10
+ json = <<-EOF
11
+ {
12
+ "session": "#{@sugar_session_id}",
13
+ "module_name": "#{module_name}",
14
+ "id": "#{id}",
15
+ "select_fields": #{resolve_fields(module_name, options[:fields])},
16
+ "link_name_to_fields_array": #{options[:link_fields].to_json}
17
+ }
18
+ EOF
19
+
20
+ json.gsub!(/^\s{6}/,'')
21
+ SugarCRM::Response.handle(send!(:get_entry, json), @session)
22
+ end
23
+ end; end
@@ -0,0 +1,31 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieve a list of SugarBeans. This is the primary method for getting
3
+ # a list of SugarBeans using the REST API.
4
+ def get_entry_list(module_name, query, opts={})
5
+ login! unless logged_in?
6
+ options = {
7
+ :order_by => '',
8
+ :offset => '',
9
+ :fields => [],
10
+ :link_fields => [],
11
+ :limit => '',
12
+ :deleted => 0
13
+ }.merge! opts
14
+
15
+ json = <<-EOF
16
+ {
17
+ "session": "#{@sugar_session_id}",
18
+ "module_name": "#{module_name}",
19
+ "query": "#{query}",
20
+ "order_by": "#{options[:order_by]}",
21
+ "offset": "#{options[:offset]}",
22
+ "select_fields": #{resolve_fields(module_name, options[:fields])},
23
+ "link_name_to_fields_array": #{options[:link_fields].to_json},
24
+ "max_results": "#{options[:limit]}",
25
+ "deleted": #{options[:deleted]}
26
+ }
27
+ EOF
28
+ json.gsub!(/^\s{6}/,'')
29
+ SugarCRM::Response.handle(send!(:get_entry_list, json), @session)
30
+ end
31
+ end; end
@@ -0,0 +1,15 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieves the vardef information of the specified bean.
3
+ def get_module_fields(module_name)
4
+ login! unless logged_in?
5
+ json = <<-EOF
6
+ {
7
+ "session": "#{@sugar_session_id}",
8
+ "module_name": "#{module_name}"
9
+ }
10
+ EOF
11
+ json.gsub!(/^\s{6}/,'')
12
+ SugarCRM::Response.handle(send!(:get_module_fields, json), @session)
13
+ end
14
+ alias :get_fields :get_module_fields
15
+ end; end
@@ -0,0 +1,14 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieves an attachment from a note.
3
+ def get_note_attachment(id)
4
+ login! unless logged_in?
5
+ json = <<-EOF
6
+ {
7
+ "session": "#{@sugar_session_id}",
8
+ "id": "#{id}"
9
+ }
10
+ EOF
11
+ json.gsub!(/^\s{6}/,'')
12
+ send!(:get_note_attachment, json)["note_attachment"]
13
+ end
14
+ end; end
@@ -0,0 +1,30 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieves a collection of beans that are related
3
+ # to the specified bean and, optionally, returns
4
+ # relationship data
5
+ def get_relationships(module_name, id, related_to, opts={})
6
+ login! unless logged_in?
7
+ options = {
8
+ :query => '',
9
+ :fields => [],
10
+ :link_fields => [],
11
+ :deleted => 0
12
+ }.merge! opts
13
+
14
+ json = <<-EOF
15
+ {
16
+ "session": "#{@sugar_session_id}",
17
+ "module_name": "#{module_name}",
18
+ "module_id": "#{id}",
19
+ "link_field_name": "#{related_to.downcase}",
20
+ "related_module_query": "#{options[:query]}",
21
+ "related_fields": #{resolve_related_fields(module_name, related_to)},
22
+ "related_module_link_name_to_fields_array": #{options[:link_fields].to_json},
23
+ "deleted": #{options[:deleted]}
24
+ }
25
+ EOF
26
+ json.gsub!(/^\s{6}/,'')
27
+ SugarCRM::Response.new(send!(:get_relationships, json), @session, {:always_return_array => true}).to_obj
28
+ end
29
+ alias :get_relationship :get_relationships
30
+ end; end
@@ -0,0 +1,17 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieves a list of report entries based on specified report IDs.
3
+ def get_report_entries(ids, opts={})
4
+ login! unless logged_in?
5
+ options = {:select_fields => ''}.merge! opts
6
+
7
+ json = <<-EOF
8
+ {
9
+ "session": "#{@sugar_session_id}",
10
+ "ids": #{ids.to_json},
11
+ "select_fields": "#{options[:select_fields].to_json}"
12
+ }
13
+ EOF
14
+ json.gsub!(/^\s{6}/,'')
15
+ send!(:get_report_entries, json)
16
+ end
17
+ end; end
@@ -0,0 +1,7 @@
1
+ module SugarCRM; class Connection
2
+ # Returns server information such as version, flavor, and gmt_time.
3
+ def get_server_info
4
+ login! unless logged_in?
5
+ Response.handle(send!(:get_server_info, ""), @session)
6
+ end
7
+ end; end
@@ -0,0 +1,13 @@
1
+ module SugarCRM; class Connection
2
+ # Returns the ID of the user who is logged into the current session.
3
+ def get_user_id
4
+ login! unless logged_in?
5
+ json = <<-EOF
6
+ {
7
+ "session": "#{@sugar_session_id}"
8
+ }
9
+ EOF
10
+ json.gsub!(/^\s{6}/,'')
11
+ send!(:get_user_id, json)
12
+ end
13
+ end; end
@@ -0,0 +1,14 @@
1
+ module SugarCRM; class Connection
2
+ # Retrieves the ID of the default team of the user
3
+ # who is logged into the current session.
4
+ def get_user_team_id
5
+ login! unless logged_in?
6
+ json = <<-EOF
7
+ {
8
+ "session": "#{@sugar_session_id}"
9
+ }
10
+ EOF
11
+ json.gsub!(/^\s{6}/,'')
12
+ send!(:get_user_team_id, json)
13
+ end
14
+ end; end
@@ -0,0 +1,18 @@
1
+ module SugarCRM; class Connection
2
+ # Logs the user into the Sugar application.
3
+ def login
4
+ connect! unless connected?
5
+ json = <<-EOF
6
+ {
7
+ "user_auth": {
8
+ "user_name": "#{@user}",
9
+ "password": "#{OpenSSL::Digest::MD5.new(@pass)}",
10
+ "version": 2
11
+ },
12
+ "application": "sugarcrm_rubygem"
13
+ }
14
+ EOF
15
+ json.gsub!(/^\s{6}/,'')
16
+ response = send!(:login, json)
17
+ end
18
+ end; end
@@ -0,0 +1,15 @@
1
+ module SugarCRM; class Connection
2
+ # Logs out of the Sugar user session.
3
+ def logout
4
+ login! unless logged_in?
5
+ json = <<-EOF
6
+ {
7
+ "user_auth": {
8
+ "session": "#{@sugar_session_id}"
9
+ }
10
+ }
11
+ EOF
12
+ json.gsub!(/^\s{6}/,'')
13
+ send!(:logout, json)
14
+ end
15
+ end; end
@@ -0,0 +1,13 @@
1
+ module SugarCRM; class Connection
2
+ # Performs a seamless login during synchronization.
3
+ def seamless_login
4
+ login! unless logged_in?
5
+ json = <<-EOF
6
+ {
7
+ "session": "#{@sugar_session_id}"
8
+ }
9
+ EOF
10
+ json.gsub!(/^\s{6}/,'')
11
+ response = send!(:seamless_login, json)
12
+ end
13
+ end; end