ooor 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -42,7 +42,7 @@ class OpenObjectsController < ActionController::Base
42
42
  end
43
43
 
44
44
  def load_all_controllers(map)
45
- OpenObjectResource.all_loaded_models.each do |model|
45
+ Ooor.all_loaded_models.each do |model|
46
46
  map.resources model.gsub('.', '_').to_sym
47
47
  end
48
48
  end
@@ -1,11 +1,6 @@
1
1
  require 'xmlrpc/client'
2
2
  require 'activeresource'
3
3
 
4
- #TODO support name_search via search + param
5
- #see name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=None):
6
- #TODO support offset, limit and order
7
- #see def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
8
-
9
4
  class OpenObjectResource < ActiveResource::Base
10
5
 
11
6
  # ******************** class methods ********************
@@ -14,7 +9,7 @@ class OpenObjectResource < ActiveResource::Base
14
9
  cattr_accessor :logger
15
10
  attr_accessor :openerp_id, :info, :access_ids, :name, :openerp_model, :field_ids, :state, #model class attributes assotiated to the OpenERP ir.model
16
11
  :field_defined, :many2one_relations, :one2many_relations, :many2many_relations,
17
- :openerp_database, :all_loaded_models
12
+ :openerp_database, :user_id
18
13
 
19
14
  def class_name_from_model_key(model_key)
20
15
  model_key.split('.').collect {|name_part| name_part[0..0].upcase + name_part[1..-1]}.join
@@ -22,11 +17,6 @@ class OpenObjectResource < ActiveResource::Base
22
17
 
23
18
  def reload_fields_definition(force = false)
24
19
  if self != IrModel and self != IrModelFields and (force or not @field_defined)#TODO have a way to force reloading @field_ids too eventually
25
- unless @field_ids
26
- model_def = IrModel.find(:all, :domain => [['model', '=', @openerp_model]])
27
- @field_ids = model_def.field_id
28
- @access_ids = model_def.access_ids
29
- end
30
20
  fields = IrModelFields.find(@field_ids)
31
21
  @fields = {}
32
22
  @many2one_relations = {}
@@ -52,15 +42,14 @@ class OpenObjectResource < ActiveResource::Base
52
42
  def define_openerp_model(arg, url, database, user_id, pass, binding)
53
43
  param = (arg.is_a? OpenObjectResource) ? arg.attributes.merge(arg.relations) : {'model' => arg}
54
44
  model_key = param['model']
55
- @all_loaded_models ||= []
56
- all_loaded_models.push(model_key)
45
+ Ooor.all_loaded_models.push(model_key)
57
46
  model_class_name = class_name_from_model_key(model_key)
58
47
  logger.info "registering #{model_class_name} as a Rails ActiveResource Model wrapper for OpenObject #{model_key} model"
59
48
  definition = "
60
49
  class #{model_class_name} < OpenObjectResource
61
- self.site = '#{url}'
50
+ self.site = '#{url || Ooor.object_url}'
62
51
  self.user = #{user_id}
63
- self.password = '#{pass}'
52
+ self.password = #{pass || false}
64
53
  self.openerp_database = '#{database}'
65
54
  self.openerp_model = '#{model_key}'
66
55
  self.openerp_id = #{param['id'] || false}
@@ -84,8 +73,14 @@ class OpenObjectResource < ActiveResource::Base
84
73
  rpc_execute('search', domain, offset, limit, order, context, count)
85
74
  end
86
75
 
87
- def client
88
- @client ||= XMLRPC::Client.new2(@site.to_s.gsub(/\/$/,'')) #always remove trailing / to make OpenERP happy
76
+ def client(url)
77
+ @clients ||= {}
78
+ @client = @clients[url]
79
+ unless @clientl
80
+ @client ||= XMLRPC::Client.new2(url)
81
+ @clients[url] = @client
82
+ end
83
+ return @client
89
84
  end
90
85
 
91
86
  #corresponding method for OpenERP osv.execute(self, db, uid, obj, method, *args, **kw) method
@@ -94,25 +89,25 @@ class OpenObjectResource < ActiveResource::Base
94
89
  end
95
90
 
96
91
  def rpc_execute_with_object(object, method, *args)
97
- rpc_execute_with_all(@openerp_database, @user, @password, object, method, *args)
92
+ rpc_execute_with_all(@database || Ooor.config[:database], @user_id || Ooor.config[:user_id], @password || Ooor.config[:password], object, method, *args)
98
93
  end
99
94
 
100
95
  #corresponding method for OpenERP osv.execute(self, db, uid, obj, method, *args, **kw) method
101
96
  def rpc_execute_with_all(db, uid, pass, obj, method, *args)
102
- try_with_pretty_error_log { client.call("execute", db, uid, pass, obj, method, *args) }
97
+ try_with_pretty_error_log { client(@database && @site || Ooor.object_url).call("execute", db, uid, pass, obj, method, *args) }
103
98
  end
104
99
 
105
100
  #corresponding method for OpenERP osv.exec_workflow(self, db, uid, obj, method, *args)
106
- def rpc_exec_workflow(method, *args)
107
- rpc_exec_workflow_with_object(@openerp_model, method, *args)
101
+ def rpc_exec_workflow(action, *args)
102
+ rpc_exec_workflow_with_object(@openerp_model, action, *args)
108
103
  end
109
104
 
110
- def rpc_exec_workflow_with_object(object, method, *args)
111
- rpc_exec_workflow_with_all(@openerp_database, @user, @password, object, method, *args)
105
+ def rpc_exec_workflow_with_object(object, action, *args)
106
+ rpc_exec_workflow_with_all(@database || Ooor.config[:database], @user_id || Ooor.config[:user_id], @password || Ooor.config[:password], object, action, *args)
112
107
  end
113
108
 
114
- def rpc_exec_workflow_with_all(method, *args)
115
- try_with_pretty_error_log { client.call("exec_workflow", db, uid, pass, obj, method, *args) }
109
+ def rpc_exec_workflow_with_all(db, uid, pass, obj, action, *args)
110
+ try_with_pretty_error_log { client(@database && @site || Ooor.object_url).call("exec_workflow", db, uid, pass, obj, action, *args) }
116
111
  end
117
112
 
118
113
  #grab the eventual error log from OpenERP response as OpenERP doesn't enforce carefuly
@@ -134,6 +129,10 @@ class OpenObjectResource < ActiveResource::Base
134
129
 
135
130
  def load_relation(model_key, ids, *arguments)
136
131
  options = arguments.extract_options!
132
+ unless Ooor.all_loaded_models.index(model_key)
133
+ model = IrModel.find(:first, :domain => [['model', '=', model_key]])
134
+ define_openerp_model(model, nil, nil, nil, nil, Ooor.binding)
135
+ end
137
136
  relation_model_class = eval class_name_from_model_key(model_key)
138
137
  relation_model_class.send :find, ids, :fields => options[:fields] || [], :context => options[:context] || {}
139
138
  end
@@ -192,6 +191,8 @@ class OpenObjectResource < ActiveResource::Base
192
191
 
193
192
  # ******************** instance methods ********************
194
193
 
194
+ attr_accessor :ooor_user, :ooor_password
195
+
195
196
  def pre_cast_attributes
196
197
  @attributes.each {|k, v| @attributes[k] = ((v.is_a? BigDecimal) ? Float(v) : v)}
197
198
  end
@@ -205,7 +206,7 @@ class OpenObjectResource < ActiveResource::Base
205
206
  when Array
206
207
  relations[key.to_s] = value #the relation because we want the method to load the association through method missing
207
208
  when Hash
208
- resource = find_or_create_resource_for(key)
209
+ resource = find_or_create_resource_for(key) #TODO check!
209
210
  @attributes[key.to_s] = resource@attributes[key.to_s].new(value)
210
211
  else
211
212
  @attributes[key.to_s] = value.dup rescue value
@@ -247,11 +248,18 @@ class OpenObjectResource < ActiveResource::Base
247
248
  #Generic OpenERP on_change method
248
249
  def on_change(on_change_method, *args)
249
250
  result = self.class.rpc_execute(on_change_method, *args)
251
+ session
250
252
  self.classlogger.info result["warning"]["title"] if result["warning"]
251
253
  self.class.logger.info result["warning"]["message"] if result["warning"]
252
254
  load(result["value"])
253
255
  end
254
256
 
257
+ #wrapper for OpenERP exec_workflow Business Process Management engine
258
+ def wkf_action(action, context={})
259
+ self.class.rpc_exec_workflow(action, self.id) #FIXME looks like OpenERP exec_workflow doesn't accept context but it might be a bug
260
+ load(self.class.find(self.id, :context => context).attributes)
261
+ end
262
+
255
263
 
256
264
  # ******************** fake associations like much like ActiveRecord according to the cached OpenERP data model ********************
257
265
 
@@ -273,17 +281,19 @@ class OpenObjectResource < ActiveResource::Base
273
281
  end
274
282
 
275
283
  def method_missing(method_id, *arguments)
284
+ @loaded_relations ||= {}
285
+ result = @loaded_relations[method_id.to_s]
286
+ return result if result
276
287
  result = relationnal_result(method_id, *arguments)
277
288
  if result
278
- return result
289
+ @loaded_relations[method_id.to_s] = result
290
+ return result
279
291
  elsif @relations and @relations[method_id.to_s] and !self.class.many2one_relations.empty?
280
292
  #maybe the relation is inherited or could be inferred from a related field
281
293
  self.class.many2one_relations.each do |k, field|
282
294
  model = self.class.load_relation(field.relation, @relations[method_id.to_s][0], *arguments)
283
295
  result = model.relationnal_result(method_id, *arguments)
284
- if result
285
- return result
286
- end
296
+ return result if result
287
297
  end
288
298
  super
289
299
  end
data/lib/ooor.rb CHANGED
@@ -1,83 +1,72 @@
1
1
  require 'logger'
2
+ require 'xmlrpc/client'
2
3
 
3
4
  module Ooor
4
5
 
5
- @ooor_logger = ((defined?(RAILS_ENV) and RAILS_ENV != "development") ? Rails.logger : Logger.new(STDOUT))
6
-
7
- #load the custom configuration
8
- def self.load_config(config_file=nil, env=nil)
9
- config_file ||= defined?(RAILS_ROOT) && "#{RAILS_ROOT}/config/ooor.yml" || 'ooor.yml'
10
- env ||= defined?(RAILS_ENV) && RAILS_ENV || 'development'
11
- @ooor_config = YAML.load_file(config_file)[env]
12
- rescue SystemCallError
13
- @ooor_logger.error """failed to load OOOR yaml configuration file.
14
- make sure your app has a #{config_file} file correctly set up
15
- if not, just copy/paste the default ooor.yml file from the OOOR Gem
16
- to #{RAILS_ROOT}/config/ooor.yml and customize it properly\n\n"""
17
- raise
18
- end
6
+ class << self
19
7
 
20
- def self.loaded?
21
- OpenObjectResource.all_loaded_models.is_a? Array and OpenObjectResource.all_loaded_models.size > 0
22
- end
8
+ attr_accessor :logger, :config, :all_loaded_models, :binding, :common_url, :object_url
23
9
 
24
- def self.reload!(config=false, env=false, keep_config=false)
25
- @ooor_config = config.is_a?(Hash) && config or keep_config && @ooor_config or self.load_config(config, env)
26
- @ooor_config.symbolize_keys!
27
-
28
- begin
29
- url = @ooor_config[:url]
30
- database = @ooor_config[:database]
31
- user = @ooor_config[:username]
32
- pass = @ooor_config[:password]
33
- @ooor_logger.level = @ooor_config[:log_level] if @ooor_config[:log_level]
34
- rescue Exception => error
35
- @ooor_logger.error """ooor.yml failed: #{error.inspect}
36
- #{error.backtrace}
37
- You probably didn't configure the ooor.yml file properly because we can't load it"""
10
+ #load the custom configuration
11
+ def load_config(config_file=nil, env=nil)
12
+ config_file ||= defined?(RAILS_ROOT) && "#{RAILS_ROOT}/config/ooor.yml" || 'ooor.yml'
13
+ env ||= defined?(RAILS_ENV) && RAILS_ENV || 'development'
14
+ Ooor.config = YAML.load_file(config_file)[env]
15
+ rescue SystemCallError
16
+ Ooor.logger.error """failed to load OOOR yaml configuration file.
17
+ make sure your app has a #{config_file} file correctly set up
18
+ if not, just copy/paste the default ooor.yml file from the OOOR Gem
19
+ to #{RAILS_ROOT}/config/ooor.yml and customize it properly\n\n"""
38
20
  raise
39
21
  end
40
22
 
41
- require 'xmlrpc/client'
42
- begin
43
- login_url = url.gsub(/\/$/,'') + "/common"
44
- client = XMLRPC::Client.new2(login_url)
45
- user_id = client.call("login", database, user, pass)
23
+ def loaded?
24
+ Ooor.all_loaded_models.size > 0
25
+ end
26
+
27
+ def global_login(user, password)
28
+ begin
29
+ Ooor.config[:username] = user
30
+ Ooor.config[:password] = password
31
+ client = OpenObjectResource.client(Ooor.common_url)
32
+ OpenObjectResource.try_with_pretty_error_log { client.call("login", Ooor.config[:database], user, password)}
33
+ rescue SocketError => error
34
+ Ooor.logger.error """login to OpenERP server failed:
35
+ #{error.inspect}
36
+ Are your sure the server is started? Are your login parameters correct? Can this server ping the OpenERP server?
37
+ login XML/RPC url was #{Ooor.config[:url].gsub(/\/$/,'') + "/common"}"""
38
+ end
39
+ end
46
40
 
41
+ def reload!(config=false, env=false, keep_config=false)
42
+ Ooor.config = config.is_a?(Hash) && config or keep_config && Ooor.config or self.load_config(config, env)
43
+ Ooor.config.symbolize_keys!
44
+ Ooor.logger.level = Ooor.config[:log_level] if Ooor.config[:log_level]
45
+ Ooor.common_url = Ooor.config[:url].gsub(/\/$/,'') + "/common"
46
+ Ooor.object_url = Ooor.config[:url].gsub(/\/$/,'') + "/object"
47
+ Ooor.config[:user_id] = global_login(Ooor.config[:username] || 'admin', Ooor.config[:password] || 'admin')
47
48
 
48
49
  #*************** load the models
49
50
 
50
- models_url = url.gsub(/\/$/,'') + "/object"
51
- OpenObjectResource.logger = @ooor_logger
52
- @ooor_binding = lambda {}
53
- OpenObjectResource.define_openerp_model("ir.model", models_url, database, user_id, pass, @ooor_binding)
54
- OpenObjectResource.define_openerp_model("ir.model.fields", models_url, database, user_id, pass, @ooor_binding)
55
-
51
+ Ooor.all_loaded_models = []
52
+ OpenObjectResource.logger = Ooor.logger
53
+ OpenObjectResource.define_openerp_model("ir.model", nil, nil, nil, nil, Ooor.binding)
54
+ OpenObjectResource.define_openerp_model("ir.model.fields", nil, nil, nil, nil, Ooor.binding)
56
55
 
57
- if @ooor_config[:models] #we load only a customized subset of the OpenERP models
58
- models = IrModel.find(:all, :domain => [['model', 'in', @ooor_config[:models]]])
56
+ if Ooor.config[:models] #we load only a customized subset of the OpenERP models
57
+ models = IrModel.find(:all, :domain => [['model', 'in', Ooor.config[:models]]])
59
58
  else #we load all the models
60
59
  models = IrModel.find(:all)
61
60
  end
62
61
 
63
- models.each {|openerp_model| OpenObjectResource.define_openerp_model(openerp_model, models_url, database, user_id, pass, @ooor_binding) }
64
-
62
+ models.each {|openerp_model| OpenObjectResource.define_openerp_model(openerp_model, nil, nil, nil, nil, Ooor.binding)}
65
63
 
66
64
  # *************** load the models REST controllers
67
65
  if defined?(ActionController)
68
- OpenObjectsController.logger = @ooor_logger
69
- models.each {|openerp_model| OpenObjectsController.define_openerp_controller(openerp_model.model, @ooor_binding) }
66
+ OpenObjectsController.logger = Ooor.logger
67
+ models.each {|openerp_model| OpenObjectsController.define_openerp_controller(openerp_model.model, Ooor.binding) }
70
68
  end
71
69
 
72
-
73
- rescue SystemCallError => error
74
- @ooor_logger.error """login to OpenERP server failed:
75
- #{error.inspect}
76
- #{error.backtrace}
77
- Are your sure the server is started? Are your login parameters correct? Can this server ping the OpenERP server?
78
- login XML/RPC url was #{login_url}
79
- database: #{database}; user name: #{user}; password: #{pass}
80
- OOOR plugin not loaded! Continuing..."""
81
70
  end
82
71
 
83
72
  end
@@ -85,6 +74,9 @@ module Ooor
85
74
  end
86
75
 
87
76
 
77
+ Ooor.logger = ((defined?(RAILS_ENV) and RAILS_ENV != "development") ? Rails.logger : Logger.new(STDOUT))
78
+ Ooor.binding = lambda {}
79
+
88
80
  require 'app/models/open_object_resource'
89
81
  require 'app/controllers/open_objects_controller'
90
82
 
data/ooor.yml ADDED
@@ -0,0 +1,27 @@
1
+ #In order Rails knows how to t=connect to your OpenERP server, you should create a file APPLICATION_ROOT/config/ooor.yml
2
+ #with the following pattern customized with your OpenERP server URL, your target OpenERP database, your login and password.
3
+
4
+ development:
5
+ url: http://localhost:8069/xmlrpc #the OpenERP XML/RPC server
6
+ database: database_name #the OpenERP database you want to connect to
7
+ username: admin
8
+ password: admin
9
+ #comment the following line if you want to load ALL the available models (slower startup), or complete it with all the OpenERP models you want to be loaded
10
+ models: [res.partner, product.template, product.product, product.category, sale.order, sale.order.line, account.invoice]
11
+ bootstrap: true #true if you want to load OpenObject models (will hit OpenERP server) at startup; else use Ooor.reload!(lambda {}) to reload the Ooor models at any time
12
+
13
+ test:
14
+ url: http://localhost:8069/xmlrpc
15
+ database: database_name
16
+ username: admin
17
+ password: admin
18
+ models: [res.partner, product.template, product.product, product.category, sale.order, sale.order.line, account.invoice]
19
+ bootstrap: true
20
+
21
+ production:
22
+ url: http://localhost:8069/xmlrpc
23
+ database: database_name
24
+ username: admin
25
+ password: admin
26
+ models: [res.partner, product.template, product.product, product.category, sale.order, sale.order.line, account.invoice]
27
+ bootstrap: true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ooor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raphael Valyi - www.akretion.com
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-04 00:00:00 -02:00
12
+ date: 2009-11-08 00:00:00 -02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -36,6 +36,7 @@ files:
36
36
  - lib/ooor.rb
37
37
  - lib/app/models/open_object_resource.rb
38
38
  - lib/app/controllers/open_objects_controller.rb
39
+ - ooor.yml
39
40
  has_rdoc: true
40
41
  homepage: http://github.com/rvalyi/ooor
41
42
  licenses: []