ooor 1.3.2 → 1.4.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.
- data/README.md +13 -1
- data/agpl-3.0-licence.txt +661 -0
- data/lib/app/models/base64.rb +31 -0
- data/lib/app/models/common_service.rb +17 -0
- data/lib/app/models/db_service.rb +20 -2
- data/lib/app/models/open_object_resource.rb +86 -68
- data/lib/app/models/uml.rb +20 -3
- data/lib/app/ui/action_window.rb +17 -0
- data/lib/app/ui/client_base.rb +17 -0
- data/lib/app/ui/form_model.rb +17 -0
- data/lib/app/ui/menu.rb +17 -0
- data/lib/ooor.rb +24 -10
- data/ooor.yml +1 -4
- data/spec/ooor_spec.rb +31 -3
- metadata +6 -5
- data/MIT-LICENSE +0 -20
@@ -0,0 +1,31 @@
|
|
1
|
+
# OOOR: Open Object On Rails
|
2
|
+
# Copyright (C) 2009-2010 Akretion LTDA (<http://www.akretion.com>).
|
3
|
+
# Author: Raphaël Valyi
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require 'base64'
|
19
|
+
module Base64
|
20
|
+
def serialize_binary_from_file(binary_path)
|
21
|
+
return Base64.encode64(File.read(binary_path))
|
22
|
+
end
|
23
|
+
|
24
|
+
def serialize_binary_from_content(content)
|
25
|
+
return Base64.encode64(content)
|
26
|
+
end
|
27
|
+
|
28
|
+
def unserialize_binary(content)
|
29
|
+
return Base64.decode64(content)
|
30
|
+
end
|
31
|
+
end
|
@@ -1,3 +1,20 @@
|
|
1
|
+
# OOOR: Open Object On Rails
|
2
|
+
# Copyright (C) 2009-2010 Akretion LTDA (<http://www.akretion.com>).
|
3
|
+
# Author: Raphaël Valyi
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
1
18
|
#proxies all 'common' class of OpenERP server/bin/service/web_service.py properly
|
2
19
|
module CommonService
|
3
20
|
def global_login(user, password)
|
@@ -1,9 +1,27 @@
|
|
1
|
+
# OOOR: Open Object On Rails
|
2
|
+
# Copyright (C) 2009-2010 Akretion LTDA (<http://www.akretion.com>).
|
3
|
+
# Author: Raphaël Valyi
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
1
18
|
#proxies all 'db' class of OpenERP server/bin/service/web_service.py properly
|
2
19
|
module DbService
|
3
|
-
def create(password=@config[:db_password], db_name='ooor_db', demo=true, lang='
|
20
|
+
def create(password=@config[:db_password], db_name='ooor_db', demo=true, lang='en_US', user_password=@config[:password] || 'admin')
|
4
21
|
process_id = OpenObjectResource.try_with_pretty_error_log { OpenObjectResource.client(@base_url + "/db").call("create", password, db_name, demo, lang, user_password) }
|
5
22
|
@config[:database] = db_name
|
6
|
-
@config[:username] =
|
23
|
+
@config[:username] = 'admin'
|
24
|
+
@config[:passowrd] = user_password
|
7
25
|
while get_progress('admin', process_id) == [0, []]
|
8
26
|
@logger.info "..."
|
9
27
|
sleep(0.5)
|
@@ -1,11 +1,25 @@
|
|
1
|
+
# OOOR: Open Object On Rails
|
2
|
+
# Copyright (C) 2009-2010 Akretion LTDA (<http://www.akretion.com>).
|
3
|
+
# Author: Raphaël Valyi
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
1
18
|
require 'xmlrpc/client'
|
2
19
|
require 'rubygems'
|
3
20
|
require 'active_resource'
|
4
21
|
require 'app/ui/form_model'
|
5
22
|
require 'app/models/uml'
|
6
|
-
require 'set'
|
7
|
-
|
8
|
-
#TODO implement passing session credentials to RPC methods (concurrent access of different user credentials in Rails)
|
9
23
|
|
10
24
|
class OpenObjectResource < ActiveResource::Base
|
11
25
|
include UML
|
@@ -25,27 +39,31 @@ class OpenObjectResource < ActiveResource::Base
|
|
25
39
|
#similar to Object#const_get but for OpenERP model key
|
26
40
|
def const_get(model_key)
|
27
41
|
klass_name = class_name_from_model_key(model_key)
|
28
|
-
klass = (self.scope_prefix ? Object.const_get(self.scope_prefix) : Object).const_defined?(klass_name) ? (self.scope_prefix ? Object.const_get(self.scope_prefix) : Object).const_get(klass_name) : @ooor.define_openerp_model(model_key, self.scope_prefix)
|
42
|
+
klass = (self.scope_prefix ? Object.const_get(self.scope_prefix) : Object).const_defined?(klass_name) ? (self.scope_prefix ? Object.const_get(self.scope_prefix) : Object).const_get(klass_name) : @ooor.define_openerp_model({'model' => model_key}, self.scope_prefix)
|
29
43
|
klass.reload_fields_definition unless klass.fields_defined
|
30
44
|
klass
|
31
45
|
end
|
32
46
|
|
47
|
+
def create(attributes = {}, context={}, default_get_list=false, reload=true)
|
48
|
+
self.new(attributes, default_get_list, context).tap { |resource| resource.save(context, reload) }
|
49
|
+
end
|
50
|
+
|
33
51
|
def reload_fields_definition(force = false)
|
34
|
-
if
|
35
|
-
|
52
|
+
if force or not @fields_defined
|
53
|
+
@fields_defined = true
|
36
54
|
@fields = {}
|
37
|
-
|
38
|
-
case field
|
55
|
+
rpc_execute("fields_get").each do |k, field|
|
56
|
+
case field['type']
|
39
57
|
when 'many2one'
|
40
|
-
@many2one_relations[
|
58
|
+
@many2one_relations[k] = field
|
41
59
|
when 'one2many'
|
42
|
-
@one2many_relations[
|
60
|
+
@one2many_relations[k] = field
|
43
61
|
when 'many2many'
|
44
|
-
@many2many_relations[
|
62
|
+
@many2many_relations[k] = field
|
45
63
|
when 'reference'
|
46
|
-
@polymorphic_m2o_relations[
|
64
|
+
@polymorphic_m2o_relations[k] = field
|
47
65
|
else
|
48
|
-
@fields[
|
66
|
+
@fields[k] = field
|
49
67
|
end
|
50
68
|
end
|
51
69
|
@relations_keys = @many2one_relations.keys + @one2many_relations.keys + @many2many_relations.keys + @polymorphic_m2o_relations.keys
|
@@ -60,7 +78,6 @@ class OpenObjectResource < ActiveResource::Base
|
|
60
78
|
end
|
61
79
|
logger.info "#{fields.size} fields loaded in model #{self.class}"
|
62
80
|
end
|
63
|
-
@fields_defined = true
|
64
81
|
end
|
65
82
|
|
66
83
|
# ******************** remote communication ********************
|
@@ -72,7 +89,7 @@ class OpenObjectResource < ActiveResource::Base
|
|
72
89
|
|
73
90
|
def client(url)
|
74
91
|
@clients ||= {}
|
75
|
-
@clients[url] ||= XMLRPC::Client.new2(url, nil,
|
92
|
+
@clients[url] ||= XMLRPC::Client.new2(url, nil, 900)
|
76
93
|
end
|
77
94
|
|
78
95
|
#corresponding method for OpenERP osv.execute(self, db, uid, obj, method, *args, **kw) method
|
@@ -163,7 +180,7 @@ class OpenObjectResource < ActiveResource::Base
|
|
163
180
|
def cast_map_to_ruby!(map)
|
164
181
|
map.each do |k, v|
|
165
182
|
if self.fields[k] && v.is_a?(String) && !v.empty?
|
166
|
-
case self.fields[k]
|
183
|
+
case self.fields[k]['type']
|
167
184
|
when 'datetime'
|
168
185
|
map[k] = Time.parse(v)
|
169
186
|
when 'date'
|
@@ -231,7 +248,7 @@ class OpenObjectResource < ActiveResource::Base
|
|
231
248
|
record.each_pair do |k,v|
|
232
249
|
r[k.to_sym] = v
|
233
250
|
end
|
234
|
-
active_resources << instantiate_record(r, prefix_options)
|
251
|
+
active_resources << instantiate_record(r, prefix_options, context)
|
235
252
|
end
|
236
253
|
unless is_collection
|
237
254
|
return active_resources[0]
|
@@ -240,8 +257,8 @@ class OpenObjectResource < ActiveResource::Base
|
|
240
257
|
end
|
241
258
|
|
242
259
|
#overriden because loading default fields is all the rage but we don't want them when reading a record
|
243
|
-
def instantiate_record(record, prefix_options = {})
|
244
|
-
new(record, [],
|
260
|
+
def instantiate_record(record, prefix_options = {}, context = {})
|
261
|
+
new(record, [], context).tap do |resource|
|
245
262
|
resource.prefix_options = prefix_options
|
246
263
|
end
|
247
264
|
end
|
@@ -251,7 +268,21 @@ class OpenObjectResource < ActiveResource::Base
|
|
251
268
|
|
252
269
|
# ******************** instance methods ********************
|
253
270
|
|
254
|
-
attr_accessor :relations, :loaded_relations, :ir_model_data_id
|
271
|
+
attr_accessor :relations, :loaded_relations, :ir_model_data_id, :object_session
|
272
|
+
|
273
|
+
def object_db; object_session[:database] || self.class.database || self.class.ooor.config[:database]; end
|
274
|
+
def object_uid;object_session[:user_id] || self.class.user_id || self.class.ooor.config[:user_id]; end
|
275
|
+
def object_pass; object_session[:password] || self.class.password || self.class.ooor.config[:password]; end
|
276
|
+
|
277
|
+
#try to wrap the object context inside the query.
|
278
|
+
def rpc_execute(method, *args)
|
279
|
+
if args[-1].is_a? Hash
|
280
|
+
args[-1] = self.class.ooor.global_context.merge(object_session[:context]).merge(args[-1])
|
281
|
+
elsif args.is_a?(Array)
|
282
|
+
args += [self.class.ooor.global_context.merge(object_session[:context])]
|
283
|
+
end
|
284
|
+
self.class.rpc_execute_with_all(object_db, object_uid, object_pass, self.class.openerp_model, method, *args)
|
285
|
+
end
|
255
286
|
|
256
287
|
def cast_relations_to_openerp!
|
257
288
|
@relations.reject! do |k, v| #reject non asigned many2one or empty list
|
@@ -282,7 +313,7 @@ class OpenObjectResource < ActiveResource::Base
|
|
282
313
|
@relations[k] = new_rel
|
283
314
|
else
|
284
315
|
self.class.many2one_relations.each do |k2, field| #try to cast the relation to an inherited o2m or m2m:
|
285
|
-
linked_class = self.class.const_get(field
|
316
|
+
linked_class = self.class.const_get(field['relation'])
|
286
317
|
new_rel = self.cast_relation(k, v, linked_class.one2many_relations, linked_class.many2many_relations)
|
287
318
|
@relations[k] = new_rel and break if new_rel
|
288
319
|
end
|
@@ -323,13 +354,12 @@ class OpenObjectResource < ActiveResource::Base
|
|
323
354
|
end
|
324
355
|
|
325
356
|
def display_available_fields
|
326
|
-
msg = "\n***
|
327
|
-
msg << "\n\n" << self.class.fields.sort {|a,b| a[1]
|
328
|
-
msg << "\n\n" << self.class.many2one_relations.map {|k, v| "many2one --- #{v
|
329
|
-
msg << "\n\n" << self.class.one2many_relations.map {|k, v| "one2many --- #{v
|
330
|
-
msg << "\n\n" << self.class.many2many_relations.map {|k, v| "many2many --- #{v
|
331
|
-
msg << "\n\n" << self.class.polymorphic_m2o_relations.map {|k, v| "polymorphic_m2o --- #{v
|
332
|
-
msg << "\n\nYOU CAN ALSO USE THE INHERITED FIELDS FROM THE INHERITANCE MANY2ONE RELATIONS OR THE OBJECT METHODS...\n\n"
|
357
|
+
msg = "\n*** AVAILABLE FIELDS ON OBJECT #{self} ARE: ***"
|
358
|
+
msg << "\n\n" << self.class.fields.sort {|a,b| a[1]['type']<=>b[1]['type']}.map {|i| "#{i[1]['type']} --- #{i[0]}"}.join("\n")
|
359
|
+
msg << "\n\n" << self.class.many2one_relations.map {|k, v| "many2one --- #{v['relation']} --- #{k}"}.join("\n")
|
360
|
+
msg << "\n\n" << self.class.one2many_relations.map {|k, v| "one2many --- #{v['relation']} --- #{k}"}.join("\n")
|
361
|
+
msg << "\n\n" << self.class.many2many_relations.map {|k, v| "many2many --- #{v['relation']} --- #{k}"}.join("\n")
|
362
|
+
msg << "\n\n" << self.class.polymorphic_m2o_relations.map {|k, v| "polymorphic_m2o --- #{v['relation']} --- #{k}"}.join("\n")
|
333
363
|
self.class.logger.debug msg
|
334
364
|
end
|
335
365
|
|
@@ -339,49 +369,55 @@ class OpenObjectResource < ActiveResource::Base
|
|
339
369
|
end
|
340
370
|
|
341
371
|
#takes care of reading OpenERP default field values.
|
342
|
-
#FIXME: until OpenObject explicits inheritances, we load all default values of all related fields, unless specified in default_get_list
|
343
372
|
def initialize(attributes = {}, default_get_list=false, context={})
|
344
|
-
@attributes
|
373
|
+
@attributes = {}
|
345
374
|
@prefix_options = {}
|
346
375
|
@ir_model_data_id = attributes.delete(:ir_model_data_id)
|
347
|
-
|
376
|
+
@object_session = {}
|
377
|
+
@object_session[:user_id] = context.delete :user_id
|
378
|
+
@object_session[:database] = context.delete :database
|
379
|
+
@object_session[:password] = context.delete :password
|
380
|
+
@object_session[:context] = context
|
381
|
+
if default_get_list == []
|
348
382
|
load(attributes)
|
349
383
|
else
|
350
|
-
|
351
|
-
default_get_list ||= Set.new(self.class.many2one_relations.reject {|k, v| attributes.keys.index(k.to_sym)}.collect {|k, field| self.class.const_get(field.relation).fields.keys}.flatten + self.class.fields.keys).to_a
|
352
|
-
load(self.class.rpc_execute("default_get", default_get_list, context).symbolize_keys!.merge(attributes.symbolize_keys!))
|
384
|
+
load(rpc_execute("default_get", rpc_execute("fields_get").keys, @object_session[:context]).symbolize_keys!.merge(attributes.symbolize_keys!))
|
353
385
|
end
|
354
386
|
end
|
355
387
|
|
388
|
+
def save(context={}, reload=true)
|
389
|
+
new? ? create(context, reload) : update(context, reload)
|
390
|
+
end
|
391
|
+
|
356
392
|
#compatible with the Rails way but also supports OpenERP context
|
357
393
|
def create(context={}, reload=true)
|
358
|
-
self.id =
|
394
|
+
self.id = rpc_execute('create', to_openerp_hash!, context)
|
359
395
|
IrModelData.create(:model => self.class.openerp_model, :module => @ir_model_data_id[0], :name=> @ir_model_data_id[1], :res_id => self.id) if @ir_model_data_id
|
360
396
|
reload_from_record!(self.class.find(self.id, :context => context)) if reload
|
361
397
|
end
|
362
398
|
|
363
399
|
#compatible with the Rails way but also supports OpenERP context
|
364
400
|
def update(context={}, reload=true)
|
365
|
-
|
401
|
+
rpc_execute('write', self.id, to_openerp_hash!, context)
|
366
402
|
reload_from_record!(self.class.find(self.id, :context => context)) if reload
|
367
403
|
end
|
368
404
|
|
369
405
|
#compatible with the Rails way but also supports OpenERP context
|
370
406
|
def destroy(context={})
|
371
|
-
|
407
|
+
rpc_execute('unlink', [self.id], context)
|
372
408
|
end
|
373
409
|
|
374
410
|
#OpenERP copy method, load persisted copied Object
|
375
411
|
def copy(defaults={}, context={})
|
376
|
-
self.class.find(
|
412
|
+
self.class.find(rpc_execute('copy', self.id, defaults, context), :context => context)
|
377
413
|
end
|
378
414
|
|
379
415
|
#Generic OpenERP rpc method call
|
380
|
-
def call(method, *args)
|
416
|
+
def call(method, *args) rpc_execute(method, *args) end
|
381
417
|
|
382
418
|
#Generic OpenERP on_change method
|
383
419
|
def on_change(on_change_method, field_name, field_value, *args)
|
384
|
-
result = self.class.
|
420
|
+
result = self.class.rpc_execute_with_all(object_db, object_uid, object_pass, self.class.openerp_model, on_change_method, self.id && [id] || [], *args) #OpenERP doesn't accept context systematically in on_change events unfortunately
|
385
421
|
if result["warning"]
|
386
422
|
self.class.logger.info result["warning"]["title"]
|
387
423
|
self.class.logger.info result["warning"]["message"]
|
@@ -390,9 +426,9 @@ class OpenObjectResource < ActiveResource::Base
|
|
390
426
|
end
|
391
427
|
|
392
428
|
#wrapper for OpenERP exec_workflow Business Process Management engine
|
393
|
-
def wkf_action(action, context={})
|
394
|
-
self.class.
|
395
|
-
reload_from_record!(self.class.find(self.id, :context => context))
|
429
|
+
def wkf_action(action, context={}, reload=true)
|
430
|
+
self.class.rpc_exec_workflow_with_all(object_db, object_uid, object_pass, self.class.openerp_model, action, self.id) #FIXME looks like OpenERP exec_workflow doesn't accept context but it might be a bug
|
431
|
+
reload_from_record!(self.class.find(self.id, :context => context)) if reload
|
396
432
|
end
|
397
433
|
|
398
434
|
def old_wizard_step(wizard_name, step='init', wizard_id=nil, form={}, context={})
|
@@ -408,11 +444,11 @@ class OpenObjectResource < ActiveResource::Base
|
|
408
444
|
def relationnal_result(method_name, *arguments)
|
409
445
|
self.class.reload_fields_definition unless self.class.fields_defined
|
410
446
|
if self.class.many2one_relations.has_key?(method_name)
|
411
|
-
load_relation(self.class.many2one_relations[method_name]
|
447
|
+
load_relation(self.class.many2one_relations[method_name]['relation'], @relations[method_name][0], *arguments)
|
412
448
|
elsif self.class.one2many_relations.has_key?(method_name)
|
413
|
-
load_relation(self.class.one2many_relations[method_name]
|
449
|
+
load_relation(self.class.one2many_relations[method_name]['relation'], @relations[method_name], *arguments)
|
414
450
|
elsif self.class.many2many_relations.has_key?(method_name)
|
415
|
-
load_relation(self.class.many2many_relations[method_name]
|
451
|
+
load_relation(self.class.many2many_relations[method_name]['relation'], @relations[method_name], *arguments)
|
416
452
|
elsif self.class.polymorphic_m2o_relations.has_key?(method_name)
|
417
453
|
values = @relations[method_name].split(',')
|
418
454
|
load_relation(values[0], values[1].to_i, *arguments)
|
@@ -426,18 +462,18 @@ class OpenObjectResource < ActiveResource::Base
|
|
426
462
|
is_assign = method_name.end_with?('=')
|
427
463
|
method_key = method_name.sub('=', '')
|
428
464
|
return super if attributes.has_key?(method_key)
|
429
|
-
return
|
465
|
+
return rpc_execute(method_name, *arguments) unless arguments.empty? || is_assign
|
430
466
|
|
431
467
|
self.class.reload_fields_definition() unless self.class.fields_defined
|
432
468
|
|
433
469
|
if is_assign
|
434
|
-
known_relations = self.class.relations_keys + self.class.many2one_relations.collect {|k, field| self.class.const_get(field
|
470
|
+
known_relations = self.class.relations_keys + self.class.many2one_relations.collect {|k, field| self.class.const_get(field['relation']).relations_keys}.flatten
|
435
471
|
if known_relations.index(method_key)
|
436
472
|
@relations[method_key] = arguments[0]
|
437
473
|
@loaded_relations[method_key] = arguments[0]
|
438
474
|
return
|
439
475
|
end
|
440
|
-
know_fields = self.class.fields.keys + self.class.many2one_relations.collect {|k, field| self.class.const_get(field
|
476
|
+
know_fields = self.class.fields.keys + self.class.many2one_relations.collect {|k, field| self.class.const_get(field['relation']).fields.keys}.flatten
|
441
477
|
@attributes[method_key] = arguments[0] and return if know_fields.index(method_key)
|
442
478
|
end
|
443
479
|
|
@@ -450,27 +486,9 @@ class OpenObjectResource < ActiveResource::Base
|
|
450
486
|
result = relationnal_result(method_name, *arguments)
|
451
487
|
@loaded_relations[method_name] = result and return result if result
|
452
488
|
|
453
|
-
#maybe the relation is inherited or could be inferred from a related field
|
454
|
-
self.class.many2one_relations.each do |k, field| #TODO could be recursive eventually
|
455
|
-
if @relations[k] #we only care if instance has a relation
|
456
|
-
related_model = self.class.const_get(field.relation)
|
457
|
-
related_model.reload_fields_definition() unless related_model.fields_defined
|
458
|
-
if related_model.relations_keys.index(method_key)
|
459
|
-
@loaded_relations[k] ||= load_relation(field.relation, @relations[k][0], *arguments)
|
460
|
-
model = @loaded_relations[k]
|
461
|
-
model.loaded_relations[method_key] ||= model.relationnal_result(method_key, *arguments)
|
462
|
-
return model.loaded_relations[method_key] if model.loaded_relations[method_key]
|
463
|
-
end
|
464
|
-
elsif is_assign
|
465
|
-
klazz = self.class.const_get(field.relation)
|
466
|
-
@relations[method_key] = arguments[0] and return if klazz.relations_keys.index(method_key)
|
467
|
-
@attributes[method_key] = arguments[0] and return if klazz.fields.keys.index(method_key)
|
468
|
-
end
|
469
|
-
end
|
470
|
-
|
471
489
|
if id
|
472
490
|
arguments += [{}] unless arguments.last.is_a?(Hash)
|
473
|
-
|
491
|
+
rpc_execute(method_key, [id], *arguments) #we assume that's an action
|
474
492
|
else
|
475
493
|
super
|
476
494
|
end
|
data/lib/app/models/uml.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# OOOR: Open Object On Rails
|
2
|
+
# Copyright (C) 2009-2010 Akretion LTDA (<http://www.akretion.com>).
|
3
|
+
# Author: Raphaël Valyi
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
1
18
|
module UML
|
2
19
|
#usage: UML.print_uml or with options: UML.print_uml(:all, : detailed) or MyOpenObjectResource.print_uml or UML.print_uml([list_of_classes], :all, :detailed)
|
3
20
|
|
@@ -17,7 +34,7 @@ module UML
|
|
17
34
|
def self.display_fields(clazz)
|
18
35
|
s = ""
|
19
36
|
clazz.reload_fields_definition if clazz.fields.empty?
|
20
|
-
clazz.fields.sort {|a,b| a[1]
|
37
|
+
clazz.fields.sort {|a,b| a[1]['type'] <=> b[1]['type']}.each {|i| s << "+ #{i[1]['type']} : #{i[0]}\\l\\n"}
|
21
38
|
s
|
22
39
|
end
|
23
40
|
|
@@ -170,8 +187,8 @@ module UML
|
|
170
187
|
private
|
171
188
|
|
172
189
|
def self.get_target(is_reverse, local, enabled_targets, field, model)
|
173
|
-
if (is_reverse && !local) || (!enabled_targets) || enabled_targets.index(field
|
174
|
-
model.const_get(field
|
190
|
+
if (is_reverse && !local) || (!enabled_targets) || enabled_targets.index(field['relation'])
|
191
|
+
model.const_get(field['relation'])
|
175
192
|
else
|
176
193
|
false
|
177
194
|
end
|
data/lib/app/ui/action_window.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# OOOR: Open Object On Rails
|
2
|
+
# Copyright (C) 2009-2010 Akretion LTDA (<http://www.akretion.com>).
|
3
|
+
# Author: Raphaël Valyi
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Affero General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Affero General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
1
18
|
module ActionWindowModule
|
2
19
|
def open(mode='tree', ids=nil)
|
3
20
|
if view_mode.index(mode)
|