| 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; |