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