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