sugarcrm_emp 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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