ooor 1.6.5 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.md +131 -88
- data/bin/ooor +4 -2
- data/lib/app/helpers/core_helpers.rb +137 -0
- data/lib/app/models/base64.rb +14 -25
- data/lib/app/models/common_service.rb +3 -15
- data/lib/app/models/db_service.rb +6 -17
- data/lib/app/models/ooor_client.rb +3 -15
- data/lib/app/models/open_object_resource.rb +40 -41
- data/lib/app/models/relation.rb +4 -16
- data/lib/app/models/serialization.rb +5 -0
- data/lib/app/models/type_casting.rb +8 -3
- data/lib/app/models/uml.rb +26 -35
- data/lib/app/ui/action_window.rb +13 -19
- data/lib/app/ui/client_base.rb +4 -21
- data/lib/app/ui/form_model.rb +4 -15
- data/lib/ooor.rb +50 -46
- data/spec/ooor_spec.rb +49 -29
- metadata +38 -37
- data/agpl-3.0-licence.txt +0 -661
- data/lib/app/ui/menu.rb +0 -34
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009-2012 Raphaël Valyi - Akretion LTDA
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
OOOR - OpenObject On
|
1
|
+
OOOR - OpenObject On Ruby:
|
2
2
|
====
|
3
3
|
|
4
4
|
<table>
|
@@ -106,14 +106,18 @@ This will bring you in a standard IRB interpreter with an OOOR client already co
|
|
106
106
|
|
107
107
|
Let's test OOOR in an irb console (irb command):
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
```ruby
|
110
|
+
require 'rubygems'
|
111
|
+
require 'ooor'
|
112
|
+
Ooor.new(:url => 'http://localhost:8069/xmlrpc', :database => 'mybase', :username => 'admin', :password => 'admin')
|
113
|
+
```
|
112
114
|
|
113
115
|
This should load all your OpenERP models into Ruby proxy Activeresource objects. Of course there are option to load only some models.
|
114
116
|
Let's try to retrieve the user with id 1:
|
115
117
|
|
116
|
-
|
118
|
+
```ruby
|
119
|
+
ResUsers.find(1)
|
120
|
+
```
|
117
121
|
|
118
122
|
(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)
|
119
123
|
|
@@ -131,52 +135,62 @@ Note: Ruby proxies objects are named after OpenERP models in but removing the '.
|
|
131
135
|
|
132
136
|
Basic finders:
|
133
137
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
138
|
+
```ruby
|
139
|
+
ProductProduct.find(1)
|
140
|
+
ProductProduct.find([1,2])
|
141
|
+
ProductProduct.find([1])
|
142
|
+
ProductProduct.find(:all)
|
143
|
+
ProductProduct.find(:last)
|
144
|
+
```
|
140
145
|
|
141
146
|
OpenERP domain support (same as OpenERP):
|
142
147
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
148
|
+
```ruby
|
149
|
+
ResPartner.find(:all, :domain=>[['supplier', '=', 1],['active','=',1]])
|
150
|
+
#More subtle now, remember OpenERP use a kind of inverse polish notation for complex domains,
|
151
|
+
#here we look for a product in category 1 AND which name is either 'PC1' OR 'PC2':
|
152
|
+
ProductProduct.find(:all, :domain=>[['categ_id','=',1],'|',['name', '=', 'PC1'],['name','=','PC2']])
|
153
|
+
```
|
147
154
|
|
148
155
|
|
149
156
|
OpenERP context support (same as OpenERP):
|
150
157
|
|
151
|
-
|
152
|
-
|
158
|
+
```ruby
|
159
|
+
ProductProduct.find(1, :context => {:my_key => 'value'})
|
160
|
+
```
|
153
161
|
|
154
162
|
Request params or ActiveResource equivalence of OpenERP domain (but degraded as only the = operator is supported, else use domain):
|
155
163
|
|
156
|
-
|
157
|
-
|
164
|
+
```ruby
|
165
|
+
ResPartner.find(:all, :params => {:supplier => true})
|
166
|
+
```
|
158
167
|
|
159
168
|
OpenERP search method:
|
160
169
|
|
161
|
-
|
170
|
+
```ruby
|
171
|
+
ResPartner.search([['name', 'ilike', 'a']], 0, 2)
|
172
|
+
```
|
162
173
|
|
163
174
|
Arguments are: domain, offset=0, limit=false, order=false, context={}, count=false
|
164
175
|
|
165
176
|
|
166
177
|
Relations (many2one, one2many, many2many) support:
|
167
178
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
179
|
+
```ruby
|
180
|
+
SaleOrder.find(1).order_line #one2many relation
|
181
|
+
p = ProductProduct.find(1)
|
182
|
+
p.product_tmpl_id #many2one relation
|
183
|
+
p.taxes_id #automagically reads man2many relation inherited via the product_tmpl_id inheritance relation
|
184
|
+
p.taxes_id = [1,2] #save a many2many relation, notice how we bypass the awkward OpenERP syntax for many2many (would require [6,0, [1,2]]) ,
|
185
|
+
p.save #assigns taxes with id 1 and 2 as sale taxes,
|
186
|
+
see [the official OpenERP documentation](http://doc.openerp.com/developer/5_18_upgrading_server/19_1_upgrading_server.html?highlight=many2many)```
|
175
187
|
|
176
188
|
|
177
189
|
Inherited relations support:
|
178
190
|
|
179
|
-
|
191
|
+
```ruby
|
192
|
+
ProductProduct.find(1).categ_id #where categ_id is inherited from the ProductTemplate
|
193
|
+
```
|
180
194
|
|
181
195
|
Please notice that loaded relations are cached (to avoid hitting OpenERP over and over)
|
182
196
|
until the root object is reloaded (after save/update for instance).
|
@@ -184,48 +198,57 @@ until the root object is reloaded (after save/update for instance).
|
|
184
198
|
|
185
199
|
Load only specific fields support (faster than loading all fields):
|
186
200
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
201
|
+
```ruby
|
202
|
+
ProductProduct.find(1, :fields=>["state", "id"])
|
203
|
+
ProductProduct.find(:all, :fields=>["state", "id"])
|
204
|
+
ProductProduct.find([1,2], :fields=>["state", "id"])
|
205
|
+
ProductProduct.find(:all, :fields=>["state", "id"])
|
206
|
+
```
|
191
207
|
|
192
208
|
even in relations:
|
193
209
|
|
194
|
-
|
195
|
-
|
210
|
+
```ruby
|
211
|
+
SaleOrder.find(1).order_line(:fields => ["state"])
|
212
|
+
```
|
196
213
|
|
197
214
|
Create:
|
198
215
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
216
|
+
```ruby
|
217
|
+
pc = ProductCategory.new(:name => 'Categ From Rails!')
|
218
|
+
#<ProductCategory:0xb702c42c @prefix_options={}, @attributes={"name"=>"Categ From Rails!"}>
|
219
|
+
pc.create
|
220
|
+
pc.id
|
221
|
+
#$ => 14
|
222
|
+
```
|
204
223
|
|
205
224
|
|
206
225
|
Update:
|
207
226
|
|
208
|
-
|
209
|
-
|
210
|
-
|
227
|
+
```ruby
|
228
|
+
pc.name = "A new name"
|
229
|
+
pc.save
|
230
|
+
```
|
211
231
|
|
212
232
|
Copy:
|
213
233
|
|
214
|
-
|
215
|
-
|
234
|
+
```ruby
|
235
|
+
copied_object = pc.copy({:categ_id => 2}) #first optionnal arg is new default values, second is context
|
236
|
+
```
|
216
237
|
|
217
238
|
Delete:
|
218
239
|
|
219
|
-
|
220
|
-
|
240
|
+
```ruby
|
241
|
+
pc.destroy
|
242
|
+
```
|
221
243
|
|
222
244
|
Call workflow:
|
223
245
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
246
|
+
```ruby
|
247
|
+
s = SaleOrder.find(2)
|
248
|
+
s.wkf_action('cancel')
|
249
|
+
s.state
|
250
|
+
#=> 'cancel'
|
251
|
+
```
|
229
252
|
|
230
253
|
On Change methods:
|
231
254
|
|
@@ -236,9 +259,11 @@ you need to explicitely tell the on_change name, the parameter name that changed
|
|
236
259
|
enfore the on_change syntax (looking at the OpenERP model code or view or XML/RPC logs will help you to find out). But
|
237
260
|
ultimately it works:
|
238
261
|
|
239
|
-
|
240
|
-
|
241
|
-
|
262
|
+
```ruby
|
263
|
+
l = SaleOrderLine.new
|
264
|
+
l.on_change('product_id_change', :product_id, 20, 1, 20, 1, false, 1, false, false, 7, 'en_US', true, false, false, false)
|
265
|
+
#=> #<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}>
|
266
|
+
```
|
242
267
|
Notice that it reloads the Objects attrs and print warning message accordingly
|
243
268
|
|
244
269
|
|
@@ -247,12 +272,14 @@ On the fly one2many object graph update/creation:
|
|
247
272
|
Just like the OpenERP GTK client (and unlike the web client), in OOOR you can pass create/update
|
248
273
|
one2many relation in place directly. For instance:
|
249
274
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
275
|
+
```ruby
|
276
|
+
so = SaleOrder.new
|
277
|
+
so.on_change('onchange_partner_id', :partner_id, 1, 1, false) #auto-complete the address and other data based on the partner
|
278
|
+
so.order_line = [SaleOrderLine.new(:name => 'sl1', :product_id => 1, :price_unit => 42, :product_uom => 1)] #create one order line
|
279
|
+
so.save
|
280
|
+
so.amount_total
|
281
|
+
#=> 42.0
|
282
|
+
```
|
256
283
|
|
257
284
|
|
258
285
|
Call aribtrary method:
|
@@ -261,22 +288,27 @@ Call aribtrary method:
|
|
261
288
|
$ or object.call(method_name, args*) #were args is an aribtrary list of arguments
|
262
289
|
|
263
290
|
Class methods from are osv.py/orm.py proxied to OpenERP directly (as the web client does):
|
264
|
-
|
265
|
-
|
291
|
+
|
292
|
+
```ruby
|
293
|
+
ResPartner.name_search('ax', [], 'ilike', {})
|
294
|
+
ProductProduct.fields_view_get(132, 'tree', {})
|
295
|
+
```
|
266
296
|
|
267
297
|
|
268
|
-
Call old style wizards:
|
298
|
+
Call old style wizards (OpenERP v5):
|
269
299
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
300
|
+
```ruby
|
301
|
+
inv = AccountInvoice.find(4)
|
302
|
+
#in case the inv.state is 'draft', do inv.wkf_action('invoice_open')
|
303
|
+
wizard = inv.old_wizard_step('account.invoice.pay') #tip: you can inspect the wizard fields, arch and datas
|
304
|
+
wizard.reconcile({:journal_id => 6, :name =>"from_rails"}) #if you want to pay all; will give you a reloaded invoice
|
305
|
+
inv.state
|
306
|
+
#=> "paid"
|
307
|
+
#or if you want a payment with a write off:
|
308
|
+
wizard.writeoff_check({"amount" => 12, "journal_id" => 6, "name" =>'from_rails'}) #use the button name as the wizard method
|
309
|
+
wizard.reconcile({required missing write off fields...}) #will give you a reloaded invoice because state is 'end'
|
310
|
+
#TODO test and document new osv_memory wizards API
|
311
|
+
```
|
280
312
|
|
281
313
|
|
282
314
|
Absolute OpenERP ids aka ir_model_data:
|
@@ -286,39 +318,48 @@ We are here speaking about the string id of the XML or CSV records, eventually p
|
|
286
318
|
Using those ids rather than the SQL ids is a good idea to avoid relying on a particular installation.
|
287
319
|
In OOOR, you can both retrieve one or several records using those ids, like for instance:
|
288
320
|
|
289
|
-
|
321
|
+
```ruby
|
322
|
+
ProductCategory.find('product.product_category_3')
|
323
|
+
```
|
290
324
|
|
291
325
|
Notice that the 'product.' module prefix is optional here but important if you have similar ids in different module scopes.
|
292
326
|
You can also create a resource and it's ir_model_data record alltogether using the ir_mode_data_id param:
|
293
327
|
|
294
|
-
|
295
|
-
|
328
|
+
```ruby
|
329
|
+
ProductCategory.create(:name => 'rails_categ', :ir_model_data_id =>['product', 'categ_x']) #1st tab element is the module, 2nd the id in the module
|
330
|
+
```
|
296
331
|
|
297
332
|
Obtain report binary data:
|
298
333
|
|
299
334
|
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.
|
300
335
|
Example:
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
336
|
+
|
337
|
+
```ruby
|
338
|
+
inv = AccountInvoice.find(3)
|
339
|
+
report = inv.get_report_data('account.invoice') #account.invoice is the service name defined in Invoices report
|
340
|
+
#Save the report to a file
|
341
|
+
#report[1] contains the file extension and report[0] contains the binary data of the report encoded in base64
|
342
|
+
File.open("invoice_report.#{report[1]}", "w") {|f| f.write(Base64.decode64(report[0]))}
|
343
|
+
```
|
307
344
|
|
308
345
|
Change logged user:
|
309
346
|
|
310
347
|
An Ooor client can have a global user logged in, to change it:
|
311
348
|
|
312
|
-
|
313
|
-
|
314
|
-
|
349
|
+
```ruby
|
350
|
+
Ooor.global_login('demo', 'demo')
|
351
|
+
s = SaleOrder.find(2)
|
352
|
+
#=> 'Access denied error'
|
353
|
+
```
|
315
354
|
|
316
355
|
Instead, every Ooor business objects can also belong to some specific user. To achieve that, generate your object passing
|
317
356
|
proper :user_id and :password parameters inside the context of the method creating the object (typically a find).
|
318
357
|
Notice that methods invoked on an objet use the same credentials as the business objects.
|
319
358
|
Objects generated by this object (by a call to an association for instance) will also have the same credentials.
|
320
359
|
|
321
|
-
|
360
|
+
```ruby
|
361
|
+
p = ProductProduct.find(1, :context => {:user_id=>3, :password=>'test'})
|
362
|
+
```
|
322
363
|
|
323
364
|
This is tipycally the system you will use in a Ruby (Rails or not) web application.
|
324
365
|
|
@@ -327,8 +368,10 @@ Change log level:
|
|
327
368
|
By default the log level is very verbose (debug level) to help newcomers to jumpstart.
|
328
369
|
However you might want to change that. 2 solutions:
|
329
370
|
|
330
|
-
|
331
|
-
|
371
|
+
```ruby
|
372
|
+
Ooor.logger.level = 1 #available levels are those of the standard Ruby Logger class: 0 debug, 1 info, 2 error
|
373
|
+
```
|
374
|
+
In the config yaml file or hash, set the :log_level parameter
|
332
375
|
|
333
376
|
|
334
377
|
[Drawing OpenERP UML diagrams with OOOR](http://wiki.github.com/rvalyi/ooor/drawing-openerp-uml-diagrams-with-ooor)
|
data/bin/ooor
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
-
puts "*** OOOR - OpenObject on Ruby! Published under the
|
3
|
+
puts "*** OOOR - OpenObject on Ruby! Published under the MIT license by Akretion.com ***"
|
4
4
|
|
5
5
|
require 'irb'
|
6
6
|
require 'rubygems'
|
@@ -9,7 +9,7 @@ require 'irb/completion'
|
|
9
9
|
|
10
10
|
unless ARGV.empty?
|
11
11
|
username = ARGV[0].split(".")[0]
|
12
|
-
database = ARGV[0].split(".")[1].split("@")[0]
|
12
|
+
database = ARGV[0].split(".")[1..100].join(".").split("@")[0]
|
13
13
|
if ARGV[0].index("@")
|
14
14
|
base_url = ARGV[0].split("@")[1]
|
15
15
|
else
|
@@ -29,7 +29,9 @@ unless ARGV.empty?
|
|
29
29
|
password = ARGV[1]
|
30
30
|
else
|
31
31
|
puts "password?"
|
32
|
+
system "stty -echo"
|
32
33
|
password = $stdin.gets.chomp!
|
34
|
+
system "stty echo"
|
33
35
|
end
|
34
36
|
|
35
37
|
if ARGV[1] == "-s" || ARGV[2] == "-s" #secure mode
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# OOOR: OpenObject On Ruby
|
2
|
+
# Copyright (C) 2009-2012 Akretion LTDA (<http://www.akretion.com>).
|
3
|
+
# Author: Akretion: Raphaël Valyi: CampToCamp: Nicolas Bessi, Joel Grand-Guillaume
|
4
|
+
# Licensed under the MIT license, see MIT-LICENSE file
|
5
|
+
|
6
|
+
Ooor.xtend('ir.module.module') do
|
7
|
+
|
8
|
+
##########################################################################
|
9
|
+
# Get recursively the whole list of modules dependencies
|
10
|
+
# for a list of modules.
|
11
|
+
# Do not add the module if it already exists in the input list
|
12
|
+
# Input :
|
13
|
+
# - modules : A [] of valid IrModuleModule instances with dependencies_id attribute
|
14
|
+
# Return
|
15
|
+
# - [] of dependencies
|
16
|
+
# Usage Example:
|
17
|
+
# dependency_modules = get_dependencies(modules)
|
18
|
+
def self.get_dependencies(modules)
|
19
|
+
dependency_modules = []
|
20
|
+
modules.select { |m| m.dependencies_id }.each do |mod|
|
21
|
+
mod.dependencies_id.each do |dep|
|
22
|
+
dep_module = IrModuleModule.find(:first,
|
23
|
+
:domain => [['name', '=', dep.name]],
|
24
|
+
:fields => ['id', 'state', 'dependencies_id'])
|
25
|
+
if dep_module.nil?
|
26
|
+
raise RuntimeError, "#{dep.name} not found"
|
27
|
+
end
|
28
|
+
dependency_modules << dep_module unless (modules + dependency_modules).map { |m| m.id }.include? dep_module.id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
dependency_modules.concat(get_dependencies(dependency_modules)) if dependency_modules.count > 0
|
32
|
+
dependency_modules.uniq { |m| m.id }
|
33
|
+
end
|
34
|
+
|
35
|
+
##########################################################################
|
36
|
+
# Run the upgrade wizard in order to install the required
|
37
|
+
# modules. Upgrade installed modules as well.
|
38
|
+
# Input :
|
39
|
+
# - modules : A [] of valid IrModuleModule instance
|
40
|
+
# Return
|
41
|
+
# - True
|
42
|
+
# Usage Example:
|
43
|
+
# res = IrModuleModule.install_modules(@openerp, modules)
|
44
|
+
def self.install_modules(openerp, modules, dependencies=false)
|
45
|
+
res = true
|
46
|
+
if dependencies
|
47
|
+
dependency_modules = get_dependencies(modules)
|
48
|
+
modules.concat(dependency_modules) if dependency_modules
|
49
|
+
end
|
50
|
+
modules_toinstall_ids = []
|
51
|
+
modules_toupgrade_ids = []
|
52
|
+
# If not installed, do it. Otherwise update it
|
53
|
+
modules.each do |m|
|
54
|
+
if m.state == 'uninstalled'
|
55
|
+
m.state = 'to install'
|
56
|
+
m.save
|
57
|
+
modules_toinstall_ids << m.id
|
58
|
+
elsif m.state == 'installed'
|
59
|
+
m.state = 'to upgrade'
|
60
|
+
m.save
|
61
|
+
modules_toupgrade_ids << m.id
|
62
|
+
elsif m.state == 'to install'
|
63
|
+
modules_toinstall_ids << m.id
|
64
|
+
elsif m.state == 'to upgrade'
|
65
|
+
modules_toupgrade_ids << m.id
|
66
|
+
end
|
67
|
+
end
|
68
|
+
#First installed required modules, then upgrade the others
|
69
|
+
upgrade = BaseModuleUpgrade.create()
|
70
|
+
upgrade.upgrade_module()
|
71
|
+
# IrModuleModule.button_install(modules_toinstall_ids)
|
72
|
+
# IrModuleModule.button_upgrade(modules_toupgrade_ids)
|
73
|
+
|
74
|
+
if res
|
75
|
+
return true
|
76
|
+
else
|
77
|
+
raise "!!! --- HELPER ERROR : install_modules was unable to install needed modules.."
|
78
|
+
end
|
79
|
+
openerp.load_models() # reload in order to have model Classes for modules installed
|
80
|
+
end
|
81
|
+
|
82
|
+
def print_uml
|
83
|
+
l = IrModelData.find(:all, :domain => {:model=>"ir.model", :module=>name})
|
84
|
+
model_names = []
|
85
|
+
l.each {|i| model_names << i.name.gsub('_', '.').gsub(/^model.report/, '').gsub(/^model./, '')}
|
86
|
+
classes = []
|
87
|
+
model_names.each {|i| begin classes << Object.const_get(IrModel.class_name_from_model_key i); rescue; end}
|
88
|
+
classes.reject! {|m| m.openerp_model.index("report")} #NOTE we would need a more robust test
|
89
|
+
begin
|
90
|
+
classes.reject! {|m| IrModel.read(m.openerp_id, ['osv_memory'])['osv_memory']}
|
91
|
+
rescue
|
92
|
+
end
|
93
|
+
classes.reject! {|m| m.openerp_model == "res.company"} if classes.size > 10
|
94
|
+
Ooor::UML.print_uml(classes, {:file_name => "#{name}_uml"})
|
95
|
+
end
|
96
|
+
|
97
|
+
def print_dependency_graph
|
98
|
+
modules = [self] + self.class.get_dependencies([self])
|
99
|
+
|
100
|
+
File.open("#{self.name}-pre.dot", 'w') do |f|
|
101
|
+
f << <<-eos
|
102
|
+
digraph DependenciesByOOOR {
|
103
|
+
fontname = "Helvetica"
|
104
|
+
fontsize = 11
|
105
|
+
label = "*** generated by OOOR by www.akretion.com ***"
|
106
|
+
node [
|
107
|
+
fontname = "Helvetica"
|
108
|
+
fontsize = 11
|
109
|
+
shape = "record"
|
110
|
+
fillcolor=orange
|
111
|
+
style="rounded,filled"
|
112
|
+
]
|
113
|
+
eos
|
114
|
+
|
115
|
+
modules.each do |m|
|
116
|
+
m.dependencies_id.each do |dep|
|
117
|
+
f << "#{m.name} -> #{dep.name};\n"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
f << "}"
|
121
|
+
end
|
122
|
+
system("tred < #{self.name}-pre.dot > #{self.name}.dot")
|
123
|
+
cmd_line2 = "dot -Tcmapx -o#{self.name}.map -Tpng -o#{self.name}.png #{self.name}.dot"
|
124
|
+
system(cmd_line2)
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
Ooor.xtend('ir.ui.menu') do
|
132
|
+
def menu_action
|
133
|
+
#TODO put in cache eventually:
|
134
|
+
action_values = self.class.ooor.const_get('ir.values').rpc_execute('get', 'action', 'tree_but_open', [['ir.ui.menu', id]], false, self.class.ooor.global_context)[0][2]#get already exists
|
135
|
+
@menu_action = self.class.ooor.const_get('ir.actions.act_window').new(action_values, []) #TODO deal with action reference instead
|
136
|
+
end
|
137
|
+
end
|