Lines 19-24
package Koha::MarcOrder;
Link Here
|
19 |
|
19 |
|
20 |
use Modern::Perl; |
20 |
use Modern::Perl; |
21 |
use Try::Tiny qw( catch try ); |
21 |
use Try::Tiny qw( catch try ); |
|
|
22 |
use Net::FTP; |
22 |
|
23 |
|
23 |
use base qw(Koha::Object); |
24 |
use base qw(Koha::Object); |
24 |
|
25 |
|
Lines 41-55
use C4::ImportBatch qw(
Link Here
|
41 |
GetImportBatchRangeDesc |
42 |
GetImportBatchRangeDesc |
42 |
GetNumberOfNonZ3950ImportBatches |
43 |
GetNumberOfNonZ3950ImportBatches |
43 |
); |
44 |
); |
44 |
use C4::Search qw( FindDuplicate ); |
45 |
use C4::Search qw( FindDuplicate ); |
45 |
use C4::Acquisition qw( NewBasket ); |
46 |
use C4::Acquisition qw( NewBasket ); |
46 |
use C4::Biblio qw( |
47 |
use C4::Biblio qw( |
47 |
AddBiblio |
48 |
AddBiblio |
48 |
GetMarcFromKohaField |
49 |
GetMarcFromKohaField |
49 |
TransformHtmlToXml |
50 |
TransformHtmlToXml |
50 |
GetMarcQuantity |
|
|
51 |
); |
51 |
); |
52 |
use C4::Items qw( AddItemFromMarc ); |
52 |
use C4::Items qw( AddItemFromMarc ); |
53 |
use C4::Budgets qw( GetBudgetByCode ); |
53 |
use C4::Budgets qw( GetBudgetByCode ); |
54 |
|
54 |
|
55 |
use Koha::Database; |
55 |
use Koha::Database; |
Lines 70-75
Koha::MarcOrder - Koha Marc Order Object class
Link Here
|
70 |
|
70 |
|
71 |
=cut |
71 |
=cut |
72 |
|
72 |
|
|
|
73 |
=head3 create_order_lines_from_file |
74 |
|
75 |
my $result = Koha::MarcOrder->create_order_lines_from_file($args); |
76 |
|
77 |
Controller for file staging, basket creation and order line creation when using the cronjob in marc_ordering_process.pl |
78 |
|
79 |
=cut |
80 |
|
81 |
sub create_order_lines_from_file { |
82 |
my ( $self, $args ) = @_; |
83 |
|
84 |
my $filename = $args->{filename}; |
85 |
my $filepath = $args->{filepath}; |
86 |
my $profile = $args->{profile}; |
87 |
my $agent = $args->{agent}; |
88 |
|
89 |
my $success; |
90 |
my $error; |
91 |
|
92 |
my $vendor_id = $profile->vendor_id; |
93 |
my $budget_id = $profile->budget_id; |
94 |
|
95 |
my $vendor_record = Koha::Acquisition::Booksellers->find({ id => $vendor_id }); |
96 |
|
97 |
my $basket_id = _create_basket_for_file({ |
98 |
filename => $filename, |
99 |
vendor_id => $vendor_id |
100 |
}); |
101 |
|
102 |
my $format = index($filename, '.mrc') != -1 ? 'ISO2709' : 'MARCXML'; |
103 |
my $params = { |
104 |
record_type => $profile->record_type, |
105 |
encoding => $profile->encoding, |
106 |
format => $format, |
107 |
filepath => $filepath, |
108 |
filename => $filename, |
109 |
comments => undef, |
110 |
parse_items => $profile->parse_items, |
111 |
matcher_id => $profile->matcher_id, |
112 |
overlay_action => $profile->overlay_action, |
113 |
nomatch_action => $profile->nomatch_action, |
114 |
item_action => $profile->item_action, |
115 |
}; |
116 |
|
117 |
try { |
118 |
my $import_batch_id = _stage_file($params); |
119 |
|
120 |
my $import_records = Koha::Import::Records->search({ |
121 |
import_batch_id => $import_batch_id, |
122 |
}); |
123 |
|
124 |
while( my $import_record = $import_records->next ){ |
125 |
my $result = add_biblios_from_import_record({ |
126 |
import_batch_id => $import_batch_id, |
127 |
import_record => $import_record, |
128 |
matcher_id => $params->{matcher_id}, |
129 |
overlay_action => $params->{overlay_action}, |
130 |
agent => $agent, |
131 |
}); |
132 |
warn "Duplicates found in $result->{duplicates_in_batch}, record was skipped." if $result->{duplicates_in_batch}; |
133 |
next if $result->{skip}; |
134 |
|
135 |
my $order_line_details = add_items_from_import_record({ |
136 |
record_result => $result->{record_result}, |
137 |
basket_id => $basket_id, |
138 |
vendor => $vendor_record, |
139 |
budget_id => $budget_id, |
140 |
agent => $agent, |
141 |
}); |
142 |
|
143 |
my $order_lines = create_order_lines({ |
144 |
order_line_details => $order_line_details |
145 |
}); |
146 |
}; |
147 |
SetImportBatchStatus( $import_batch_id, 'imported' ) |
148 |
if Koha::Import::Records->search({import_batch_id => $import_batch_id, status => 'imported' })->count |
149 |
== Koha::Import::Records->search({import_batch_id => $import_batch_id})->count; |
150 |
|
151 |
$success = 1; |
152 |
} catch { |
153 |
$success = 0; |
154 |
$error = $_; |
155 |
}; |
156 |
|
157 |
return $success ? { success => 1, error => ''} : { success => 0, error => $error }; |
158 |
} |
159 |
|
73 |
=head3 import_record_and_create_order_lines |
160 |
=head3 import_record_and_create_order_lines |
74 |
|
161 |
|
75 |
my $result = Koha::MarcOrder->import_record_and_create_order_lines($args); |
162 |
my $result = Koha::MarcOrder->import_record_and_create_order_lines($args); |
Lines 82-88
sub import_record_and_create_order_lines {
Link Here
|
82 |
my ( $self, $args ) = @_; |
169 |
my ( $self, $args ) = @_; |
83 |
|
170 |
|
84 |
my $import_batch_id = $args->{import_batch_id}; |
171 |
my $import_batch_id = $args->{import_batch_id}; |
85 |
my $import_record_id_selected = $args->{import_record_id_selected} || (); |
172 |
my @import_record_id_selected = $args->{import_record_id_selected} || (); |
86 |
my $matcher_id = $args->{matcher_id}; |
173 |
my $matcher_id = $args->{matcher_id}; |
87 |
my $overlay_action = $args->{overlay_action}; |
174 |
my $overlay_action = $args->{overlay_action}; |
88 |
my $import_record = $args->{import_record}; |
175 |
my $import_record = $args->{import_record}; |
Lines 108-163
sub import_record_and_create_order_lines {
Link Here
|
108 |
skip => $result->{skip} |
195 |
skip => $result->{skip} |
109 |
} if $result->{skip}; |
196 |
} if $result->{skip}; |
110 |
|
197 |
|
111 |
my $order_line_details = add_items_from_import_record( |
198 |
my $order_line_details = add_items_from_import_record({ |
112 |
{ |
199 |
record_result => $result->{record_result}, |
113 |
record_result => $result->{record_result}, |
200 |
basket_id => $basket_id, |
114 |
basket_id => $basket_id, |
201 |
vendor => $vendor, |
115 |
vendor => $vendor, |
202 |
budget_id => $budget_id, |
116 |
budget_id => $budget_id, |
203 |
agent => $agent, |
117 |
agent => $agent, |
204 |
client_item_fields => $client_item_fields |
118 |
client_item_fields => $client_item_fields |
205 |
}); |
119 |
} |
|
|
120 |
); |
121 |
|
206 |
|
122 |
my $order_lines = create_order_lines( { order_line_details => $order_line_details } ); |
207 |
my $order_lines = create_order_lines({ |
|
|
208 |
order_line_details => $order_line_details |
209 |
}); |
123 |
|
210 |
|
124 |
return { |
211 |
return { |
125 |
duplicates_in_batch => 0, |
212 |
duplicates_in_batch => 0, |
126 |
skip => 0 |
213 |
skip => 0 |
127 |
}; |
214 |
} |
128 |
} |
215 |
} |
129 |
|
216 |
|
130 |
=head3 _get_MarcFieldsToOrder_syspref_data |
217 |
=head3 _create_basket_for_file |
131 |
|
218 |
|
132 |
my $marc_fields_to_order = _get_MarcFieldsToOrder_syspref_data('MarcFieldsToOrder', $marcrecord, $fields); |
219 |
my $basket_id = _create_basket_for_file({ |
|
|
220 |
filename => $filename, |
221 |
vendor_id => $vendor_id |
222 |
}); |
133 |
|
223 |
|
134 |
Fetches data from a marc record based on the mappings in the syspref MarcFieldsToOrder using the fields selected in $fields (array). |
224 |
Creates a basket ready to receive order lines based on the imported file |
135 |
|
225 |
|
136 |
=cut |
226 |
=cut |
137 |
|
227 |
|
138 |
sub _get_MarcFieldsToOrder_syspref_data { |
228 |
sub _create_basket_for_file { |
139 |
my ( $syspref_name, $record, $field_list ) = @_; |
229 |
my ( $args ) = @_; |
140 |
my $syspref = C4::Context->preference($syspref_name); |
230 |
|
141 |
$syspref = "$syspref\n\n"; |
231 |
my $filename = $args->{filename}; |
142 |
my $yaml = eval { YAML::XS::Load( Encode::encode_utf8($syspref) ); }; |
232 |
my $vendor_id = $args->{vendor_id}; |
143 |
if ($@) { |
233 |
|
144 |
warn "Unable to parse $syspref syspref : $@"; |
234 |
# aqbasketname.basketname has a max length of 50 characters so long file names will need to be truncated |
145 |
return (); |
235 |
my $basketname = length($filename) > 50 ? substr( $filename, 0, 50 ): $filename; |
146 |
} |
236 |
|
147 |
my $r; |
237 |
my $basketno = |
148 |
for my $field_name (@$field_list) { |
238 |
NewBasket( $vendor_id, 0, $basketname, q{}, |
149 |
next unless exists $yaml->{$field_name}; |
239 |
q{} . q{} ); |
150 |
my @fields = split /\|/, $yaml->{$field_name}; |
240 |
|
151 |
for my $field (@fields) { |
241 |
return $basketno; |
152 |
my ( $f, $sf ) = split /\$/, $field; |
242 |
} |
153 |
next unless $f and $sf; |
243 |
|
154 |
if ( my $v = $record->subfield( $f, $sf ) ) { |
244 |
=head3 _stage_file |
155 |
$r->{$field_name} = $v; |
245 |
|
|
|
246 |
$file->_stage_file($params) |
247 |
|
248 |
Stages a file directly using parameters from a marc ordering account and without using the background job |
249 |
This function is a mirror of Koha::BackgroundJob::StageMARCForImport->process but with the background job functionality removed |
250 |
|
251 |
=cut |
252 |
|
253 |
sub _stage_file { |
254 |
my ( $args ) = @_; |
255 |
|
256 |
my $record_type = $args->{record_type}; |
257 |
my $encoding = $args->{encoding}; |
258 |
my $format = $args->{format}; |
259 |
my $filepath = $args->{filepath}; |
260 |
my $filename = $args->{filename}; |
261 |
my $marc_modification_template = $args->{marc_modification_template}; |
262 |
my $comments = $args->{comments}; |
263 |
my $parse_items = $args->{parse_items}; |
264 |
my $matcher_id = $args->{matcher_id}; |
265 |
my $overlay_action = $args->{overlay_action}; |
266 |
my $nomatch_action = $args->{nomatch_action}; |
267 |
my $item_action = $args->{item_action}; |
268 |
|
269 |
my @messages; |
270 |
my ( $batch_id, $num_valid, $num_items, @import_errors ); |
271 |
my $num_with_matches = 0; |
272 |
my $checked_matches = 0; |
273 |
my $matcher_failed = 0; |
274 |
my $matcher_code = ""; |
275 |
|
276 |
my $schema = Koha::Database->new->schema; |
277 |
try { |
278 |
$schema->storage->txn_begin; |
279 |
|
280 |
my ( $errors, $marcrecords ); |
281 |
if ( $format eq 'MARCXML' ) { |
282 |
( $errors, $marcrecords ) = |
283 |
C4::ImportBatch::RecordsFromMARCXMLFile( $filepath, $encoding ); |
284 |
} |
285 |
elsif ( $format eq 'ISO2709' ) { |
286 |
( $errors, $marcrecords ) = |
287 |
C4::ImportBatch::RecordsFromISO2709File( $filepath, $record_type, |
288 |
$encoding ); |
289 |
} |
290 |
else { # plugin based |
291 |
$errors = []; |
292 |
$marcrecords = |
293 |
C4::ImportBatch::RecordsFromMarcPlugin( $filepath, $format, |
294 |
$encoding ); |
295 |
} |
296 |
|
297 |
( $batch_id, $num_valid, $num_items, @import_errors ) = BatchStageMarcRecords( |
298 |
$record_type, $encoding, |
299 |
$marcrecords, $filename, |
300 |
$marc_modification_template, $comments, |
301 |
'', $parse_items, |
302 |
0 |
303 |
); |
304 |
|
305 |
if ($matcher_id) { |
306 |
my $matcher = C4::Matcher->fetch($matcher_id); |
307 |
if ( defined $matcher ) { |
308 |
$checked_matches = 1; |
309 |
$matcher_code = $matcher->code(); |
310 |
$num_with_matches = |
311 |
BatchFindDuplicates( $batch_id, $matcher, 10); |
312 |
SetImportBatchMatcher( $batch_id, $matcher_id ); |
313 |
SetImportBatchOverlayAction( $batch_id, $overlay_action ); |
314 |
SetImportBatchNoMatchAction( $batch_id, $nomatch_action ); |
315 |
SetImportBatchItemAction( $batch_id, $item_action ); |
316 |
$schema->storage->txn_commit; |
156 |
} |
317 |
} |
157 |
last if $yaml->{$field}; |
318 |
else { |
|
|
319 |
$matcher_failed = 1; |
320 |
$schema->storage->txn_rollback; |
321 |
} |
322 |
} else { |
323 |
$schema->storage->txn_commit; |
158 |
} |
324 |
} |
|
|
325 |
|
326 |
return $batch_id; |
159 |
} |
327 |
} |
160 |
return $r; |
328 |
catch { |
|
|
329 |
warn $_; |
330 |
$schema->storage->txn_rollback; |
331 |
die "Something terrible has happened!" |
332 |
if ( $_ =~ /Rollback failed/ ); # TODO Check test: Rollback failed |
333 |
}; |
161 |
} |
334 |
} |
162 |
|
335 |
|
163 |
=head3 _get_MarcItemFieldsToOrder_syspref_data |
336 |
=head3 _get_MarcItemFieldsToOrder_syspref_data |
Lines 185-192
sub _get_MarcItemFieldsToOrder_syspref_data {
Link Here
|
185 |
} |
358 |
} |
186 |
@tags_list = List::MoreUtils::uniq(@tags_list); |
359 |
@tags_list = List::MoreUtils::uniq(@tags_list); |
187 |
|
360 |
|
188 |
my $tags_count = _verify_number_of_fields( \@tags_list, $record ); |
361 |
die "System preference MarcItemFieldsToOrder has not been filled in. Please set the mapping values to use this cron script." if scalar(@tags_list == 0); |
189 |
|
362 |
|
|
|
363 |
my $tags_count = _verify_number_of_fields(\@tags_list, $record); |
190 |
# Return if the number of these fields in the record is not the same. |
364 |
# Return if the number of these fields in the record is not the same. |
191 |
die "Invalid number of fields detected on field $tags_count->{key}, please check this file" if $tags_count->{error}; |
365 |
die "Invalid number of fields detected on field $tags_count->{key}, please check this file" if $tags_count->{error}; |
192 |
|
366 |
|
Lines 194-200
sub _get_MarcItemFieldsToOrder_syspref_data {
Link Here
|
194 |
my $fields_hash; |
368 |
my $fields_hash; |
195 |
foreach my $tag (@tags_list) { |
369 |
foreach my $tag (@tags_list) { |
196 |
my @tmp_fields; |
370 |
my @tmp_fields; |
197 |
foreach my $field ( $record->field($tag) ) { |
371 |
foreach my $field ($record->field($tag)) { |
198 |
push @tmp_fields, $field; |
372 |
push @tmp_fields, $field; |
199 |
} |
373 |
} |
200 |
$fields_hash->{$tag} = \@tmp_fields; |
374 |
$fields_hash->{$tag} = \@tmp_fields; |
Lines 229-235
sub _get_MarcItemFieldsToOrder_syspref_data {
Link Here
|
229 |
=cut |
403 |
=cut |
230 |
|
404 |
|
231 |
sub _verify_number_of_fields { |
405 |
sub _verify_number_of_fields { |
232 |
my ( $tags_list, $record ) = @_; |
406 |
my ($tags_list, $record) = @_; |
233 |
my $tag_fields_count; |
407 |
my $tag_fields_count; |
234 |
for my $tag (@$tags_list) { |
408 |
for my $tag (@$tags_list) { |
235 |
my @fields = $record->field($tag); |
409 |
my @fields = $record->field($tag); |
Lines 238-250
sub _verify_number_of_fields {
Link Here
|
238 |
|
412 |
|
239 |
my $tags_count; |
413 |
my $tags_count; |
240 |
foreach my $key ( keys %$tag_fields_count ) { |
414 |
foreach my $key ( keys %$tag_fields_count ) { |
241 |
if ( $tag_fields_count->{$key} > 0 ) { # Having 0 of a field is ok |
415 |
if ( $tag_fields_count->{$key} > 0 ) { # Having 0 of a field is ok |
242 |
$tags_count //= $tag_fields_count->{$key}; # Start with the count from the first occurrence |
416 |
$tags_count //= $tag_fields_count->{$key}; # Start with the count from the first occurrence |
243 |
return { error => 1, key => $key } |
417 |
return { error => 1, key => $key } if $tag_fields_count->{$key} != $tags_count; # All counts of various fields should be equal if they exist |
244 |
if $tag_fields_count->{$key} != |
|
|
245 |
$tags_count; # All counts of various fields should be equal if they exist |
246 |
} |
418 |
} |
247 |
} |
419 |
} |
|
|
420 |
|
248 |
return { error => 0, count => $tags_count }; |
421 |
return { error => 0, count => $tags_count }; |
249 |
} |
422 |
} |
250 |
|
423 |
|
Lines 269-275
sub add_biblio_from_import_record {
Link Here
|
269 |
my ($args) = @_; |
442 |
my ($args) = @_; |
270 |
|
443 |
|
271 |
my $import_batch_id = $args->{import_batch_id}; |
444 |
my $import_batch_id = $args->{import_batch_id}; |
272 |
my $import_record_id_selected = $args->{import_record_id_selected} || (); |
445 |
my @import_record_id_selected = $args->{import_record_id_selected} || (); |
273 |
my $matcher_id = $args->{matcher_id}; |
446 |
my $matcher_id = $args->{matcher_id}; |
274 |
my $overlay_action = $args->{overlay_action}; |
447 |
my $overlay_action = $args->{overlay_action}; |
275 |
my $import_record = $args->{import_record}; |
448 |
my $import_record = $args->{import_record}; |
Lines 277-307
sub add_biblio_from_import_record {
Link Here
|
277 |
my $duplicates_in_batch; |
450 |
my $duplicates_in_batch; |
278 |
|
451 |
|
279 |
my $duplicates_found = 0; |
452 |
my $duplicates_found = 0; |
280 |
if ( $agent eq 'client' ) { |
453 |
if($agent eq 'client') { |
281 |
return { |
454 |
return { |
282 |
record_result => 0, |
455 |
record_result => 0, |
283 |
duplicates_in_batch => 0, |
456 |
duplicates_in_batch => 0, |
284 |
skip => 1 |
457 |
skip => 1 |
285 |
} if not grep { $_ eq $import_record->import_record_id } @{$import_record_id_selected}; |
458 |
} if not grep { $_ eq $import_record->import_record_id } @import_record_id_selected; |
286 |
} |
459 |
} |
287 |
|
460 |
|
288 |
my $marcrecord = $import_record->get_marc_record || die "Couldn't translate marc information"; |
461 |
my $marcrecord = $import_record->get_marc_record || die "Couldn't translate marc information"; |
289 |
my $matches = $import_record->get_import_record_matches( { chosen => 1 } ); |
462 |
my $matches = $import_record->get_import_record_matches({ chosen => 1 }); |
290 |
my $match = $matches->count ? $matches->next : undef; |
463 |
my $match = $matches->count ? $matches->next : undef; |
291 |
my $biblionumber = $match ? $match->candidate_match_id : 0; |
464 |
my $biblionumber = $match ? $match->candidate_match_id : 0; |
292 |
|
465 |
|
293 |
if ($biblionumber) { |
466 |
if ( $biblionumber ) { |
294 |
$import_record->status('imported')->store; |
467 |
$import_record->status('imported')->store; |
295 |
if ( $overlay_action eq 'replace' ) { |
468 |
if( $overlay_action eq 'replace' ){ |
296 |
my $biblio = Koha::Biblios->find($biblionumber); |
469 |
my $biblio = Koha::Biblios->find( $biblionumber ); |
297 |
$import_record->replace( { biblio => $biblio } ); |
470 |
$import_record->replace({ biblio => $biblio }); |
298 |
} |
471 |
} |
299 |
} else { |
472 |
} else { |
300 |
if ($matcher_id) { |
473 |
if ($matcher_id) { |
301 |
if ( $matcher_id eq '_TITLE_AUTHOR_' ) { |
474 |
if ( $matcher_id eq '_TITLE_AUTHOR_' ) { |
302 |
my @matches = FindDuplicate($marcrecord); |
475 |
my @matches = FindDuplicate($marcrecord); |
303 |
$duplicates_found = 1 if @matches; |
476 |
$duplicates_found = 1 if @matches; |
304 |
} else { |
477 |
} |
|
|
478 |
else { |
305 |
my $matcher = C4::Matcher->fetch($matcher_id); |
479 |
my $matcher = C4::Matcher->fetch($matcher_id); |
306 |
my @matches = $matcher->get_matches( $marcrecord, my $max_matches = 1 ); |
480 |
my @matches = $matcher->get_matches( $marcrecord, my $max_matches = 1 ); |
307 |
$duplicates_found = 1 if @matches; |
481 |
$duplicates_found = 1 if @matches; |
Lines 314-320
sub add_biblio_from_import_record {
Link Here
|
314 |
} |
488 |
} |
315 |
|
489 |
|
316 |
# add the biblio if no matches were found |
490 |
# add the biblio if no matches were found |
317 |
if ( !$duplicates_found ) { |
491 |
if( !$duplicates_found ) { |
318 |
( $biblionumber, undef ) = AddBiblio( $marcrecord, '' ); |
492 |
( $biblionumber, undef ) = AddBiblio( $marcrecord, '' ); |
319 |
$import_record->status('imported')->store; |
493 |
$import_record->status('imported')->store; |
320 |
} |
494 |
} |
Lines 352-358
sub add_biblio_from_import_record {
Link Here
|
352 |
=cut |
526 |
=cut |
353 |
|
527 |
|
354 |
sub add_items_from_import_record { |
528 |
sub add_items_from_import_record { |
355 |
my ($args) = @_; |
529 |
my ( $args ) = @_; |
356 |
|
530 |
|
357 |
my $record_result = $args->{record_result}; |
531 |
my $record_result = $args->{record_result}; |
358 |
my $basket_id = $args->{basket_id}; |
532 |
my $basket_id = $args->{basket_id}; |
Lines 439-457
sub add_items_from_import_record {
Link Here
|
439 |
=cut |
613 |
=cut |
440 |
|
614 |
|
441 |
sub create_order_lines { |
615 |
sub create_order_lines { |
442 |
my ($args) = @_; |
616 |
my ( $args ) = @_; |
443 |
|
617 |
|
444 |
my $order_line_details = $args->{order_line_details}; |
618 |
my $order_line_details = $args->{order_line_details}; |
445 |
|
619 |
|
446 |
foreach my $order_detail ( @{$order_line_details} ) { |
620 |
foreach my $order_detail ( @{ $order_line_details } ) { |
447 |
my @itemnumbers = $order_detail->{itemnumbers} || (); |
621 |
my @itemnumbers = $order_detail->{itemnumbers}; |
448 |
delete( $order_detail->{itemnumbers} ); |
622 |
delete($order_detail->{itemnumber}); |
449 |
my $order = Koha::Acquisition::Order->new( \%{$order_detail} ); |
623 |
my $order = Koha::Acquisition::Order->new( \%{ $order_detail } ); |
450 |
$order->populate_with_prices_for_ordering(); |
624 |
$order->populate_with_prices_for_ordering(); |
451 |
$order->populate_with_prices_for_receiving(); |
625 |
$order->populate_with_prices_for_receiving(); |
452 |
$order->store; |
626 |
$order->store; |
453 |
foreach my $itemnumber (@itemnumbers) { |
627 |
foreach my $itemnumber ( @itemnumbers ) { |
454 |
$order->add_item($itemnumber); |
628 |
$order->add_item( $itemnumber ); |
455 |
} |
629 |
} |
456 |
} |
630 |
} |
457 |
return; |
631 |
return; |
Lines 983-986
sub _create_item_fields_from_syspref {
Link Here
|
983 |
return $item_fields; |
1157 |
return $item_fields; |
984 |
} |
1158 |
} |
985 |
|
1159 |
|
986 |
1; |
1160 |
1; |