Giter Club home page Giter Club logo

ooor's Introduction

Build Status Code Climate Coverage Status Gem Version Dependency Status

OOOR by Akretion

Why use Ooor?

  • Ooor is an administration Swiss Army knife in an interactive Ruby session. You connect remotely to any running Odoo instance without stopping it, without compromising its security. It has tab auto-completion and object introspection features. You can script anything you would do in the web interface or in an Odoo module with the same level of query optimization.
  • Ooor is the basis for unleashed web development. It is Rack based and inject proxies to Odoo entities in your Rack env just like you use them in your env registry in Odoo modules. You use it in popular Ruby web frameworks such as Sinatra or Rails.

Odoo is all the rage for efficiently building an ERP back-office, but sometimes you want freedom and scalablity for your web front ends. Ooor enables you to model your web app using standard web frameworks like Rails while using Odoo as the persistence layer - without data duplication or synchronization/mapping logic - and reusing the Odoo business logic. Ooor even has an optionnal Rack filter that enables you to proxy some Odoo applications of your choice (say the shopping cart for instance) and share the HTTP session with it.

Because Ooor is ActiveModel based and emulates the ActiveRecord API well enough, it just works with popular Ruby gems such as Devise for authentication, will_paginate for pagination, SimpleForm, Cocoon for nested forms...

Ooor is also a lot more advanced than its Python clones: it is very carefuly designed to save Odoo requests. It can avoid the N+1 queries and also works smartly with the Rails cache so that the meta-data used to define the Odoo proxies can be cached shared between concurrent Rails workers without the need to hit Odoo again with requests such as fields_get.

Related projects - a full web stack!

  • Ooorest, Ooor is the Model layer of MVC. Ooorest is the Controller layer, enforcing a clean Railish REST API and offering handy helper to use Odoo in your Rails application.
  • Aktooor, Aktooor is the missing View layer of MVC. It's based on SimpleForm, that is a clean minimalist framework that extend Rails form framework over Twitter Bootstrap
  • Erpify, Erpify is Odoo inside the Liquid non evaling language, that is the templating language of Shopify or LocomotiveCMS for instance.
  • Locomotive-erpify, Erpify for LocomotiveCMS, both the engine and the Wagon local editor
  • Solarize, pulling data from Odoo relational database may not scale to your need. No problem with Solarize: you can index your OpenERP data with the Solerp OpenERP module, then search it using SolR API and even load it from SolR without even hitting OpenERP!
  • TerminatOOOR, a Pentaho ETL Kettle plugin allowing to push/pull data into/from Odoo with an incomparable flexibility and yet benefit all standard ETL features, including the AgileBI OLAP business intelligence plugin.

How?

Odoo is a Python based open source ERP. But every Odoo business method is actually exposed as a JSON-RPC webservice (SOA orientation, close to being RESTful). Ooor doesn't connect to the Odoo database directly, Instead it uses the Odoo JSON-RPC API so it fully enforces Odoo security model and business logic.

Ooor is around 2000 lines of code and has a test coverage over 93%. The API it exposes is not invented but it is the one of Rails: it is modeled after Rails ActiveModel, ActiveResource and ActiveRecord layers.

More specifically, an Odoo Ooor proxy implements the ActiveModel API. Instead of depending on ActiveResource which is actually a bit different (not multi-tenant, little access right management), we copied a tiny subset of it in the mini_active_resource.rb file and Odoo proxies include this module. Finally Ooor emulates the ActiveRecord API wherever possible delegating its requests to Odoo using Odoo domain S expressions instead of SQL. The ActiveRecord API emulation is actually pretty good: think Ooor looks more like ActiveRecord than Mongoid; it has associations, surface ARel API, Reflection API, can be paginated via Kaminary, can be integrated with SimpleForm or Cocoon seamlessly...

Ooor features several session modes: in the default IRB console usage it uses a global login scheme and generate constants for your OpenERP proxies, such as ProductProduct for the product.product OpenERP object much like Rails ActiveRecord. In web mode instead, you can have several sessions and do session['product.product'] to get a proxy to the Product object matching your current session credentials, chosen database and OpenERP url (yes Ooor is not only multi-database like OpenEP, it's in fact multi-OpenERP!)

Installation

$ gem install ooor

Warning Ooor has been ureleased for several months, don't hesitate to run the git version instead

Trying it simply

Once you installed the OOOR gem, you get a new OOOR command line. Basic usage is:

$ ooor username:password@host:port/database

This will bring you in a standard IRB interpreter with an ooor client already connected to your Odoo server so you can start playing with it.

Standalone (J)Ruby application:

Let's test ooor in an irb console (irb command):

require 'rubygems'
require 'ooor'
Ooor.new(:url => 'http://localhost:8069/xmlrpc', :database => 'mybase', :username => 'admin', :password => 'admin')

This should load all your Odoo models into Ruby proxy Activeresource objects. Of course there are option to load only some models. Let's try to retrieve the user with id 1:

ResUsers.find(1)

(in case you have an error like "no such file to load -- net/https", then on Debian/Ubuntu, you might need to do before: apt-get install libopenssl-ruby)

(J)Ruby on Rails application:

Please read details https://github.com/rvalyi/ooor/wiki/(J)Ruby-on-Rails-application

API usage

Note: Ruby proxy objects are named after Odoo models in but removing the '.' and using CamelCase. (we remind you that Odoo tables are also named after Odoo models but replacing the '.' by '_'.)

Basic finders:

ProductProduct.find(1)
ProductProduct.find([1,2])
ProductProduct.find([1])
ProductProduct.find(:all)
ProductProduct.find(:last)

Odoo domain support (same as Odoo):

ResPartner.find(:all, :domain=>[['supplier', '=', 1],['active','=',1]])
#More subtle now, remember Odoo use a kind of inverse polish notation for complex domains,
#here we look for a product in category 1 AND which name is either 'PC1' OR 'PC2':
ProductProduct.find(:all, :domain=>[['categ_id','=',1],'|',['name', '=', 'PC1'],['name','=','PC2']])

Odoo context support (same as Odoo):

ProductProduct.find(1, :context => {:my_key => 'value'})

Request params or ActiveResource equivalence of Odoo domain (but degraded as only the = operator is supported, else use domain):

ResPartner.find(:all, :params => {:supplier => true})

Odoo search method:

ResPartner.search([['name', 'ilike', 'a']], 0, 2)

Arguments are: domain, offset=0, limit=false, order=false, context={}, count=false

Relations (many2one, one2many, many2many) support:

SaleOrder.find(1).order_line #one2many relation
p = ProductProduct.find(1)
p.product_tmpl_id #many2one relation
p.taxes_id #automagically reads man2many relation inherited via the product_tmpl_id inheritance relation
p.taxes_id = [1,2] #save a many2many relation, notice how we bypass the awkward Odoo syntax for many2many (would require [6,0, [1,2]]) ,
p.save #assigns taxes with id 1 and 2 as sale taxes,
see [the official Odoo documentation](http://doc.openerp.com/developer/5_18_upgrading_server/19_1_upgrading_server.html?highlight=many2many)```


Inherited relations support:

```ruby
ProductProduct.find(1).categ_id #where categ_id is inherited from the ProductTemplate

Please notice that loaded relations are cached (to avoid hitting Odoo over and over) until the root object is reloaded (after save/update for instance).

Load only specific fields support (faster than loading all fields):

ProductProduct.find(1, :fields=>["state", "id"])
ProductProduct.find(:all, :fields=>["state", "id"])
ProductProduct.find([1,2], :fields=>["state", "id"])
ProductProduct.find(:all, :fields=>["state", "id"])
even in relations:
SaleOrder.find(1).order_line(:fields => ["state"])

Create:

pc = ProductCategory.new(:name => 'Categ From Rails!')
# <ProductCategory:0xb702c42c @prefix_options={}, @attributes={"name"=>"Categ From Rails!"}>
pc.create
pc.id
# $ => 14

Update:

pc.name = "A new name"
pc.save

Copy:

copied_object = pc.copy({:categ_id => 2})  #first optionnal arg is new default values, second is context

Delete:

pc.destroy

Call workflow:

s = SaleOrder.find(2)
s.wkf_action('cancel')
s.state
# => 'cancel'

On Change methods:

Note: currently OOOR doesn't deal with the View layer, or has a very limited support for forms for the wizards. So, it's not possible so far for OOOR to know an on_change signature. Because of this, the on_change syntax is bit awkward as you will see (fortunately OpenERP SA announced they will fix that on_change API in subsequent v6 OpenERP releases): you need to explicitely tell the on_change name, the parameter name that changed, the new value and finally enforce the on_change syntax (looking at the OpenERP model code or view or XML/RPC logs will help you to find out). But ultimately it works:

l = SaleOrderLine.new
l.on_change('product_id_change', :product_id, 20, 1, 20, 1, false, 1, false, false, 7, 'en_US', true, false, false, false)
# => #<SaleOrderLine:0x7f76118b4348 @prefix_options={}, @relations={"product_uos"=>false, "product_id"=>20, "product_uom"=>1, "tax_id"=>[]}, @loaded_relations={}, @attributes={"name"=>"[TOW1] ATX Mid-size Tower", "product_uos_qty"=>1, "delay"=>1.0, "price_unit"=>37.5, "type"=>"make_to_stock", "th_weight"=>0}>

Notice that it reloads the Objects attrs and print warning message accordingly

On the fly one2many object graph update/creation:

Just like the OpenERP GTK client (and unlike the web client), in OOOR you can pass create/update one2many relation in place directly. For instance:

so = SaleOrder.new
so.on_change('onchange_partner_id', :partner_id, 1, 1, false) #auto-complete the address and other data based on the partner
so.order_line = [SaleOrderLine.new(:name => 'sl1', :product_id => 1, :price_unit => 42, :product_uom => 1)] #create one order line
so.save
so.amount_total
# => 42.0

Call aribtrary method:

$ use static ObjectClass.rpc_execute_with_all method
$ or object.call(method_name, args*) #were args is an aribtrary list of arguments

Class methods from are osv.py/orm.py proxied to OpenERP directly (as the web client does):

ResPartner.name_search('ax', [], 'ilike', {})
ProductProduct.fields_view_get(132, 'tree', {})

Call old style wizards (OpenERP v5):

inv = AccountInvoice.find(4)
# in case the inv.state is 'draft', do inv.wkf_action('invoice_open')
wizard = inv.old_wizard_step('account.invoice.pay') #tip: you can inspect the wizard fields, arch and datas
wizard.reconcile({:journal_id => 6, :name =>"from_rails"}) #if you want to pay all; will give you a reloaded invoice
inv.state
# => "paid"
# or if you want a payment with a write off:
wizard.writeoff_check({"amount" => 12, "journal_id" => 6, "name" =>'from_rails'}) #use the button name as the wizard method
wizard.reconcile({required missing write off fields...}) #will give you a reloaded invoice because state is 'end'
# TODO test and document new osv_memory wizards API

Absolute OpenERP ids aka ir_model_data:

just like Rails fixtures, OpenERP supports absolute ids for its records, especially those imported from XML or CSV. We are here speaking about the string id of the XML or CSV records, eventually prefixed by the module name. Using those ids rather than the SQL ids is a good idea to avoid relying on a particular installation. In OOOR, you can both retrieve one or several records using those ids, like for instance:

ProductCategory.find('product.product_category_3')

Notice that the 'product.' module prefix is optional here but important if you have similar ids in different module scopes. You can also create a resource and it's ir_model_data record alltogether using the ir_mode_data_id param:

ProductCategory.create(:name => 'rails_categ', :ir_model_data_id =>['product', 'categ_x']) #1st tab element is the module, 2nd the id in the module

Obtain report binary data:

To obtain the binary data of an object report simply use the function get_report_data(report_name). This function returns a list that contains the binary data encoded in base64 and a string with the file format. Example:

inv = AccountInvoice.find(3)
report = inv.get_report_data('account.invoice') #account.invoice is the service name defined in Invoices report
# Save the report to a file
# report[1] contains the file extension and report[0] contains the binary data of the report encoded in base64
File.open("invoice_report.#{report[1]}", "w") {|f| f.write(Base64.decode64(report[0]))}

Change logged user:

An Ooor client can have a global user logged in, to change it:

Ooor.global_login('demo', 'demo')
s = SaleOrder.find(2)
# => 'Access denied error'

Instead, every Ooor business objects can also belong to some specific user. To achieve that, generate your object passing proper :user_id and :password parameters inside the context of the method creating the object (typically a find). Notice that methods invoked on an objet use the same credentials as the business objects. Objects generated by this object (by a call to an association for instance) will also have the same credentials.

p = ProductProduct.find(1, :context => {:user_id=>3, :password=>'test'})

This is tipycally the system you will use in a Ruby (Rails or not) web application.

Change log level:

By default the log level is very verbose (debug level) to help newcomers to jumpstart. However you might want to change that. 2 solutions:

Ooor.logger.level = 1 #available levels are those of the standard Ruby Logger class: 0 debug, 1 info, 2 error

In the config yaml file or hash, set the :log_level parameter

Drawing OpenERP UML diagrams with OOOR

Finger in the nose multi-OpenERP instances migration/management with OOOR

Detailed API in the automated test suite

OOOR ships with an RSpec automated unit test suite to avoid regressions. This is also the place where you can easily read the exact API detail to master every OOOR features. You can read the test suite here: http://github.com/rvalyi/ooor/blob/master/spec/ooor_spec.rb Of course this also shows you can use RSpec to specify and test your OpenERP modules. OOOR is actually used to test OpenERP complex features in a specification language business experts can read and even write! In this case CampToCamp used the famous Cucumber functionnal test suite in the OERPScenario project.

FAQ

Please read the FAQ here

ooor's People

Contributors

bryant1410 avatar dbroeglin avatar flyfy1 avatar guewen avatar hugosantosred avatar huoxito avatar olimart avatar rvalyi avatar sebastienbeau avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ooor's Issues

Ruby dates might not be passed correctly to OpenERP

Hello using OOOR in Kettle (soon published), we suspect that OpenERP entities created in OOOR in the Ruby side don't pass correctly dates to OpenERP, should be a trivial formatting issue. We will investigate on this.

binary support

Hello, this is more a blueprint than a issue.
OOOR did not seem to have a native support for binary support.
I have written a basic module that provide basic helpers.
May be this should be included in CommonService module or function it can be class methods like in UML module.

This way you can do
company.logo = Ooor.serialize_binary_from_file('my_logo.jpg')
company.save

Ideally it should be one the fly when you read write the value of a binary file, but I did not take the time to do it, sorry.

here is the module

require 'base64'
module OOORMisc
def serialize_binary_from_file(binary_path)
return Base64.encode64(File.read(binary_path))
end

def serialize_binary_from_content(content)
    return Base64.encode64(content)
end

def unserialize_binary(content)
    return Base64.decode64(content)
end

end

Hope it helps

Regards

Nicolas

Really Nasty bug in 1.2.5 with default value

Here is the sample
data = {:code => '20g', :name=>'toto' ….}
acc = AccountAnalyticAccount.new(data)
acc.create()
acc.code = 33305 #o_0 ??

It appears that the default value feature does not merge the value in the right direction. It replace value set in the constructor by the value set by the default value of OpenERP but we want the opposite merge behavior.

One2Many field relation don't work properly on 1.0.0.7

Hi !

Trying this:

res=ResPartner.find(:all,:domain=>[ ['supplier','=',true] ])
res.should be_true
res.each do |part|
if (part.address.length >0) :
@partner = part
break
end
end

You get an error which was not present into the 1.0.6 :

*********** OpenERP Server ERROR:
Traceback (most recent call last):
File "/Users/jgrandguillaume/c2c/Code/Customers-dev/openerp_vogel/server/bin/netsvc.py", line 244, in dispatch
result = LocalService(service_name)(method, _params)
File "/Users/jgrandguillaume/c2c/Code/Customers-dev/openerp_vogel/server/bin/netsvc.py", line 73, in call
return getattr(self, method)(_params)
File "/Users/jgrandguillaume/c2c/Code/Customers-dev/openerp_vogel/server/bin/service/web_services.py", line 583, in execute
res = service.execute(db, uid, object, method, _args)
File "/Users/jgrandguillaume/c2c/Code/Customers-dev/openerp_vogel/server/bin/osv/osv.py", line 61, in wrapper
return f(self, dbname, *args, *_kwargs)
File "/Users/jgrandguillaume/c2c/Code/Customers-dev/openerp_vogel/server/bin/osv/osv.py", line 120, in execute
res = pool.execute_cr(cr, uid, obj, method, _args, *_kw)
File "/Users/jgrandguillaume/c2c/Code/Customers-dev/openerp_vogel/server/bin/osv/osv.py", line 112, in execute_cr
return getattr(object, method)(cr, uid, _args, *_kw)
File "/Users/jgrandguillaume/c2c/Code/Customers-dev/openerp_vogel/server/bin/osv/orm.py", line 2143, in read
result = self._read_flat(cr, user, select, fields, context, load)
File "/Users/jgrandguillaume/c2c/Code/Customers-dev/openerp_vogel/server/bin/osv/orm.py", line 2183, in _read_flat
or (f in self._columns and getattr(self._columns[f], '_classic_write'))
TypeError: list objects are unhashable

        ***********

The part.address don't work :( You cannot write something like part.address[0].name.

Regards,

Joël

Related object are always reloaded from OpenERP

An example of the issue has been provided by Joel Grand-Guillaume from CampToCamp:
a=ResPartnerAddress.find(:first)
a.partner_id.supplier=true
a.save
a.partner_id.supplier -> false

Actually there are two issues in this example:

  1. save is not deep. I think deep should be the default, see:
    http://github.com/rvalyi/ooor/issues/#issue/3
  2. a.partner_id.supplier = false because the partner is re-loaded from the database no matter what and since it has not been saved, it's wrong.

Can't access reconcile_id many2one relation

Hello,
I try to fix this one but I break my tooth on it :

l = AccountMoveLine.find(:first)
l.reconcile_id
NoMethodError: undefined method []' for nil:NilClass from /Library/Ruby/Gems/1.8/gems/ooor-1.0.9/lib/app/models/open_object_resource.rb:298:inrelationnal_result'
from /Library/Ruby/Gems/1.8/gems/ooor-1.0.9/lib/app/models/open_object_resource.rb:311:in `method_missing'
from (irb):10

Maybe it's due to the fact the field is readonly.

I'm perplex on this one.

Regards

Nicolas

Crash when there is an " ' " info info fields

Crash when there is an " ' " info info fields.
I suggest in ooor.rb at line 66 to do something like this.

  models.each do |openerp_model| 
      if openerp_model.attributes['info'] :
          openerp_model.attributes['info'] = openerp_model.attributes['info'].gsub("'",'')
      end 
      OpenObjectResource.define_openerp_model(openerp_model, models_url, database, user_id, pass, @ooor_binding) 
  end 

Sorry I have some trouble installing git

Nicolas Bessi

No all_loaded_models method...

Trying to use ooorest and getting the following:

initialize': undefined methodall_loaded_models' for #Ooor:0xb749200c (NoMethodError)

It appears the method is missing but ooorest points to it.

Create Database function does not work when super admin password is not 'admin'

Create Database function does not work when super admin password is not 'admin'

Here is what I propose to fix it :
--- /Library/Ruby/Gems/1.8/gems/ooor-1.3.1/lib/app/models/db_service.rb
+++ db_service.rb
@@ -2,9 +2,10 @@
module DbService
def create(password=@config[:db_password], db_name='ooor_db', demo=true, lang='en-US', user_password=@config[:password] || 'admin')
process_id = OpenObjectResource.try_with_pretty_error_log { OpenObjectResource.client(@base_url + "/db").call("create", password, db_name, demo, lang, user_password) }

  • @config[:password] = user_password
    @config[:database] = db_name
  • @config[:username] = user_password
  • while get_progress('admin', process_id) == [0, []]
  • @config[:username] = 'admin'
  • while get_progress(password, process_id) == [0, []]
    @logger.info "..."
    sleep(0.5)
    end

If the diff is not clear enough

def create(password=@config[:db_password], db_name='ooor_db', demo=true, lang='en-US', user_password=@config[:password] || 'admin')
process_id = OpenObjectResource.try_with_pretty_error_log { OpenObjectResource.client(@base_url + "/db").call("create", password, db_name, demo, lang, user_password) }
@config[:password] = user_password
@config[:database] = db_name
@config[:username] = 'admin'
while get_progress(password, process_id) == [0, []]
@logger.info "..."
sleep(0.5)
end
load_models()
end

Reload ressource after using wkf_action

Hi !

When you use the wkf_action method, like invoice.wkf_action('invoice_cancel'), you should have a reloaded invoice into invoice var. This is at least the case for other, like workflow method.

To avoid this, you can do the following, but could be done directly into wkf_action :

invoice.wkf_action('invoice_cancel')
invoice=invoice.find(invoice.id)

Regards,

Joël

database creation with user password other than 'admin' fail to reload the model afterwards

stack trace is similar to:

registering IrModel as a Rails ActiveResource Model wrapper for OpenObject ir.model model
/home/isadaptool/.gem/ruby/1.8/gems/ooor-1.3.2/lib/ooor.rb:88: warning: already initialized constant IrModel
registering IrModelFields as a Rails ActiveResource Model wrapper for OpenObject ir.model.fields model
/home/isadaptool/.gem/ruby/1.8/gems/ooor-1.3.2/lib/ooor.rb:88: warning: already initialized constant IrModelFields
rpc_execute_with_all: rpc_method: 'execute', db: "db_termi2", uid: false, pass: "old_pass", obj: "ir.model", method: search, args: [[], {}]
*
********* OpenERP Server ERROR:
Traceback (most recent call last):
File "/opt/openerp5.0_test/server/bin/netsvc.py", line 244, in dispatch
result = LocalService(service_name)(method, _params)
File "/opt/openerp5.0_test/server/bin/netsvc.py", line 73, in call
return getattr(self, method)(_params)
File "/opt/openerp5.0_test/server/bin/service/web_services.py", line 574, in execute
security.check(db, uid, passwd)
File "/opt/openerp5.0_test/server/bin/service/security.py", line 57, in check
raise Exception('AccessDenied')
Exception: AccessDenied


RuntimeError: OpenERP server error
from /home/isadaptool/.gem/ruby/1.8/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:134:in try_with_pretty_error_log' from /home/isadaptool/.gem/ruby/1.8/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:91:inrpc_execute_with_all'
from /home/isadaptool/.gem/ruby/1.8/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:84:in rpc_execute_with_object' from /home/isadaptool/.gem/ruby/1.8/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:80:inrpc_execute'
from /home/isadaptool/.gem/ruby/1.8/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:205:in find_every' from /var/lib/gems/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:582:infind'
from /home/isadaptool/.gem/ruby/1.8/gems/ooor-1.3.2/lib/ooor.rb:55:in load_models' from /home/isadaptool/.gem/ruby/1.8/gems/ooor-1.3.2/lib/app/models/db_service.rb:11:increate'
from (irb):46
irb(main):047:0>

workaround: you can still reconnect a new Ooor instance to the created database; using 'admin' as the password also works.

I'm still investigating what is the issue.

not all methods have their arguments casted properly

For CRUD methods the arguments are properly casted, for instance: Ruby BigNumber is casted to integer, date as strings are casted to Ruby date or datetime and reversely.

However, for arbitrary methods called via method_missing or even the on_change or wizard methods, the casting is not triggered. A workaround is to manually cast those arguments but of course having an automatic casting just before/after the RPC call would be better. This is for 1.2.6...

Endless loop with new object form through OooREST [SystemStackError in Crm_case#new]

Hi Raphaël,

I get the following error when I try to open a form for a new crm_case object using OooREST (http://localhost:3000/crm_case/new):

D:/Ruby/lib/ruby/gems/1.9.1/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:455:in `block in method_missing'
D:/Ruby/lib/ruby/gems/1.9.1/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:454:in `each'
D:/Ruby/lib/ruby/gems/1.9.1/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:454:in `method_missing'
D:/Ruby/lib/ruby/gems/1.9.1/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:56:in `block (3 levels) in reload_fields_definition'
-- snipped --
D:/Ruby/lib/ruby/gems/1.9.1/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:471:in `method_missing'
D:/Ruby/lib/ruby/gems/1.9.1/gems/ooor-1.3.2/lib/app/models/open_object_resource.rb:56:in `block (3 levels) in reload_fields_definition'
D:/Ruby/lib/ruby/gems/1.9.1/gems/activeresource-2.3.5/lib/active_resource/base.rb:775:in `new?'
D:/Ruby/lib/ruby/gems/1.9.1/gems/actionpack-2.3.5/lib/action_view/helpers/form_helper.rb:290:in `apply_form_for_options!'
D:/Ruby/lib/ruby/gems/1.9.1/gems/actionpack-2.3.5/lib/action_view/helpers/form_helper.rb:277:in `form_for'

Contents of new.html.erb:

<h2>New Case</h2>
<% form_for(@models) do |f| %>
    <p>
        <%= f.label :code %><br />
        <%= f.text_field :code %>
    </p>
<% end %>

I'm following the Rails guide, so it may be that I haven't set this up properly to work with OooREST.

Object method call seems to have trouble reloading relations

Hi,

I think there is a problem on calling objects methods. See commit 97 in OERPScenario, file "sale_order.rb", line 126.

Seems related to a quite complex workflow :( !

From a created SaleOrder (with one line, and manual shipping and invoice) in @saleorder do

@saleorder.wkf_action('order_confirm')
@saleorder.wkf_action('manual_invoice')
@Invoice[email protected]_ids[0]
@invoice.wkf_action('invoice_open')
@invoice.wkf_action('invoice_cancel')
AccountInvoice.action_cancel_draft([@invoice.id])
puts @saleorder.state

=> At this point, the SO has a 'invoice_except' state into the DB, but a 'confirmed' state for Ooor...

Even doing that:

@saleorder=SaleOrderLine.find(@saleorder.id)
puts @saleorder.state

At least, if too complicated to fix the whole things, is it possible to avoid that by "finding" again the needed object ?

Thanks in advance,

Regards,

Joël

Really slow when updating product variants

Hi,

I have more than 600 product variants from a product template created using the product_variant_multi module. Now I wanted to set the product code (defalut_code field) with a code that has a fixed prefix and a suffix based on the dimension values of the variant.

I used OOOR for that and it works fine, but it takes about 3 minutes per product variant update.

I have tried other things to see if speed improved, like loading only the required models :models => ['product.product', 'product.variant.dimension.value'] and execute prod.update(:default_code => new_code) instead of prod.save but it still very slow so I can't spend 30 hours to complete the product code update.

Is there any thing that I can do speed up the process?

Thank you very much

possible instance method_missing bug

Currently, if I do:
p=ProductPrdouct.find(1)
p.log("log test")
it will call:
rpc_method: 'execute', db: bambino_dev, uid: 1, pass: ######, obj: product.product, method: log, *args: ["log test", {}]
which fails because OpenERP expect the id to be passed just like in:
p.log(p.id, "log test")

The only way we pass the id eventually is when the args are empty like for an action such as:
sale_order.button_confirm

I really wonder if it makes sense to dispatch the way I did in method_missing:
return rpc_execute(method_name, *arguments) unless arguments.empty? || is_assign

I should test if this match any use case. If not, just drop that line and even adapt rpc_execute(method_key, [id], *arguments) for the case where there is no id ([] then).

Thoughts?

REGRESSION in OOOR-1.2.8: ArgumentError: no id given

Guys, I apologize for that,

Because of the code line 49 to 55 in openobject_resource.rb we added to help aut-completion tool, we now have a regression, try:
s=SaleOrder.create(:partner_id=>1, :partner_order_id=>1, :partner_invoice_id=>1, :partner_shipping_id=>1)

Results in:
ArgumentError: no id given
from /home/rvalyi/.gem/ruby/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:1153:in method_missing' from /home/rvalyi/.gem/ruby/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:1153:inmethod_missing'
from /home/rvalyi/DEV/ooortest/vendor/plugins/ooor/lib/app/models/open_object_resource.rb:455:in method_missing' from /home/rvalyi/DEV/ooortest/vendor/plugins/ooor/lib/app/models/open_object_resource.rb:52:insend'
from /home/rvalyi/DEV/ooortest/vendor/plugins/ooor/lib/app/models/open_object_resource.rb:52:in id' from /home/rvalyi/.gem/ruby/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:775:innew?'
from /home/rvalyi/.gem/ruby/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:864:in save_without_validation' from /home/rvalyi/.gem/ruby/1.8/gems/activeresource-2.3.5/lib/active_resource/validations.rb:259:insave'
from /home/rvalyi/.gem/ruby/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:528:in create' from /home/rvalyi/.gem/ruby/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:528:intap'
from /home/rvalyi/.gem/ruby/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:528:in `create'
from (irb):2

do not crash when trying to find with a domain and there is no result

It currently blows up because it will try a read with no id and with try to send nil over XML/RPC which is not allowed. We should skip the read when no id is found by the search.

Here is an example we have from the Kettle ETL (TerminatOOOR plugin):

rpc_execute_with_all: rpc_method: 'execute', db: "adaptoo", uid: 1, pass: "pass", obj: "account.move.line", method: search, *args: [[["journal_id", "=", "x Sales Journal"], ["period_id", "=", 13]], {}]
rpc_execute_with_all: rpc_method: 'execute', db: "adaptoo", uid: 1, pass: "pass", obj: "account.move.line", method: read, *args: [[], [], {}]
file:/opt/kettle/libext/jruby-complete-ooor.jar!/META-INF/jruby.home/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/core_ext/string/output_safety.rb:25:in `add_with_safety': can't convert nil into String (TypeError)
from <script>:21
org.jruby.embed.EvalFailedException: can't convert nil into String
at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:116)
at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:162)
at com.akretion.kettle.steps.terminatooor.ScriptValuesMod.addValues(Unknown Source)
at com.akretion.kettle.steps.terminatooor.ScriptValuesMod.processRow(Unknown Source)
at org.pentaho.di.trans.step.RunThread.run(RunThread.java:28)
at java.lang.Thread.run(Thread.java:717)
Caused by: org.jruby.exceptions.RaiseException: can't convert nil into String

Nasty Instance creation bug in OOOR 1.2.1

In short

toto = AccountInvoice.new()
=> #<AccountInvoice:0x102292270 @loaded_relations={}, @prefix_options={}, @attributes={}, @relations={}>
toto.name = 'a'
=> "a"
pp toto.inspect
"#<AccountInvoice:0x102292270 @loaded_relations={}, @prefix_options={}, @attributes={}, @relations={"name"=>"a"}>"
=> nil
toto.name
Raise a no method error
*** DIRECTLY AVAILABLE FIELDS ON OBJECT #AccountInvoice:0x102292270 ARE: ***

As you can see the basic attributes goes into the @relation property dict not in the @Attribute as they should, this is the same with any other simple attribute. So we can not anymore create any new invoice from zero.

Regards

Nicolas

default values (potentially inherited) should not be taken from related objects that are specified in attributes

When we create a ProductProduct, OpenERP doesn't tell us that ProductProduct inherits from ProductTemplate (variant system) and we think this is bad and will ask for that meta information in OpenERP 5.2.

So what default fields do we look for? Well, the default fields of ProductProduct + any related object though many2one keys such as ProductTemplate... (the OpenERP clients don't have that issue because they follow only views stupidly).

The issue arises however if you try to create a product variant, that is specifying a template. OpenERP will not like you specify a product_tmpl_id and also try to write default values into the inherited ProductTemplate object.

So since OOOR-1.3.2, we filter out default fields related to many2one keys that are specified as attributes (and it's also faster the to read default fields). And it work. See the difference between those 2 cases (including custom modules):

p1=ProductProduct.new
rpc_execute_with_all: rpc_method: 'execute', db: "homecine", uid: 1, pass: "admin", obj: "ir.model.fields", method: read, *args: [[768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 994, 1460, 1572, 1573, 1574, 1887, 1888, 1907, 1908, 1955], [], {}]
26 fields loaded in model Class
rpc_execute_with_all: rpc_method: 'execute', db: "homecine", uid: 1, pass: "admin", obj: "ir.model.fields", method: read, *args: [[735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 992, 993, 1448, 1449, 1450, 1451, 1575, 1576, 1577, 1578, 1579], [], {}]
44 fields loaded in model Class
rpc_execute_with_all: rpc_method: 'execute', db: "homecine", uid: 1, pass: "admin", obj: "product.product", method: default_get, *args: [["ean13", "price", "pricelist_sale", "name", "weight_net", "lst_price", "deee_value", "description_sale", "code", "default_code", "qty_available", "track_outgoing", "loc_rack", "sale_ok", "sale_delay", "virtual_available", "price_extra", "track_incoming", "weight", "outgoing_qty", "pricelist_purchase", "seller_delay", "price_margin", "track_production", "homecine_margin_relative", "description_purchase", "purchase_ok", "type", "volume", "loc_case", "produce_delay", "incoming_qty", "variants", "loc_row", "procure_method", "partner_ref", "homecine_margin", "supply_method", "description", "rental", "standard_price", "active", "purchase_avg_price", "warranty", "list_price", "mes_type", "uos_coeff", "state", "cost_method"], {}]
=> #<ProductProduct:0x7ff9e078f5c8 @loaded_relations={}, @relations={}, @prefix_options={}, @ir_model_data_id=nil, @attributes={"deee_value"=>0, "sale_ok"=>1, "sale_delay"=>7, "price_extra"=>0.0, "purchase_ok"=>1, "price_margin"=>1.0, "produce_delay"=>1, "type"=>"product", "procure_method"=>"make_to_stock", "supply_method"=>"buy", "standard_price"=>1, "list_price"=>-1, "mes_type"=>"fixed", "active"=>1, "uos_coeff"=>1.0, "cost_method"=>"standard"}>

p2=ProductProduct.new(:product_tmpl_id => 25)
rpc_execute_with_all: rpc_method: 'execute', db: "homecine", uid: 1, pass: "admin", obj: "product.product", method: default_get, *args: [["ean13", "price", "pricelist_sale", "lst_price", "deee_value", "code", "default_code", "qty_available", "track_outgoing", "virtual_available", "price_extra", "track_incoming", "outgoing_qty", "pricelist_purchase", "price_margin", "track_production", "homecine_margin_relative", "incoming_qty", "variants", "partner_ref", "homecine_margin", "active", "purchase_avg_price"], {}]
=> #<ProductProduct:0x7ff9e055dde0 @loaded_relations={}, @relations={"product_tmpl_id"=>25}, @prefix_options={}, @ir_model_data_id=nil, @attributes={"deee_value"=>0, "price_extra"=>0.0, "price_margin"=>1.0, "active"=>1}>

So in OOOR-1.3.2 it works out of the box. In OOOR < 1.3.2, you should rather specify a list of default fields to read (like []) when calling new, such as:
p = ProductProduct.new({:product_tmpl_id => tmpl_id, :dimension_value_ids => [value_id1, value_id2], :code => "MYSUPERCODE"}, [])

We also added a test case along with the fix.

Set debug level in OOOR

Hello,

when OOOR use reload! the logger outputs a lot of things in STDOUT.
It will be nice to be able to set the debug level

something like Ooor.reload!({:url => "http://localhost:#{@port}/xmlrpc", :database => @dbname, :username => @user, :password => @pwd, :logLevel=>Logger::ERROR})

I propose this patch

--- ooor.rb (saved version)
+++ (current document)
@@ -24,7 +24,9 @@
def self.reload!(config=false, env=false, keep_config=false)
@ooor_config = config.is_a?(Hash) && config or keep_config && @ooor_config or self.load_config(config, env)

@ooor_config.symbolize_keys!

  • if @ooor_config.has_key? :logLevel and @ooor_config[:logLevel]:
  •    @ooor_logger.level = @ooor_config[:logLevel]
    
  • end
    begin
    url = @ooor_config[:url]
    database = @ooor_config[:database]

incompatibility with Rails 3: Rails.root and Rails.logger might not exist when gems are required

the code to autoload OOOR when used in a Rails context doesn't work well in Rails 3, this is because Rails.root and Rails.logger might not exist yet!

A workaround is to comment the autoload and init Ooor inside the application.rb file.

A more robust way might have been found for that gem:
http://support.getexceptional.com/discussions/problems/134-rails3-issues-with-railsroot-being-null
download it here: https://rubygems.org/gems/exceptional

The important part of the fix seems that Rails initializer extension:

require 'exceptional'
require 'rails'

module Exceptional
class Railtie < Rails::Railtie

initializer "exceptional.middleware" do |app|
  Exceptional::Config.load(File.join(Rails.root, "/config/exceptional.yml"))

  if Exceptional::Config.should_send_to_api?
    Exceptional.logger.info("Loading Exceptional #{Exceptional::VERSION} for #{Rails::VERSION::STRING}")      
    app.config.middleware.use "Rack::RailsExceptional"
  end
end

end
end

define_openerp_model

like OpenERP save should include the loaded related models cascade by default

In the following script provided by Joël Grand-Guillaume from CampToCamp:

a=ResPartnerAddress.find(:first)
a.partner_id.supplier=true
a.save
a.partner_id.supplier -> false

a.save doesn't save the related partner address. OpenERP ORM is able do do it and that would be the default using the OpenERP client (change a sale order and it will save lines and all other many2one/one2many related records.

From now on, many2one loaded relation are cached in @loaded_relations. If those relations are many2one and one2many fields, let's give them to the OpenERP save method too.

Endless loop when retrieving an attribute

Hello,

My issue occures when I use ooor with Magento Open ERP Connector.
I create a connexion with Open ERP, I get an attribute set, and when I try to access to this set's attribute list, it starts an endless loop.

My OOOR with Open ERP connexion :
irb(main):004:0> ooor = Ooor.new({:url => "http://localhost:8045/xmlrpc", :database => "openerp", :username => "admin", :password => "admin"})

I get an attribute set (we can see that the list of attributes is well in this object):
irb(main):005:0> set = MagerpProduct_attribute_set.find(:first, :domain=>[['id','=',180]])
D, [2010-09-27T09:03:57.850525 #15521] DEBUG -- : rpc_execute_with_all: rpc_method: 'execute', db: "openerp", uid: 1, pass: "admin", obj: "magerp.product_attribute_set", method: search, *args: [[["id", "=", 180]], {}]
D, [2010-09-27T09:03:57.872650 #15521] DEBUG -- : rpc_execute_with_all: rpc_method: 'execute', db: "openerp", uid: 1, pass: "admin", obj: "magerp.product_attribute_set", method: fields_get, *args: []
I, [2010-09-27T09:03:57.887035 #15521] INFO -- : 3 fields loaded in model Class
D, [2010-09-27T09:03:57.887190 #15521] DEBUG -- : rpc_execute_with_all: rpc_method: 'execute', db: "openerp", uid: 1, pass: "admin", obj: "magerp.product_attribute_set", method: read, *args: [[180], [], {}]
=> #<MagerpProduct_attribute_set:0xb6956418 @relations={"attributes"=>[6183, 6184, 6185, 6186, 6187, 6192, 6193, 6194, 6195, 6198, 6199, 6200, 6201, 6202, 7029, 7030, 7031, 7032, 7038, 7039, 7040, 7041, 7042, 7043, 7044, 7045, 7046, 7069, 7070, 7071, 7072, 7073, 7074, 7075, 7076, 7077, 7078, 7079, 7080, 7081, 7082, 7083, 7084, 7085, 7086, 7087, 7088, 7089, 7090, 7091, 7092, 7093, 7094, 7095, 7096, 7097, 7098, 7099, 7100, 7101, 7102, 7103, 7104, 7105], "referential_id"=>[1, "debonix"]}, @prefix_options={}, @object_session={:context=>{}, :user_id=>nil, :password=>nil, :database=>nil}, @loaded_relations={}, @ir_model_data_id=nil, @attributes={"attribute_set_name"=>"Pompe \303\200 Eau", "sort_order"=>false, "id"=>180, "magento_id"=>56}>

If I try to access to the attributes of the set, I get that infinite loop :
irb(main):007:0> set.attributes
SystemStackError: stack level too deep
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:463:in method_missing' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:insend'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in attributes' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:464:inmethod_missing'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in send' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:inattributes'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:464:in method_missing' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:insend'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in attributes' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:464:inmethod_missing'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in send' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:inattributes'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:464:in method_missing' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:insend'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in attributes' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:464:inmethod_missing'
... 2445 levels...
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in send' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:inattributes'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:464:in method_missing' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:insend'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in attributes' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:464:inmethod_missing'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in send' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:inattributes'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:464:in method_missing' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:insend'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in attributes' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:464:inmethod_missing'
from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:in send' from /var/lib/gems/1.8/gems/ooor-1.4.1/lib/app/models/open_object_resource.rb:74:inattributes'
from (irb):7
from �:0irb(main):008:0>

Thank you, Regards
Guewen

split very large reads, like foo.find(:all) into small bits ?

Using OOOR in The Kettle ETL, if we don't pay attention we can typically request a read over all account move lines to get them exported to some external accounting format. The issue is that can generate a timeout in OpenERP server when there are too many computed fields to recompute.

Rather than force the API user to think about that to avoid timeouts, may be it's better to split the read like 100 by 100 and then makes the union of the requests.

This is easy to implement in the find_every method of OOOR, buy I'm not very sure yet still if we should do it. Thoughts?

wrong rpc_exec_workflow_with_all definition

wrong signature in:

try_with_pretty_error_log { client(@site).call("exec_workflow", db, uid, pass, obj, method, *args) }

Thanks to Joël Grand-Guillaume from CampToCamp for reporting!

OOOR REST part depends on action_pack without mentioning it in the gem spec

Hello,

The REST exposure of OpenERP business object by OOOR is somewhat bastard and not assumed. Indeed it's pretty different from the OOOR Model layer core and is more a Controller layer. I made it inside of OOOR because OOOR started as a Rails plugin.

Now, the REST part is very optional. As so, we try to load it only if ActionController is defined. And as it is considered optional, we don't even mention action_pack in the ooor.gemspec file.

The issue we saw yesterday was that because of the gemspec you could upgrade your active_resource or active_suppport gems while keeping an old action_pack gem (because of an old Rails install for instance). When loading, that action_pack gem will require and old active_support gem while the newer active_resources loaded a newer active_support already and kaboom!

I think the way we will fix this is bite the bullet and extract the optionnal REST layer of OOOR into a new gem called OOOREST, I just started the project here: http://github.com/rvalyi/ooorest

correct documentation: create returns the object, not an id

Hello,
contrary to OpenERP which just returns an object with the method create. OOOR returns the whole object. Actually this is OK, because it saves code lines most of the time and also respects the Rails way.

Now, we should update the documentation where a create is showcased (ProductCategory)!

optimize load by ir_model_data absolute id

in open_object_resource.rb around line 219, we do:
ir_model_data = const_get('ir.model.data').find(:first, :domain => domain)

It performs 2 request a read more SQL than required. We could do only one server round trip by using instead:
const_get('ir.model.data')._get_id(module_name, absolute_id)

IrModelData OpenERP absolute references do not work when using OOOR with the :scope_prefix option

:scope_prefix is very useful for multi-instance or to avoid model name conflict with your Rails app (we had one!), but currently, with OOOR-1.2.7 you would have that error:

irb(main):004:0> OE::ProductProduct.find('product.p1')
ArgumentError: Anonymous modules have no name to be referenced by
from /home/rvalyi/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:585:in to_constant_name' from /home/rvalyi/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:391:inqualified_name_for'
from /home/rvalyi/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:104:in const_missing' from /usr/lib/ruby/gems/1.8/gems/ooor-1.2.7/lib/app/models/open_object_resource.rb:208:infind_single'
from /usr/lib/ruby/gems/1.8/gems/ooor-1.2.7/lib/app/models/open_object_resource.rb:203:in map!' from /usr/lib/ruby/gems/1.8/gems/ooor-1.2.7/lib/app/models/open_object_resource.rb:203:infind_single'
from /home/rvalyi/.gem/ruby/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:586:in `find'
from (irb):4

Function field of type date return empty String

Function field of type date return empty String. So when Ruby try to parse date it raise en error.

--- open_object_resource.rb
@@ -187,7 +187,7 @@
def cast_attributes_to_ruby!
@attributes.each do |k, v|
if self.class.fields[k]

  •    if v.is_a?(String)
    
  •    if v.is_a?(String) and not v.empty?
       case self.class.fields[k].ttype
         when 'datetime'
           @attributes[k] = Time.parse(v)
    

Bug in on_change : erase @attributes

Hi,

Using the new on_change, I realize that it breaks the current object by erasing the current info. On_change just return attributes concerned by the on_change and lost infos about what was already set... :

toreturn = AccountInvoice.new()
toreturn.name = 'My name'

=> here toreturn is:

<AccountInvoice:0x1024a4748 @relations={}, @attributes={"name"=>"MySupplierInvoiceBankStatement2", "currency_id"=>5, "type"=>"in_invoice", "date_invoice"=>"2009-01-01", "partner_id"=>2}, @loaded_relations={}, @prefix_options={}>

toreturn.on_change('onchange_partner_id', :partner_id ,1, 0[:type], partner.id, toreturn.date_invoice, false, false)

=> here toreturn is:

<AccountInvoice:0x1024a4748 @relations={"fiscal_position"=>false, "account_id"=>353, "address_invoice_id"=>6, "payment_term"=>false, "address_contact_id"=>6, "partner_id"=>1}, @attributes={}, @loaded_relations={}, @prefix_options={}>

No more attributes, no more currency etc....

Regards,

Joël

issues with Ruby 1.9

Looks like we have a couple of issues with Ruby 1.9,
especially:

  • getting UTF-8 strings from OpenERP (error in the REXML parser)
  • BigDecimal to Integer conversion to cast the attributes to OpenERP

Shouldn't be hard to fix. In any case, Ruby 1.9 isn't the standard yet. But we will probably support it full in less than one month in any case.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.