line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package OpenERP::OOM::Object::Base; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
10786
|
use 5.010; |
|
2
|
|
|
|
|
8
|
|
4
|
2
|
|
|
2
|
|
29
|
use Carp; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
121
|
|
5
|
2
|
|
|
2
|
|
536
|
use Data::Dumper; |
|
2
|
|
|
|
|
5140
|
|
|
2
|
|
|
|
|
102
|
|
6
|
2
|
|
|
2
|
|
12
|
use List::MoreUtils qw/uniq/; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
23
|
|
7
|
2
|
|
|
2
|
|
1249
|
use Moose; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
13
|
|
8
|
2
|
|
|
2
|
|
11707
|
use Try::Tiny; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
109
|
|
9
|
2
|
|
|
2
|
|
11
|
use Try::Tiny::Retry; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
112
|
|
10
|
2
|
|
|
2
|
|
11
|
use Time::HiRes qw/usleep/; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
17
|
|
11
|
2
|
|
|
2
|
|
224
|
use Switch::Plain; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
16
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
extends 'Moose::Object'; |
14
|
|
|
|
|
|
|
with 'OpenERP::OOM::DynamicUtils'; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
OpenERP::OOM::Class::Base |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 SYNOPSYS |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
my $obj = $schema->class('Name')->create(\%args); |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
:say $obj->id; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
$obj->name('New name'); |
27
|
|
|
|
|
|
|
$obj->update; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
$obj->delete; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=head1 DESCRIPTION |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
Provides a base set of properties and methods for OpenERP::OOM objects (update, delete, etc). |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head1 PROPERTIES |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=head2 id |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
Returns the OpenERP ID of an object. |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
say $obj->id; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head2 BUILD |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
The BUILD method sets up the methods for the links to the attached objects. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=cut |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
has 'id' => ( |
50
|
|
|
|
|
|
|
isa => 'Int', |
51
|
|
|
|
|
|
|
is => 'ro', |
52
|
|
|
|
|
|
|
); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub BUILD { |
55
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
# Add methods to follow links |
58
|
0
|
|
|
|
|
|
my $links = $self->meta->link; |
59
|
0
|
|
|
|
|
|
while (my ($name, $link) = each %$links) { |
60
|
|
|
|
|
|
|
sswitch ($link->{type}) { |
61
|
|
|
|
|
|
|
case ('single'): { |
62
|
|
|
|
|
|
|
$self->meta->add_method( |
63
|
|
|
|
|
|
|
$name, |
64
|
|
|
|
|
|
|
sub { |
65
|
0
|
|
|
0
|
|
|
my $obj = shift; |
66
|
0
|
|
0
|
|
|
|
$obj->{"_$name"} //= $obj->class->schema->link($link->{class})->retrieve($link->{args}, $obj->{$link->{key}}); |
67
|
|
|
|
|
|
|
|
68
|
0
|
0
|
|
|
|
|
unless ($obj->{"_$name"}) { |
69
|
|
|
|
|
|
|
# FIXME: If $obj->{"_$name"} is undefined, we have a data integrity problem. |
70
|
|
|
|
|
|
|
# Either the linked data is missing, or the key in the OpenERP object is missing. |
71
|
0
|
|
|
|
|
|
die "Error linking to OpenERP object " . $obj->id . " of class " . ref($obj); |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# NOTE: this only links up the object from the linked object |
75
|
|
|
|
|
|
|
# if it has a _source attribute |
76
|
|
|
|
|
|
|
# |
77
|
|
|
|
|
|
|
# has _source => (is => 'rw'); |
78
|
|
|
|
|
|
|
|
79
|
0
|
0
|
|
|
|
|
if ($obj->{"_$name"}->can('_source')) { |
80
|
|
|
|
|
|
|
# set the _source attribute to point back |
81
|
|
|
|
|
|
|
# to the linked object. |
82
|
0
|
|
|
|
|
|
$obj->{"_$name"}->_source($obj); |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
0
|
|
|
|
|
|
return $obj->{"_$name"}; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
) |
88
|
0
|
|
|
|
|
|
} |
89
|
0
|
0
|
|
|
|
|
case ('multiple'): { |
|
|
0
|
|
|
|
|
|
90
|
|
|
|
|
|
|
$self->meta->add_method( |
91
|
|
|
|
|
|
|
$name, |
92
|
|
|
|
|
|
|
sub { |
93
|
0
|
|
|
0
|
|
|
return $self->class->schema->link($link->{class})->retrieve_list($link->{args}, $self->{$link->{key}}); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
) |
96
|
0
|
|
|
|
|
|
} |
97
|
0
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=head1 METHODS |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head2 update |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
Updates an object in OpenERP after its properties have been changed. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
$obj->name('New name'); |
111
|
|
|
|
|
|
|
$obj->update; |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Also allows a hashref to be passed to update multiple properties: |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
$obj->update({ |
116
|
|
|
|
|
|
|
name => 'new name', |
117
|
|
|
|
|
|
|
ref => 'new reference', |
118
|
|
|
|
|
|
|
price => 'new price', |
119
|
|
|
|
|
|
|
}); |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=cut |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub update { |
124
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
125
|
|
|
|
|
|
|
|
126
|
0
|
0
|
|
|
|
|
if (my $update = shift) { |
127
|
0
|
|
|
|
|
|
while (my ($param, $value) = each %$update) { |
128
|
0
|
|
|
|
|
|
$self->$param($value); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
} |
131
|
0
|
|
|
|
|
|
my $context = $self->class->_get_context(shift); |
132
|
|
|
|
|
|
|
|
133
|
0
|
|
|
|
|
|
my $object; |
134
|
0
|
|
|
|
|
|
foreach my $attribute ($self->dirty_attributes) { |
135
|
0
|
0
|
|
|
|
|
next if ($attribute eq 'id'); |
136
|
0
|
0
|
|
|
|
|
next if ($attribute =~ '^_'); |
137
|
|
|
|
|
|
|
|
138
|
0
|
|
|
|
|
|
$object->{$attribute} = $self->{$attribute}; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
0
|
|
|
|
|
|
my $relationships = $self->meta->relationship; |
142
|
0
|
|
|
|
|
|
while (my ($name, $rel) = each %$relationships) { |
143
|
0
|
0
|
|
|
|
|
if ($object->{$rel->{key}}) { |
144
|
|
|
|
|
|
|
sswitch ($rel->{type}) { |
145
|
|
|
|
|
|
|
case ('one2many'): { |
146
|
0
|
|
|
|
|
|
delete $object->{$rel->{key}}; # Don't update one2many relationships |
147
|
|
|
|
|
|
|
} |
148
|
0
|
0
|
|
|
|
|
case ('many2many'): { |
|
|
0
|
|
|
|
|
|
149
|
0
|
|
|
|
|
|
$object->{$rel->{key}} = [[6,0,$object->{$rel->{key}}]]; |
150
|
|
|
|
|
|
|
} |
151
|
0
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# Force Str parameters to be object type RPC::XML::string |
156
|
0
|
|
|
|
|
|
foreach my $attribute ($self->meta->get_all_attributes) { |
157
|
0
|
0
|
|
|
|
|
if (exists $object->{$attribute->name}) { |
158
|
0
|
|
|
|
|
|
$object->{$attribute->name} = $self->prepare_attribute_for_send($attribute->type_constraint, $object->{$attribute->name}); |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
$self->class->_with_retries(sub { |
163
|
0
|
|
|
0
|
|
|
$self->class->schema->client->update($self->model, $self->id, $object, $context); |
164
|
0
|
|
|
|
|
|
}); |
165
|
0
|
|
|
|
|
|
$self->refresh; |
166
|
|
|
|
|
|
|
|
167
|
0
|
|
|
|
|
|
return $self; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head2 update_single |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Updates OpenERP with a single property of an object. |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
$obj->name('New name'); |
177
|
|
|
|
|
|
|
$obj->status('Active'); |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
$obj->update_single('name'); # Only the 'name' property is updated |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=cut |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
sub update_single { |
184
|
0
|
|
|
0
|
1
|
|
my ($self, $property) = @_; |
185
|
0
|
|
|
|
|
|
my $value = $self->{$property}; |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# Check to see if the property is the key to a many2many relationship |
188
|
0
|
|
|
|
|
|
my $relationships = $self->meta->relationship; |
189
|
0
|
|
|
|
|
|
my ($key) = grep { $relationships->{$_}->{key} eq $property } keys %$relationships; |
|
0
|
|
|
|
|
|
|
190
|
0
|
0
|
|
|
|
|
if($key) |
191
|
|
|
|
|
|
|
{ |
192
|
0
|
|
|
|
|
|
my $rel = $relationships->{$key}; |
193
|
0
|
0
|
|
|
|
|
if ($rel->{type} eq 'many2many') { |
194
|
0
|
|
|
|
|
|
$value = [[6,0,$value]]; |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# Force Str parameters to be object type RPC::XML::string |
199
|
0
|
|
|
|
|
|
foreach my $attribute ($self->meta->get_all_attributes) { |
200
|
0
|
0
|
|
|
|
|
if ($attribute->name eq $property) { |
201
|
0
|
|
|
|
|
|
$value = $self->prepare_attribute_for_send($attribute->type_constraint, $value); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
0
|
|
|
|
|
|
$self->class->schema->client->update($self->model, $self->id, {$property => $value}); |
206
|
0
|
|
|
|
|
|
return $self; |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=head2 refresh |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
Reloads an object's properties from OpenERP. |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
$obj->refresh; |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=cut |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
sub refresh { |
220
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
221
|
|
|
|
|
|
|
|
222
|
0
|
|
|
|
|
|
my $new = $self->class->retrieve($self->id); |
223
|
|
|
|
|
|
|
|
224
|
0
|
|
|
|
|
|
foreach my $attribute ($self->meta->get_all_attributes) { |
225
|
0
|
|
|
|
|
|
my $name = $attribute->name; |
226
|
0
|
|
|
|
|
|
$self->{$name} = ($new->$name); |
227
|
|
|
|
|
|
|
} |
228
|
0
|
|
|
|
|
|
$self->mark_all_clean; # reset the dirty attribute |
229
|
|
|
|
|
|
|
|
230
|
0
|
|
|
|
|
|
return $self; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=head2 delete |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
Deletes an object from OpenERP. |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
my $obj = $schema->class('Partner')->retrieve(60); |
241
|
|
|
|
|
|
|
$obj->delete; |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
=cut |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub delete { |
246
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
247
|
|
|
|
|
|
|
|
248
|
0
|
|
|
|
|
|
$self->class->schema->client->delete($self->model, $self->id); |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub _copy |
252
|
|
|
|
|
|
|
{ |
253
|
0
|
|
|
0
|
|
|
my $self = shift; |
254
|
|
|
|
|
|
|
|
255
|
0
|
|
|
|
|
|
my $id = $self->class->schema->client->copy($self->model, $self->id); |
256
|
|
|
|
|
|
|
# now load the new invoice and return it |
257
|
0
|
|
|
|
|
|
return $id; |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=head2 copy |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
Clone the current object, returning the new object. |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
This is equivalent to pressing duplicate in the OpenERP user interface. |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=cut |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub copy |
269
|
|
|
|
|
|
|
{ |
270
|
0
|
|
|
0
|
1
|
|
my ($self, @args) = @_; |
271
|
0
|
|
|
|
|
|
my $args = shift; |
272
|
0
|
|
|
|
|
|
my $id = $self->_copy; |
273
|
|
|
|
|
|
|
# passing args through allows for field refinement. |
274
|
0
|
|
|
|
|
|
my $clone = $self->class->retrieve($id, @args); |
275
|
0
|
|
|
|
|
|
return $clone; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=head2 print |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
This is a debug method. |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=cut |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
sub print { |
287
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
288
|
|
|
|
|
|
|
|
289
|
0
|
|
|
|
|
|
say "Print called"; |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=head2 real_create_related |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
This actually does the create related via OpenERP. |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
I'm not sure in what scenarios you should use it versus the scenario's you |
300
|
|
|
|
|
|
|
shouldn't. Suck it and see. |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
It will create calls like this, |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
# DEBUG_RPC:rpc.request:('execute', 'db', 1, '*', ('stock.partial.picking', 'write', [1], {'product_moves_out': [(0, 0, {'prodlot_id': False, 'product_id': 16, 'product_uom': 1, 'quantity': 10.0})]}, {'lang': 'en_GB', 'search_default_available': 1, 'project_id': False, 'tz': False, '__last_update': {'stock.partial.picking,1': False}, 'active_model': 'ir.ui.menu', 'section_id': False, 'contact_display': 'partner_address', 'active_ids': [3], 'active_id': 316})) |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
Note that it will not return the object created. |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=cut |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
sub real_create_related |
311
|
|
|
|
|
|
|
{ |
312
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
313
|
0
|
|
|
|
|
|
my $relation_name = shift; |
314
|
0
|
|
|
|
|
|
my $object = shift; |
315
|
0
|
|
|
|
|
|
my $context = $self->class->_get_context(shift); |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
# find relationship class |
318
|
0
|
|
|
|
|
|
my $class = $self->relationship_class($relation_name); |
319
|
0
|
|
|
|
|
|
my $data = $class->_collapse_data_to_ids($object); |
320
|
|
|
|
|
|
|
|
321
|
0
|
|
|
|
|
|
$self->class->schema->client->update($self->model, $self->id, {$relation_name => [[ 0, 0, $data ]]}, $context); |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
# FIXME: need to check what happens to existing data |
324
|
|
|
|
|
|
|
# how do you add multiple objects ? |
325
|
0
|
|
|
|
|
|
return; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=head2 create_related |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
Creates a related or linked object. |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
$obj->create_related('address',{ |
333
|
|
|
|
|
|
|
street => 'Drury Lane', |
334
|
|
|
|
|
|
|
postcode => 'CV21 3DE', |
335
|
|
|
|
|
|
|
}); |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=cut |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
sub create_related { |
340
|
0
|
|
|
0
|
1
|
|
my ($self, $relation_name, $object) = @_; |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
### Creating related object |
343
|
|
|
|
|
|
|
### $relation_name |
344
|
|
|
|
|
|
|
### with initial data: |
345
|
|
|
|
|
|
|
### $object |
346
|
0
|
|
|
|
|
|
my $created_obj; |
347
|
|
|
|
|
|
|
|
348
|
0
|
0
|
|
|
|
|
if (my $relation = $self->meta->relationship->{$relation_name}) { |
|
|
0
|
|
|
|
|
|
349
|
|
|
|
|
|
|
sswitch ($relation->{type}) { |
350
|
|
|
|
|
|
|
case ('one2many'): { |
351
|
0
|
|
|
|
|
|
my $class = $self->meta->name; |
352
|
0
|
0
|
|
|
|
|
if ($class =~ m/(.*?)::(\w+)$/) { |
353
|
0
|
|
|
|
|
|
my ($base, $name) = ($1, $2); |
354
|
0
|
|
|
|
|
|
my $related_class = $base . "::" . $relation->{class}; |
355
|
|
|
|
|
|
|
|
356
|
0
|
|
|
|
|
|
$self->ensure_class_loaded($related_class); |
357
|
0
|
|
|
|
|
|
my $related_meta = $related_class->meta->relationship; |
358
|
|
|
|
|
|
|
|
359
|
0
|
|
|
|
|
|
my $far_end_relation; |
360
|
0
|
|
|
|
|
|
REL: for my $key (keys %$related_meta) { |
361
|
0
|
|
|
|
|
|
my $value = $related_meta->{$key}; |
362
|
0
|
0
|
|
|
|
|
if ($value->{class} eq $name) { |
363
|
0
|
|
|
|
|
|
$far_end_relation = $key; |
364
|
0
|
|
|
|
|
|
last REL; |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
|
368
|
0
|
0
|
|
|
|
|
if ($far_end_relation) { |
369
|
0
|
|
|
|
|
|
my $foreign_key = $related_meta->{$far_end_relation}->{key}; |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
### Far end relation exists |
372
|
0
|
|
|
|
|
|
$created_obj = $self->class->schema->class($relation->{class})->create({ |
373
|
|
|
|
|
|
|
%$object, |
374
|
|
|
|
|
|
|
$foreign_key => $self->id, |
375
|
|
|
|
|
|
|
}); |
376
|
|
|
|
|
|
|
|
377
|
0
|
|
|
|
|
|
$self->refresh; |
378
|
|
|
|
|
|
|
} else { |
379
|
0
|
|
|
|
|
|
my $new_object = $self->class->schema->class($relation->{class})->create($object); |
380
|
|
|
|
|
|
|
|
381
|
0
|
|
|
|
|
|
$created_obj = $new_object; |
382
|
0
|
|
|
|
|
|
$self->refresh; |
383
|
|
|
|
|
|
|
|
384
|
0
|
0
|
|
|
|
|
unless (grep {$new_object->id} @{$self->{$relation->{key}}}) { |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
385
|
0
|
|
|
|
|
|
push @{$self->{$relation->{key}}}, $new_object->id; |
|
0
|
|
|
|
|
|
|
386
|
0
|
|
|
|
|
|
$self->update; |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
} |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
} |
391
|
|
|
|
|
|
|
case ('many2many'): { |
392
|
0
|
|
|
|
|
|
say "create_related many2many"; |
393
|
|
|
|
|
|
|
} |
394
|
0
|
0
|
|
|
|
|
case ('many2one'): { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
395
|
0
|
|
|
|
|
|
say "create_related many2one"; |
396
|
|
|
|
|
|
|
} |
397
|
0
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
} elsif ($relation = $self->meta->link->{$relation_name}) { |
399
|
|
|
|
|
|
|
sswitch ($relation->{type}) { |
400
|
|
|
|
|
|
|
case ('single'): { |
401
|
|
|
|
|
|
|
### Creating linked object |
402
|
|
|
|
|
|
|
try { |
403
|
0
|
|
|
0
|
|
|
my $id = $self->class->schema->link($relation->{class})->create($relation->{args}, $object); |
404
|
0
|
|
|
|
|
|
$created_obj = $id; |
405
|
|
|
|
|
|
|
### Linked object created with key $id |
406
|
0
|
|
|
|
|
|
$self->{$relation->{key}} = $id; |
407
|
0
|
|
|
|
|
|
$self->update_single($relation->{key}); |
408
|
0
|
|
|
|
|
|
undef $self->{"_$relation_name"}; |
409
|
|
|
|
|
|
|
} catch { |
410
|
0
|
|
|
0
|
|
|
die "Error creating linked object: $_[0]"; |
411
|
0
|
|
|
|
|
|
}; |
412
|
|
|
|
|
|
|
} |
413
|
0
|
0
|
|
|
|
|
case ('multiple'): { |
|
|
0
|
|
|
|
|
|
414
|
0
|
|
|
|
|
|
say "create_linked multiple"; |
415
|
|
|
|
|
|
|
} |
416
|
0
|
|
|
|
|
|
} |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
else { |
419
|
0
|
|
|
|
|
|
croak "Can not find relation $relation_name"; |
420
|
|
|
|
|
|
|
} |
421
|
0
|
0
|
|
|
|
|
return $created_obj if $created_obj; |
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
sub _id |
425
|
|
|
|
|
|
|
{ |
426
|
0
|
|
|
0
|
|
|
my $val = shift; |
427
|
0
|
0
|
|
|
|
|
return ref $val ? $val->id : $val; |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
=head2 find_related |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
Finds a property related to the current object. |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
my $line = $po->find_related('order_lines', [ 'id', '=', 1 ]); |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
This only works with relationships to OpenERP objects (i.e. not DBIC) and |
437
|
|
|
|
|
|
|
to one2many relationships where the other side of the relationship has a field |
438
|
|
|
|
|
|
|
pointing back to the object you are searching from. |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
In any other case the method will croak. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
If the search criteria return more than one result it will whine. |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
=cut |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
sub find_related { |
447
|
0
|
|
|
0
|
1
|
|
my ($self) = shift; |
448
|
0
|
|
|
|
|
|
my @results = $self->search_related(@_); |
449
|
0
|
0
|
|
|
|
|
if(scalar @results > 1) |
450
|
|
|
|
|
|
|
{ |
451
|
|
|
|
|
|
|
# should this just croak? |
452
|
0
|
|
|
|
|
|
carp 'find_related returned more than 1 result'; |
453
|
|
|
|
|
|
|
} |
454
|
0
|
0
|
|
|
|
|
if(@results) |
455
|
|
|
|
|
|
|
{ |
456
|
0
|
|
|
|
|
|
return $results[0]; |
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
} |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
=head2 relationship_class |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
Returns the OpenERP::OOM::Class object for the relationship passed in. |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
Obviously this only works for the OpenERP relationships. It will croak |
465
|
|
|
|
|
|
|
if you ask for a relationship to a DBIC object. |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
=cut |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
sub relationship_class |
470
|
|
|
|
|
|
|
{ |
471
|
0
|
|
|
0
|
1
|
|
my ($self, $relationship) = @_; |
472
|
0
|
0
|
|
|
|
|
if (my $relation = $self->meta->relationship->{$relationship}) { |
473
|
0
|
|
|
|
|
|
my $type = $relation->{type}; |
474
|
0
|
0
|
0
|
|
|
|
croak 'Cannot get a class for a DBIC relationship' if $type eq 'single' |
475
|
|
|
|
|
|
|
|| $type eq 'multiple'; |
476
|
0
|
|
|
|
|
|
my $class = $relation->{class}; |
477
|
0
|
|
|
|
|
|
return $self->class->schema->class($class); |
478
|
|
|
|
|
|
|
} |
479
|
0
|
|
|
|
|
|
croak "Unable to find relation $relationship"; |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
=head2 search_related |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
Searches for objects of a relation associated with this object. |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
my @lines = $po->search_related('order_lines', [ 'state', '=', 'draft' ]); |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
This only works with relationships to OpenERP objects (i.e. not DBIC) and |
489
|
|
|
|
|
|
|
to one2many relationships where the other side of the relationship has a field |
490
|
|
|
|
|
|
|
pointing back to the object you are searching from. |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
In any other case the method will croak. |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=cut |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
sub search_related { |
497
|
0
|
|
|
0
|
1
|
|
my ($self, $relation_name, @search) = @_; |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
# find the relation details and add it to the search criteria. |
500
|
0
|
0
|
|
|
|
|
if (my $relation = $self->meta->relationship->{$relation_name}) { |
|
|
0
|
|
|
|
|
|
501
|
|
|
|
|
|
|
sswitch ($relation->{type}) { |
502
|
|
|
|
|
|
|
case ('one2many'): { |
503
|
0
|
|
|
|
|
|
my $class = $self->meta->name; |
504
|
0
|
0
|
|
|
|
|
if ($class =~ m/(.*?)::(\w+)$/) { |
505
|
0
|
|
|
|
|
|
my ($base, $name) = ($1, $2); |
506
|
0
|
|
|
|
|
|
my $related_class = $self->class->schema->class($relation->{class}); |
507
|
0
|
|
|
|
|
|
my $related_meta = $related_class->object->meta->relationship; |
508
|
|
|
|
|
|
|
|
509
|
0
|
|
|
|
|
|
my $far_end_relation; |
510
|
0
|
|
|
|
|
|
REL: for my $key (keys %$related_meta) { |
511
|
0
|
|
|
|
|
|
my $value = $related_meta->{$key}; |
512
|
0
|
0
|
|
|
|
|
if ($value->{class} eq $name) { |
513
|
0
|
|
|
|
|
|
$far_end_relation = $key; |
514
|
0
|
|
|
|
|
|
last REL; |
515
|
|
|
|
|
|
|
} |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
0
|
0
|
|
|
|
|
if ($far_end_relation) { |
519
|
|
|
|
|
|
|
|
520
|
0
|
|
|
|
|
|
my $foreign_key = $related_meta->{$far_end_relation}->{key}; |
521
|
|
|
|
|
|
|
|
522
|
0
|
|
|
|
|
|
push @search, [ $foreign_key, '=', $self->id ]; |
523
|
0
|
|
|
|
|
|
return $related_class->search(@search); |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
} else { |
526
|
|
|
|
|
|
|
# well, perhaps we could fix this, but I can't be bothered at the moment. |
527
|
0
|
|
|
|
|
|
croak 'Unable to search_related without relationship back'; |
528
|
|
|
|
|
|
|
} |
529
|
|
|
|
|
|
|
} |
530
|
|
|
|
|
|
|
} |
531
|
|
|
|
|
|
|
case ('many2many'): { |
532
|
0
|
|
|
|
|
|
croak 'Unable to search_related many2many relationships'; |
533
|
|
|
|
|
|
|
} |
534
|
0
|
0
|
|
|
|
|
case ('many2one'): { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
535
|
0
|
|
|
|
|
|
croak 'Unable to search_related many2one relationships'; |
536
|
|
|
|
|
|
|
} |
537
|
0
|
|
|
|
|
|
} |
538
|
|
|
|
|
|
|
} elsif ($relation = $self->meta->link->{$relation_name}) { |
539
|
0
|
|
|
|
|
|
croak 'Unable to search_related outside NonOpenERP'; |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
|
542
|
0
|
|
|
|
|
|
croak 'Unable to search_related'; # beat up the lame programmer who did this. |
543
|
|
|
|
|
|
|
} |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
=head2 add_related |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
Adds a related or linked object to a one2many, many2many, or multiple relationship. |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
my $partner = $schema->class('Partner')->find(...); |
553
|
|
|
|
|
|
|
my $category = $schema->class('PartnerCategory')->find(...); |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
$partner->add_related('category', $category); |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
=cut |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
sub add_related { |
560
|
0
|
|
|
0
|
1
|
|
my ($self, $relation_name, $object) = @_; |
561
|
|
|
|
|
|
|
|
562
|
0
|
0
|
|
|
|
|
if (my $relation = $self->meta->relationship->{$relation_name}) { |
|
|
0
|
|
|
|
|
|
563
|
|
|
|
|
|
|
sswitch ($relation->{type}) { |
564
|
|
|
|
|
|
|
case ('one2many'): { |
565
|
|
|
|
|
|
|
# FIXME - is this the same process as adding a many2many relationship? |
566
|
|
|
|
|
|
|
} |
567
|
0
|
0
|
|
|
|
|
case ('many2many'): { |
|
|
0
|
|
|
|
|
|
568
|
0
|
|
|
|
|
|
push @{$self->{$relation->{key}}}, _id($object); |
|
0
|
|
|
|
|
|
|
569
|
0
|
|
|
|
|
|
$self->{$relation->{key}} = [uniq @{$self->{$relation->{key}}}]; |
|
0
|
|
|
|
|
|
|
570
|
0
|
|
|
|
|
|
$self->update_single($relation->{key}); |
571
|
|
|
|
|
|
|
} |
572
|
0
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
} elsif ($relation = $self->meta->link->{$relation_name}) { |
574
|
|
|
|
|
|
|
sswitch ($relation->{type}) { |
575
|
0
|
0
|
|
|
|
|
case ('multiple'): { |
576
|
|
|
|
|
|
|
# FIXME - handle linked as well as related objects |
577
|
|
|
|
|
|
|
} |
578
|
0
|
|
|
|
|
|
} |
579
|
|
|
|
|
|
|
} |
580
|
|
|
|
|
|
|
} |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
=head2 set_related |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
Like the DBIx::Class set_related. Sets up a link to a related object. |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
=cut |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
sub set_related { |
592
|
0
|
|
|
0
|
1
|
|
my ($self, $relation_name, $object) = @_; |
593
|
|
|
|
|
|
|
|
594
|
0
|
0
|
|
|
|
|
if (my $relation = $self->meta->relationship->{$relation_name}) { |
595
|
|
|
|
|
|
|
sswitch ($relation->{type}) { |
596
|
|
|
|
|
|
|
case ('many2one'): { |
597
|
0
|
0
|
|
|
|
|
$self->{$relation->{key}} = $object ? _id($object) : undef; |
598
|
0
|
|
|
|
|
|
$self->update_single($relation->{key}); |
599
|
|
|
|
|
|
|
} |
600
|
|
|
|
|
|
|
case ('many2many'): { |
601
|
0
|
|
|
|
|
|
my @array; |
602
|
0
|
0
|
|
|
|
|
if($object) |
603
|
|
|
|
|
|
|
{ |
604
|
0
|
0
|
|
|
|
|
if(ref $object eq 'ARRAY') |
605
|
|
|
|
|
|
|
{ |
606
|
0
|
|
|
|
|
|
@array = map { _id($_) } @$object; |
|
0
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
} |
608
|
|
|
|
|
|
|
else |
609
|
|
|
|
|
|
|
{ |
610
|
0
|
|
|
|
|
|
push @array, _id($object); |
611
|
|
|
|
|
|
|
} |
612
|
|
|
|
|
|
|
} |
613
|
0
|
|
|
|
|
|
$self->{$relation->{key}} = \@array; |
614
|
0
|
|
|
|
|
|
$self->update_single($relation->{key}); |
615
|
|
|
|
|
|
|
} |
616
|
0
|
0
|
|
|
|
|
default: { |
|
|
0
|
|
|
|
|
|
617
|
0
|
|
|
|
|
|
carp "Cannot use set_related() on a $_ relationship"; |
618
|
|
|
|
|
|
|
} |
619
|
0
|
|
|
|
|
|
} |
620
|
|
|
|
|
|
|
} else { |
621
|
0
|
|
|
|
|
|
carp "Relation '$relation_name' does not exist!"; |
622
|
|
|
|
|
|
|
} |
623
|
|
|
|
|
|
|
} |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
=head2 execute_workflow |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
Performs an exec_workflow in OpenERP. |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
$self->execute_workflow('purchase_confirm'); |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
Is likely to translate to something like this, |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
# DEBUG_RPC:rpc.request:('exec_workflow', 'db', 1, '*', ('purchase.order', 'purchase_confirm', 24)) |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
The 24 is the id of the object. |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
=cut |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
sub execute_workflow |
640
|
|
|
|
|
|
|
{ |
641
|
0
|
|
|
0
|
1
|
|
my ($self, $workflow) = @_; |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
retry |
644
|
|
|
|
|
|
|
{ |
645
|
0
|
|
|
0
|
|
|
$self->class->schema->client->object_exec_workflow($workflow, $self->model, $self->id); |
646
|
|
|
|
|
|
|
} |
647
|
0
|
|
|
0
|
|
|
retry_if {/current transaction is aborted, commands ignored until end of transaction block/} |
648
|
|
|
|
|
|
|
catch |
649
|
|
|
|
|
|
|
{ |
650
|
0
|
|
|
0
|
|
|
die $_; # rethrow the unhandled exception |
651
|
0
|
|
|
|
|
|
}; |
652
|
|
|
|
|
|
|
} |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
=head2 execute |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
Performs an execute in OpenERP. |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
$self->execute('action_process'); |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
Is likely to translate to something like this, |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
# DEBUG_RPC:rpc.request:('execute', 'gooner', 1, '*', ('stock.picking', 'action_process', [26], {'lang': 'en_GB', 'search_default_available': 1, 'active_ids': [316], 'tz': False, 'active_model': 'ir.ui.menu', 'section_id': False, 'contact_display': 'partner_address', 'project_id': False, 'active_id': 316})) |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
The 26 is the id of the object. |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=cut |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
sub execute |
669
|
|
|
|
|
|
|
{ |
670
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
671
|
0
|
|
|
|
|
|
my $action = shift; |
672
|
0
|
|
|
|
|
|
my @params = @_; |
673
|
|
|
|
|
|
|
|
674
|
0
|
|
|
|
|
|
my @args = ($action, $self->model, [$self->id], @params); |
675
|
0
|
|
|
|
|
|
my $retval; |
676
|
|
|
|
|
|
|
$self->class->_with_retries(sub { |
677
|
0
|
|
|
0
|
|
|
$retval = $self->class->schema->client->object_execute(@args); |
678
|
0
|
|
|
|
|
|
}); |
679
|
0
|
|
|
|
|
|
return $retval; |
680
|
|
|
|
|
|
|
} |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
=head2 executex |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
Similar to execute but it allows you to specify any number of parameters. |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
Primarily created to prevent any compatibility problems with other callers. |
687
|
|
|
|
|
|
|
Although I'm not entirely sure if there are any. |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
$self->executex('add_invoices_to_payment', [1,2], [3,4]); |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
Translates roughly to |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
execute_kw(..., 'payment.order', 'add_invoices_to_payment', [5], [1, 2], [3, 4]) |
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
Stick a hash on the end of the list of params to pass a context object. |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
=cut |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
sub executex |
700
|
|
|
|
|
|
|
{ |
701
|
0
|
|
|
0
|
1
|
|
my ($self, $action, @rest) = @_; |
702
|
|
|
|
|
|
|
|
703
|
0
|
|
|
|
|
|
my @args = ($action, $self->model, [$self->id]); |
704
|
0
|
0
|
|
|
|
|
push @args, @rest if @rest; |
705
|
0
|
|
|
|
|
|
my $retval; |
706
|
|
|
|
|
|
|
$self->class->_with_retries(sub { |
707
|
0
|
|
|
0
|
|
|
$retval = $self->class->schema->client->object_execute(@args); |
708
|
0
|
|
|
|
|
|
}); |
709
|
0
|
|
|
|
|
|
return $retval; |
710
|
|
|
|
|
|
|
} |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
=head2 get_report |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
To print a purchase order we need to send a report, then get it, then display it, then print it (and you don't want to know about all the traffic behind the scenes...) |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
The first step looks like this: |
717
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
# DEBUG_RPC:rpc.request:('report', 'aquarius_openerp_jj_staging', 1, '*', (u'purchase.quotation', [1], {'model': u'purchase.order', 'id': 1, 'report_type': u'pdf'}, {'lang': u'en_GB', 'active_ids': [1], 'tz': False, 'active_model': u'purchase.order', 'section_id': False, 'search_default_draft': 1, 'project_id': False, 'active_id': 1})) |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
=cut |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
sub get_report |
723
|
|
|
|
|
|
|
{ |
724
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
725
|
0
|
|
|
|
|
|
my $report_id = shift; |
726
|
|
|
|
|
|
|
|
727
|
0
|
|
|
|
|
|
my $id = $self->class->schema->client->report_report($report_id, $self->id, |
728
|
|
|
|
|
|
|
{ |
729
|
|
|
|
|
|
|
model => $self->model, |
730
|
|
|
|
|
|
|
id => $self->id, |
731
|
|
|
|
|
|
|
report_type => 'pdf', |
732
|
|
|
|
|
|
|
}, @_); |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
# the report_report function returns only a report id, which is all we need to pass to the next function call |
735
|
|
|
|
|
|
|
# but report_report_get don't work first time (?!) so we need to call it recursively until with get an answer |
736
|
0
|
|
|
|
|
|
my $data; |
737
|
0
|
|
|
|
|
|
while(!$data) |
738
|
|
|
|
|
|
|
{ |
739
|
0
|
|
|
|
|
|
$data = $self->class->schema->client->report_report_get($id); |
740
|
0
|
|
|
|
|
|
sleep 1; |
741
|
|
|
|
|
|
|
} |
742
|
0
|
|
|
|
|
|
return $data; |
743
|
|
|
|
|
|
|
} |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
1; |