View | Details | Raw Unified | Return to bug 34355
Collapse All | Expand All

(-)a/Koha/MarcOrder.pm (-234 / +366 lines)
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 34-53 use C4::ImportBatch qw( Link Here
34
    SetImportBatchNoMatchAction
35
    SetImportBatchNoMatchAction
35
    SetImportBatchItemAction
36
    SetImportBatchItemAction
36
    SetImportBatchStatus
37
    SetImportBatchStatus
37
    GetImportBatchOverlayAction
38
    GetImportBatchNoMatchAction
39
    GetImportBatchItemAction
40
    GetImportBatch
41
);
38
);
42
use C4::Search      qw( FindDuplicate );
39
use C4::Search qw( FindDuplicate );
43
use C4::Acquisition qw( NewBasket );
40
use C4::Acquisition qw( NewBasket );
44
use C4::Biblio      qw(
41
use C4::Biblio qw(
45
    AddBiblio
42
    AddBiblio
46
    GetMarcFromKohaField
43
    GetMarcFromKohaField
47
    TransformHtmlToXml
44
    TransformHtmlToXml
48
    GetMarcQuantity
49
);
45
);
50
use C4::Items   qw( AddItemFromMarc );
46
use C4::Items qw( AddItemFromMarc );
51
use C4::Budgets qw( GetBudgetByCode );
47
use C4::Budgets qw( GetBudgetByCode );
52
48
53
use Koha::Database;
49
use Koha::Database;
Lines 68-73 Koha::MarcOrder - Koha Marc Order Object class Link Here
68
64
69
=cut
65
=cut
70
66
67
=head3 create_order_lines_from_file
68
69
    my $result = Koha::MarcOrder->create_order_lines_from_file($args);
70
71
    Controller for file staging, basket creation and order line creation when using the cronjob in marc_ordering_process.pl
72
73
=cut
74
75
sub create_order_lines_from_file {
76
    my ( $self, $args ) = @_;
77
78
    my $filename = $args->{filename};
79
    my $filepath = $args->{filepath};
80
    my $profile  = $args->{profile};
81
    my $agent    = $args->{agent};
82
83
    my $success;
84
    my $error;
85
86
    my $vendor_id = $profile->vendor_id;
87
    my $budget_id = $profile->budget_id;
88
89
    my $vendor_record = Koha::Acquisition::Booksellers->find({ id => $vendor_id });
90
91
    my $basket_id = _create_basket_for_file({
92
        filename  => $filename,
93
        vendor_id => $vendor_id
94
    });
95
96
    my $format = index($filename, '.mrc') != -1 ? 'ISO2709' : 'MARCXML';
97
    my $params = {
98
        record_type                => $profile->record_type,
99
        encoding                   => $profile->encoding,
100
        format                     => $format,
101
        filepath                   => $filepath,
102
        filename                   => $filename,
103
        comments                   => undef,
104
        parse_items                => $profile->parse_items,
105
        matcher_id                 => $profile->matcher_id,
106
        overlay_action             => $profile->overlay_action,
107
        nomatch_action             => $profile->nomatch_action,
108
        item_action                => $profile->item_action,
109
    };
110
111
    try {
112
        my $import_batch_id = _stage_file($params);
113
114
        my $import_records = Koha::Import::Records->search({
115
            import_batch_id => $import_batch_id,
116
        });
117
118
        while( my $import_record = $import_records->next ){
119
            my $result = add_biblios_from_import_record({
120
                import_batch_id => $import_batch_id,
121
                import_record   => $import_record,
122
                matcher_id      => $params->{matcher_id},
123
                overlay_action  => $params->{overlay_action},
124
                agent           => $agent,
125
            });
126
            warn "Duplicates found in $result->{duplicates_in_batch}, record was skipped." if $result->{duplicates_in_batch};
127
            next if $result->{skip};
128
129
            my $order_line_details = add_items_from_import_record({
130
                record_result   => $result->{record_result},
131
                basket_id       => $basket_id,
132
                vendor          => $vendor_record,
133
                budget_id       => $budget_id,
134
                agent           => $agent,
135
            });
136
137
            my $order_lines = create_order_lines({
138
                order_line_details => $order_line_details
139
            });
140
        };
141
        SetImportBatchStatus( $import_batch_id, 'imported' )
142
            if Koha::Import::Records->search({import_batch_id => $import_batch_id, status => 'imported' })->count
143
            == Koha::Import::Records->search({import_batch_id => $import_batch_id})->count;
144
145
        $success = 1;
146
    } catch {
147
        $success = 0;
148
        $error = $_;
149
    };
150
151
    return $success ? { success => 1, error => ''} : { success => 0, error => $error };
152
}
153
71
=head3 import_record_and_create_order_lines
154
=head3 import_record_and_create_order_lines
72
155
73
    my $result = Koha::MarcOrder->import_record_and_create_order_lines($args);
156
    my $result = Koha::MarcOrder->import_record_and_create_order_lines($args);
Lines 80-86 sub import_record_and_create_order_lines { Link Here
80
    my ( $self, $args ) = @_;
163
    my ( $self, $args ) = @_;
81
164
82
    my $import_batch_id           = $args->{import_batch_id};
165
    my $import_batch_id           = $args->{import_batch_id};
83
    my $import_record_id_selected = $args->{import_record_id_selected} || ();
166
    my @import_record_id_selected = $args->{import_record_id_selected} || ();
84
    my $matcher_id                = $args->{matcher_id};
167
    my $matcher_id                = $args->{matcher_id};
85
    my $overlay_action            = $args->{overlay_action};
168
    my $overlay_action            = $args->{overlay_action};
86
    my $import_record             = $args->{import_record};
169
    my $import_record             = $args->{import_record};
Lines 90-161 sub import_record_and_create_order_lines { Link Here
90
    my $budget_id                 = $args->{budget_id};
173
    my $budget_id                 = $args->{budget_id};
91
    my $vendor                    = $args->{vendor};
174
    my $vendor                    = $args->{vendor};
92
175
93
    my $result = add_biblios_from_import_record(
176
    my $result = add_biblios_from_import_record({
94
        {
177
        import_batch_id           => $import_batch_id,
95
            import_batch_id           => $import_batch_id,
178
        import_record             => $import_record,
96
            import_record             => $import_record,
179
        matcher_id                => $matcher_id,
97
            matcher_id                => $matcher_id,
180
        overlay_action            => $overlay_action,
98
            overlay_action            => $overlay_action,
181
        agent                     => $agent,
99
            agent                     => $agent,
182
        import_record_id_selected => @import_record_id_selected,
100
            import_record_id_selected => $import_record_id_selected,
183
    });
101
        }
102
    );
103
184
104
    return {
185
    return {
105
        duplicates_in_batch => $result->{duplicates_in_batch},
186
        duplicates_in_batch => $result->{duplicates_in_batch},
106
        skip                => $result->{skip}
187
        skip                => $result->{skip}
107
    } if $result->{skip};
188
    } if $result->{skip};
108
189
109
    my $order_line_details = add_items_from_import_record(
190
    my $order_line_details = add_items_from_import_record({
110
        {
191
        record_result      => $result->{record_result},
111
            record_result      => $result->{record_result},
192
        basket_id          => $basket_id,
112
            basket_id          => $basket_id,
193
        vendor             => $vendor,
113
            vendor             => $vendor,
194
        budget_id          => $budget_id,
114
            budget_id          => $budget_id,
195
        agent              => $agent,
115
            agent              => $agent,
196
        client_item_fields => $client_item_fields
116
            client_item_fields => $client_item_fields
197
    });
117
        }
118
    );
119
198
120
    my $order_lines = create_order_lines( { order_line_details => $order_line_details } );
199
    my $order_lines = create_order_lines({
200
        order_line_details => $order_line_details
201
    });
121
202
122
    return {
203
    return {
123
        duplicates_in_batch => 0,
204
        duplicates_in_batch => 0,
124
        skip                => 0
205
        skip                => 0
125
    };
206
    }
126
}
207
}
127
208
128
=head3 _get_MarcFieldsToOrder_syspref_data
209
=head3 _create_basket_for_file
129
210
130
    my $marc_fields_to_order = _get_MarcFieldsToOrder_syspref_data('MarcFieldsToOrder', $marcrecord, $fields);
211
    my $basket_id = _create_basket_for_file({
212
        filename  => $filename,
213
        vendor_id => $vendor_id
214
    });
131
215
132
    Fetches data from a marc record based on the mappings in the syspref MarcFieldsToOrder using the fields selected in $fields (array).
216
    Creates a basket ready to receive order lines based on the imported file
133
217
134
=cut
218
=cut
135
219
136
sub _get_MarcFieldsToOrder_syspref_data {
220
sub _create_basket_for_file {
137
    my ( $syspref_name, $record, $field_list ) = @_;
221
    my ( $args ) = @_;
138
    my $syspref = C4::Context->preference($syspref_name);
222
139
    $syspref = "$syspref\n\n";
223
    my $filename = $args->{filename};
140
    my $yaml = eval { YAML::XS::Load( Encode::encode_utf8($syspref) ); };
224
    my $vendor_id = $args->{vendor_id};
141
    if ($@) {
225
142
        warn "Unable to parse $syspref syspref : $@";
226
    # aqbasketname.basketname has a max length of 50 characters so long file names will need to be truncated
143
        return ();
227
    my $basketname = length($filename) > 50 ? substr( $filename, 0, 50 ): $filename;
144
    }
228
145
    my $r;
229
    my $basketno =
146
    for my $field_name (@$field_list) {
230
        NewBasket( $vendor_id, 0, $basketname, q{},
147
        next unless exists $yaml->{$field_name};
231
        q{} . q{} );
148
        my @fields = split /\|/, $yaml->{$field_name};
232
149
        for my $field (@fields) {
233
    return $basketno;
150
            my ( $f, $sf ) = split /\$/, $field;
234
}
151
            next unless $f and $sf;
235
152
            if ( my $v = $record->subfield( $f, $sf ) ) {
236
=head3 _stage_file
153
                $r->{$field_name} = $v;
237
238
    $file->_stage_file($params)
239
240
    Stages a file directly using parameters from a marc ordering account and without using the background job
241
    This function is a mirror of Koha::BackgroundJob::StageMARCForImport->process but with the background job functionality removed
242
243
=cut
244
245
sub _stage_file {
246
    my ( $args ) = @_;
247
248
    my $record_type                = $args->{record_type};
249
    my $encoding                   = $args->{encoding};
250
    my $format                     = $args->{format};
251
    my $filepath                   = $args->{filepath};
252
    my $filename                   = $args->{filename};
253
    my $marc_modification_template = $args->{marc_modification_template};
254
    my $comments                   = $args->{comments};
255
    my $parse_items                = $args->{parse_items};
256
    my $matcher_id                 = $args->{matcher_id};
257
    my $overlay_action             = $args->{overlay_action};
258
    my $nomatch_action             = $args->{nomatch_action};
259
    my $item_action                = $args->{item_action};
260
261
    my @messages;
262
    my ( $batch_id, $num_valid, $num_items, @import_errors );
263
    my $num_with_matches = 0;
264
    my $checked_matches  = 0;
265
    my $matcher_failed   = 0;
266
    my $matcher_code     = "";
267
268
    my $schema = Koha::Database->new->schema;
269
    try {
270
        $schema->storage->txn_begin;
271
272
        my ( $errors, $marcrecords );
273
        if ( $format eq 'MARCXML' ) {
274
            ( $errors, $marcrecords ) =
275
              C4::ImportBatch::RecordsFromMARCXMLFile( $filepath, $encoding );
276
        }
277
        elsif ( $format eq 'ISO2709' ) {
278
            ( $errors, $marcrecords ) =
279
              C4::ImportBatch::RecordsFromISO2709File( $filepath, $record_type,
280
                $encoding );
281
        }
282
        else {    # plugin based
283
            $errors = [];
284
            $marcrecords =
285
              C4::ImportBatch::RecordsFromMarcPlugin( $filepath, $format,
286
                $encoding );
287
        }
288
289
        ( $batch_id, $num_valid, $num_items, @import_errors ) = BatchStageMarcRecords(
290
            $record_type,                $encoding,
291
            $marcrecords,                $filename,
292
            $marc_modification_template, $comments,
293
            '',                          $parse_items,
294
            0
295
        );
296
297
        if ($matcher_id) {
298
            my $matcher = C4::Matcher->fetch($matcher_id);
299
            if ( defined $matcher ) {
300
                $checked_matches = 1;
301
                $matcher_code    = $matcher->code();
302
                $num_with_matches =
303
                  BatchFindDuplicates( $batch_id, $matcher, 10);
304
                SetImportBatchMatcher( $batch_id, $matcher_id );
305
                SetImportBatchOverlayAction( $batch_id, $overlay_action );
306
                SetImportBatchNoMatchAction( $batch_id, $nomatch_action );
307
                SetImportBatchItemAction( $batch_id, $item_action );
308
                $schema->storage->txn_commit;
309
            }
310
            else {
311
                $matcher_failed = 1;
312
                $schema->storage->txn_rollback;
154
            }
313
            }
155
            last if $yaml->{$field};
314
        } else {
315
            $schema->storage->txn_commit;
156
        }
316
        }
317
318
        return $batch_id;
157
    }
319
    }
158
    return $r;
320
    catch {
321
        warn $_;
322
        $schema->storage->txn_rollback;
323
        die "Something terrible has happened!"
324
          if ( $_ =~ /Rollback failed/ );    # TODO Check test: Rollback failed
325
    };
159
}
326
}
160
327
161
=head3 _get_MarcItemFieldsToOrder_syspref_data
328
=head3 _get_MarcItemFieldsToOrder_syspref_data
Lines 167-177 sub _get_MarcFieldsToOrder_syspref_data { Link Here
167
=cut
334
=cut
168
335
169
sub _get_MarcItemFieldsToOrder_syspref_data {
336
sub _get_MarcItemFieldsToOrder_syspref_data {
170
    my ( $syspref_name, $record, $field_list ) = @_;
337
    my ($syspref_name, $record, $field_list) = @_;
171
    my $syspref = C4::Context->preference($syspref_name);
338
    my $syspref = C4::Context->preference($syspref_name);
172
    $syspref = "$syspref\n\n";
339
    $syspref = "$syspref\n\n";
173
    my $yaml = eval { YAML::XS::Load( Encode::encode_utf8($syspref) ); };
340
    my $yaml = eval {
174
    if ($@) {
341
        YAML::XS::Load(Encode::encode_utf8($syspref));
342
    };
343
    if ( $@ ) {
175
        warn "Unable to parse $syspref syspref : $@";
344
        warn "Unable to parse $syspref syspref : $@";
176
        return ();
345
        return ();
177
    }
346
    }
Lines 179-188 sub _get_MarcItemFieldsToOrder_syspref_data { Link Here
179
    my @tags_list;
348
    my @tags_list;
180
349
181
    # Check tags in syspref definition
350
    # Check tags in syspref definition
182
    for my $field_name (@$field_list) {
351
    for my $field_name ( @$field_list ) {
183
        next unless exists $yaml->{$field_name};
352
        next unless exists $yaml->{$field_name};
184
        my @fields = split /\|/, $yaml->{$field_name};
353
        my @fields = split /\|/, $yaml->{$field_name};
185
        for my $field (@fields) {
354
        for my $field ( @fields ) {
186
            my ( $f, $sf ) = split /\$/, $field;
355
            my ( $f, $sf ) = split /\$/, $field;
187
            next unless $f and $sf;
356
            next unless $f and $sf;
188
            push @tags_list, $f;
357
            push @tags_list, $f;
Lines 190-197 sub _get_MarcItemFieldsToOrder_syspref_data { Link Here
190
    }
359
    }
191
    @tags_list = List::MoreUtils::uniq(@tags_list);
360
    @tags_list = List::MoreUtils::uniq(@tags_list);
192
361
193
    my $tags_count = _verify_number_of_fields( \@tags_list, $record );
362
    die "System preference MarcItemFieldsToOrder has not been filled in. Please set the mapping values to use this cron script." if scalar(@tags_list == 0);
194
363
364
    my $tags_count = _verify_number_of_fields(\@tags_list, $record);
195
    # Return if the number of these fields in the record is not the same.
365
    # Return if the number of these fields in the record is not the same.
196
    die "Invalid number of fields detected on field $tags_count->{key}, please check this file" if $tags_count->{error};
366
    die "Invalid number of fields detected on field $tags_count->{key}, please check this file" if $tags_count->{error};
197
367
Lines 199-228 sub _get_MarcItemFieldsToOrder_syspref_data { Link Here
199
    my $fields_hash;
369
    my $fields_hash;
200
    foreach my $tag (@tags_list) {
370
    foreach my $tag (@tags_list) {
201
        my @tmp_fields;
371
        my @tmp_fields;
202
        foreach my $field ( $record->field($tag) ) {
372
        foreach my $field ($record->field($tag)) {
203
            push @tmp_fields, $field;
373
            push @tmp_fields, $field;
204
        }
374
        }
205
        $fields_hash->{$tag} = \@tmp_fields;
375
        $fields_hash->{$tag} = \@tmp_fields;
206
    }
376
    }
207
377
208
    if ( $tags_count->{count} ) {
378
    for (my $i = 0; $i < $tags_count->{count}; $i++) {
209
        for ( my $i = 0 ; $i < $tags_count->{count} ; $i++ ) {
379
        my $r;
210
            my $r;
380
        for my $field_name ( @$field_list ) {
211
            for my $field_name (@$field_list) {
381
            next unless exists $yaml->{$field_name};
212
                next unless exists $yaml->{$field_name};
382
            my @fields = split /\|/, $yaml->{$field_name};
213
                my @fields = split /\|/, $yaml->{$field_name};
383
            for my $field ( @fields ) {
214
                for my $field (@fields) {
384
                my ( $f, $sf ) = split /\$/, $field;
215
                    my ( $f, $sf ) = split /\$/, $field;
385
                next unless $f and $sf;
216
                    next unless $f and $sf;
386
                my $v = $fields_hash->{$f}[$i] ? $fields_hash->{$f}[$i]->subfield( $sf ) : undef;
217
                    my $v = $fields_hash->{$f}[$i] ? $fields_hash->{$f}[$i]->subfield($sf) : undef;
387
                $r->{$field_name} = $v if (defined $v);
218
                    $r->{$field_name} = $v if ( defined $v );
388
                last if $yaml->{$field};
219
                    last if $yaml->{$field};
220
                }
221
            }
389
            }
222
            push @result, $r;
223
        }
390
        }
391
        push @result, $r;
224
    }
392
    }
225
226
    return $result[0];
393
    return $result[0];
227
}
394
}
228
395
Lines 235-241 sub _get_MarcItemFieldsToOrder_syspref_data { Link Here
235
=cut
402
=cut
236
403
237
sub _verify_number_of_fields {
404
sub _verify_number_of_fields {
238
    my ( $tags_list, $record ) = @_;
405
    my ($tags_list, $record) = @_;
239
    my $tag_fields_count;
406
    my $tag_fields_count;
240
    for my $tag (@$tags_list) {
407
    for my $tag (@$tags_list) {
241
        my @fields = $record->field($tag);
408
        my @fields = $record->field($tag);
Lines 244-256 sub _verify_number_of_fields { Link Here
244
411
245
    my $tags_count;
412
    my $tags_count;
246
    foreach my $key ( keys %$tag_fields_count ) {
413
    foreach my $key ( keys %$tag_fields_count ) {
247
        if ( $tag_fields_count->{$key} > 0 ) {    # Having 0 of a field is ok
414
        if ( $tag_fields_count->{$key} > 0 ) { # Having 0 of a field is ok
248
            $tags_count //= $tag_fields_count->{$key};    # Start with the count from the first occurrence
415
            $tags_count //= $tag_fields_count->{$key}; # Start with the count from the first occurrence
249
            return { error => 1, key => $key }
416
            return { error => 1, key => $key } if $tag_fields_count->{$key} != $tags_count; # All counts of various fields should be equal if they exist
250
                if $tag_fields_count->{$key} !=
251
                $tags_count;                              # All counts of various fields should be equal if they exist
252
        }
417
        }
253
    }
418
    }
419
254
    return { error => 0, count => $tags_count };
420
    return { error => 0, count => $tags_count };
255
}
421
}
256
422
Lines 272-281 sub _verify_number_of_fields { Link Here
272
=cut
438
=cut
273
439
274
sub add_biblios_from_import_record {
440
sub add_biblios_from_import_record {
275
    my ($args) = @_;
441
    my ( $args ) = @_;
276
442
277
    my $import_batch_id           = $args->{import_batch_id};
443
    my $import_batch_id           = $args->{import_batch_id};
278
    my $import_record_id_selected = $args->{import_record_id_selected} || ();
444
    my @import_record_id_selected = $args->{import_record_id_selected} || ();
279
    my $matcher_id                = $args->{matcher_id};
445
    my $matcher_id                = $args->{matcher_id};
280
    my $overlay_action            = $args->{overlay_action};
446
    my $overlay_action            = $args->{overlay_action};
281
    my $import_record             = $args->{import_record};
447
    my $import_record             = $args->{import_record};
Lines 283-313 sub add_biblios_from_import_record { Link Here
283
    my $duplicates_in_batch;
449
    my $duplicates_in_batch;
284
450
285
    my $duplicates_found = 0;
451
    my $duplicates_found = 0;
286
    if ( $agent eq 'client' ) {
452
    if($agent eq 'client') {
287
        return {
453
        return {
288
            record_result       => 0,
454
            record_result       => 0,
289
            duplicates_in_batch => 0,
455
            duplicates_in_batch => 0,
290
            skip                => 1
456
            skip                => 1
291
        } if not grep { $_ eq $import_record->import_record_id } @{$import_record_id_selected};
457
        } if not grep { $_ eq $import_record->import_record_id } @import_record_id_selected;
292
    }
458
    }
293
459
294
    my $marcrecord   = $import_record->get_marc_record || die "Couldn't translate marc information";
460
    my $marcrecord   = $import_record->get_marc_record || die "Couldn't translate marc information";
295
    my $matches      = $import_record->get_import_record_matches( { chosen => 1 } );
461
    my $matches      = $import_record->get_import_record_matches({ chosen => 1 });
296
    my $match        = $matches->count ? $matches->next             : undef;
462
    my $match        = $matches->count ? $matches->next : undef;
297
    my $biblionumber = $match          ? $match->candidate_match_id : 0;
463
    my $biblionumber = $match ? $match->candidate_match_id : 0;
298
464
299
    if ($biblionumber) {
465
    if ( $biblionumber ) {
300
        $import_record->status('imported')->store;
466
        $import_record->status('imported')->store;
301
        if ( $overlay_action eq 'replace' ) {
467
        if( $overlay_action eq 'replace' ){
302
            my $biblio = Koha::Biblios->find($biblionumber);
468
            my $biblio = Koha::Biblios->find( $biblionumber );
303
            $import_record->replace( { biblio => $biblio } );
469
            $import_record->replace({ biblio => $biblio });
304
        }
470
        }
305
    } else {
471
    } else {
306
        if ($matcher_id) {
472
        if ($matcher_id) {
307
            if ( $matcher_id eq '_TITLE_AUTHOR_' ) {
473
            if ( $matcher_id eq '_TITLE_AUTHOR_' ) {
308
                my @matches = FindDuplicate($marcrecord);
474
                my @matches = FindDuplicate($marcrecord);
309
                $duplicates_found = 1 if @matches;
475
                $duplicates_found = 1 if @matches;
310
            } else {
476
            }
477
            else {
311
                my $matcher = C4::Matcher->fetch($matcher_id);
478
                my $matcher = C4::Matcher->fetch($matcher_id);
312
                my @matches = $matcher->get_matches( $marcrecord, my $max_matches = 1 );
479
                my @matches = $matcher->get_matches( $marcrecord, my $max_matches = 1 );
313
                $duplicates_found = 1 if @matches;
480
                $duplicates_found = 1 if @matches;
Lines 320-326 sub add_biblios_from_import_record { Link Here
320
        }
487
        }
321
488
322
        # add the biblio if no matches were found
489
        # add the biblio if no matches were found
323
        if ( !$duplicates_found ) {
490
        if( !$duplicates_found ) {
324
            ( $biblionumber, undef ) = AddBiblio( $marcrecord, '' );
491
            ( $biblionumber, undef ) = AddBiblio( $marcrecord, '' );
325
            $import_record->status('imported')->store;
492
            $import_record->status('imported')->store;
326
        }
493
        }
Lines 358-364 sub add_biblios_from_import_record { Link Here
358
=cut
525
=cut
359
526
360
sub add_items_from_import_record {
527
sub add_items_from_import_record {
361
    my ($args) = @_;
528
    my ( $args ) = @_;
362
529
363
    my $record_result      = $args->{record_result};
530
    my $record_result      = $args->{record_result};
364
    my $basket_id          = $args->{basket_id};
531
    my $basket_id          = $args->{basket_id};
Lines 371-424 sub add_items_from_import_record { Link Here
371
    my $marcrecord         = $record_result->{marcrecord};
538
    my $marcrecord         = $record_result->{marcrecord};
372
    my @order_line_details;
539
    my @order_line_details;
373
540
374
    if ( $agent eq 'cron' ) {
541
    if($agent eq 'cron') {
375
        my $marc_fields_to_order = _get_MarcFieldsToOrder_syspref_data(
542
        my $marc_item_fields_to_order = _get_MarcItemFieldsToOrder_syspref_data('MarcItemFieldsToOrder', $marcrecord, ['homebranch', 'holdingbranch', 'itype', 'nonpublic_note', 'public_note', 'loc', 'ccode', 'notforloan', 'uri', 'copyno', 'price', 'replacementprice', 'itemcallnumber', 'quantity', 'budget_code']);
376
            'MarcFieldsToOrder', $marcrecord,
543
        my $item_homebranch           = $marc_item_fields_to_order->{homebranch};
377
            [ 'price', 'quantity', 'budget_code', 'discount', 'sort1', 'sort2' ]
544
        my $item_holdingbranch        = $marc_item_fields_to_order->{holdingbranch};
378
        );
545
        my $item_itype                = $marc_item_fields_to_order->{itype};
379
        my $quantity = $marc_fields_to_order->{quantity};
546
        my $item_nonpublic_note       = $marc_item_fields_to_order->{nonpublic_note};
380
        my $budget_code =
547
        my $item_public_note          = $marc_item_fields_to_order->{public_note};
381
            $marc_fields_to_order->{budget_code} || $budget_id;    # Use fallback from ordering profile if not mapped
548
        my $item_loc                  = $marc_item_fields_to_order->{loc};
382
        my $price    = $marc_fields_to_order->{price};
549
        my $item_ccode                = $marc_item_fields_to_order->{ccode};
383
        my $discount = $marc_fields_to_order->{discount};
550
        my $item_notforloan           = $marc_item_fields_to_order->{notforloan};
384
        my $sort1    = $marc_fields_to_order->{sort1};
551
        my $item_uri                  = $marc_item_fields_to_order->{uri};
385
        my $sort2    = $marc_fields_to_order->{sort2};
552
        my $item_copyno               = $marc_item_fields_to_order->{copyno};
386
        my $mapped_budget;
553
        my $item_quantity             = $marc_item_fields_to_order->{quantity};
387
554
        my $item_budget_code          = $marc_item_fields_to_order->{budget_code};
388
        if ($budget_code) {
389
            my $biblio_budget = GetBudgetByCode($budget_code);
390
            if ($biblio_budget) {
391
                $mapped_budget = $biblio_budget->{budget_id};
392
            } else {
393
                $mapped_budget = $budget_id;
394
            }
395
        }
396
397
        my $marc_item_fields_to_order = _get_MarcItemFieldsToOrder_syspref_data(
398
            'MarcItemFieldsToOrder',
399
            $marcrecord,
400
            [
401
                'homebranch', 'holdingbranch', 'itype', 'nonpublic_note',   'public_note', 'loc', 'ccode', 'notforloan',
402
                'uri',        'copyno',        'price', 'replacementprice', 'itemcallnumber', 'quantity', 'budget_code'
403
            ]
404
        );
405
        my $item_homebranch     = $marc_item_fields_to_order->{homebranch};
406
        my $item_holdingbranch  = $marc_item_fields_to_order->{holdingbranch};
407
        my $item_itype          = $marc_item_fields_to_order->{itype};
408
        my $item_nonpublic_note = $marc_item_fields_to_order->{nonpublic_note};
409
        my $item_public_note    = $marc_item_fields_to_order->{public_note};
410
        my $item_loc            = $marc_item_fields_to_order->{loc};
411
        my $item_ccode          = $marc_item_fields_to_order->{ccode};
412
        my $item_notforloan     = $marc_item_fields_to_order->{notforloan};
413
        my $item_uri            = $marc_item_fields_to_order->{uri};
414
        my $item_copyno         = $marc_item_fields_to_order->{copyno};
415
        my $item_quantity       = $marc_item_fields_to_order->{quantity} || 0;
416
        my $item_budget_code    = $marc_item_fields_to_order->{budget_code};
417
        my $item_budget_id;
555
        my $item_budget_id;
418
419
        if ( $marc_item_fields_to_order->{budget_code} ) {
556
        if ( $marc_item_fields_to_order->{budget_code} ) {
420
            my $item_budget = GetBudgetByCode( $marc_item_fields_to_order->{budget_code} );
557
            my $item_budget = GetBudgetByCode( $marc_item_fields_to_order->{budget_code} );
421
            if ($item_budget) {
558
            if ( $item_budget ) {
422
                $item_budget_id = $item_budget->{budget_id};
559
                $item_budget_id = $item_budget->{budget_id};
423
            } else {
560
            } else {
424
                $item_budget_id = $budget_id;
561
                $item_budget_id = $budget_id;
Lines 429-475 sub add_items_from_import_record { Link Here
429
        my $item_price             = $marc_item_fields_to_order->{price};
566
        my $item_price             = $marc_item_fields_to_order->{price};
430
        my $item_replacement_price = $marc_item_fields_to_order->{replacementprice};
567
        my $item_replacement_price = $marc_item_fields_to_order->{replacementprice};
431
        my $item_callnumber        = $marc_item_fields_to_order->{itemcallnumber};
568
        my $item_callnumber        = $marc_item_fields_to_order->{itemcallnumber};
432
        my $itemcreation           = 0;
433
569
434
        for ( my $i = 0 ; $i < $item_quantity ; $i++ ) {
570
        if(!$item_quantity) {
435
            $itemcreation = 1;
571
            my $isbn = $marcrecord->subfield( '020', "a" );
436
            my $item = Koha::Item->new(
572
            warn "No quantity found for record with ISBN: $isbn. No items will be added.";
437
                {
573
        }
438
                    biblionumber        => $biblionumber,
574
439
                    homebranch          => $item_homebranch,
575
        for (my $i = 0; $i < $item_quantity; $i++) {
440
                    holdingbranch       => $item_holdingbranch,
576
            my $item = Koha::Item->new({
441
                    itype               => $item_itype,
577
                biblionumber          => $biblionumber,
442
                    itemnotes_nonpublic => $item_nonpublic_note,
578
                homebranch            => $item_homebranch,
443
                    itemnotes           => $item_public_note,
579
                holdingbranch         => $item_holdingbranch,
444
                    location            => $item_loc,
580
                itype                 => $item_itype,
445
                    ccode               => $item_ccode,
581
                itemnotes_nonpublic   => $item_nonpublic_note,
446
                    notforloan          => $item_notforloan,
582
                itemnotes             => $item_public_note,
447
                    uri                 => $item_uri,
583
                location              => $item_loc,
448
                    copynumber          => $item_copyno,
584
                ccode                 => $item_ccode,
449
                    price               => $item_price,
585
                notforloan            => $item_notforloan,
450
                    replacementprice    => $item_replacement_price,
586
                uri                   => $item_uri,
451
                    itemcallnumber      => $item_callnumber,
587
                copynumber            => $item_copyno,
452
                }
588
                price                 => $item_price,
453
            )->store;
589
                replacementprice      => $item_replacement_price,
590
                itemcallnumber        => $item_callnumber,
591
            })->store;
454
592
455
            my %order_detail_hash = (
593
            my %order_detail_hash = (
456
                biblionumber => $biblionumber,
594
                biblionumber => $biblionumber,
595
                itemnumbers  => ($item->itemnumber),
457
                basketno     => $basket_id,
596
                basketno     => $basket_id,
458
                itemnumbers  => ( $item->itemnumber ),
459
                quantity     => 1,
597
                quantity     => 1,
460
                budget_id    => $item_budget_id,
598
                budget_id    => $item_budget_id,
461
                currency     => $vendor->listprice,
599
                currency     => $vendor->listprice,
462
            );
600
            );
463
601
464
            if ($item_price) {
602
            if($item_price) {
465
                $order_detail_hash{tax_rate_on_ordering}  = $vendor->tax_rate;
603
                $order_detail_hash{tax_rate_on_ordering}  = $vendor->tax_rate;
466
                $order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
604
                $order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
467
                $order_detail_hash{discount}              = $vendor->discount;
605
                $order_detail_hash{discount}              = $vendor->discount;
468
                $order_detail_hash{rrp}                   = $item_price;
606
                $order_detail_hash{rrp}                   = $item_price;
469
                $order_detail_hash{ecost} =
607
                $order_detail_hash{ecost}                 = $vendor->discount ? $item_price * ( 1 - $vendor->discount / 100 ) : $item_price;
470
                    $vendor->discount ? $item_price * ( 1 - $vendor->discount / 100 ) : $item_price;
608
                $order_detail_hash{listprice}             = $order_detail_hash{rrp} / $active_currency->rate;
471
                $order_detail_hash{listprice} = $order_detail_hash{rrp} / $active_currency->rate;
609
                $order_detail_hash{unitprice}             = $order_detail_hash{ecost};
472
                $order_detail_hash{unitprice} = $order_detail_hash{ecost};
473
            } else {
610
            } else {
474
                $order_detail_hash{listprice} = 0;
611
                $order_detail_hash{listprice} = 0;
475
            }
612
            }
Lines 478-514 sub add_items_from_import_record { Link Here
478
615
479
            push @order_line_details, \%order_detail_hash;
616
            push @order_line_details, \%order_detail_hash;
480
        }
617
        }
481
482
        if ( !$itemcreation ) {
483
            my %order_detail_hash = (
484
                biblionumber   => $biblionumber,
485
                basketno       => $basket_id,
486
                quantity       => $quantity,
487
                budget_id      => $mapped_budget,
488
                uncertainprice => 1,
489
                sort1          => $sort1,
490
                sort2          => $sort2,
491
            );
492
493
            if ($price) {
494
                $order_detail_hash{tax_rate_on_ordering}  = $vendor->tax_rate;
495
                $order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
496
                my $order_discount = $discount ? $discount : $vendor->discount;
497
                $order_detail_hash{discount}  = $order_discount;
498
                $order_detail_hash{rrp}       = $price;
499
                $order_detail_hash{ecost}     = $order_discount ? $price * ( 1 - $order_discount / 100 ) : $price;
500
                $order_detail_hash{listprice} = $order_detail_hash{rrp} / $active_currency->rate;
501
                $order_detail_hash{unitprice} = $order_detail_hash{ecost};
502
            } else {
503
                $order_detail_hash{listprice} = 0;
504
            }
505
506
            $order_detail_hash{uncertainprice} = 0 if $order_detail_hash{listprice};
507
            push @order_line_details, \%order_detail_hash;
508
        }
509
    }
618
    }
510
619
511
    if ( $agent eq 'client' ) {
620
    if($agent eq 'client') {
512
        my $homebranches      = $client_item_fields->{homebranches};
621
        my $homebranches      = $client_item_fields->{homebranches};
513
        my $count             = scalar @$homebranches;
622
        my $count             = scalar @$homebranches;
514
        my $holdingbranches   = $client_item_fields->{holdingbranches};
623
        my $holdingbranches   = $client_item_fields->{holdingbranches};
Lines 526-532 sub add_items_from_import_record { Link Here
526
        my $itemcallnumbers   = $client_item_fields->{itemcallnumbers};
635
        my $itemcallnumbers   = $client_item_fields->{itemcallnumbers};
527
636
528
        my $itemcreation;
637
        my $itemcreation;
529
        for ( my $i = 0 ; $i < $count ; $i++ ) {
638
        for (my $i = 0; $i < $count; $i++) {
530
            $itemcreation = 1;
639
            $itemcreation = 1;
531
            my $item = Koha::Item->new(
640
            my $item = Koha::Item->new(
532
                {
641
                {
Lines 549-573 sub add_items_from_import_record { Link Here
549
658
550
            my %order_detail_hash = (
659
            my %order_detail_hash = (
551
                biblionumber => $biblionumber,
660
                biblionumber => $biblionumber,
552
                itemnumbers  => ( $item->itemnumber ),
661
                itemnumbers  => ($item->itemnumber),
553
                basketno     => $basket_id,
662
                basketno     => $basket_id,
554
                quantity     => 1,
663
                quantity     => 1,
555
                budget_id    => @$budget_codes[$i]
664
                budget_id    => @$budget_codes[$i] || $budget_id, # If no budget selected in the UI, default to the budget on the ordering account
556
                    || $budget_id,    # If no budget selected in the UI, default to the budget on the ordering account
665
                currency     => $vendor->listprice,
557
                currency => $vendor->listprice,
558
            );
666
            );
559
667
560
            if ( @$itemprices[$i] ) {
668
            if(@$itemprices[$i]) {
561
                $order_detail_hash{tax_rate_on_ordering}  = $vendor->tax_rate;
669
                $order_detail_hash{tax_rate_on_ordering}  = $vendor->tax_rate;
562
                $order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
670
                $order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
563
                my $order_discount =
671
                my $order_discount                        = $client_item_fields->{c_discount} ? $client_item_fields->{c_discount} : $vendor->discount;
564
                    $client_item_fields->{c_discount} ? $client_item_fields->{c_discount} : $vendor->discount;
672
                $order_detail_hash{discount}              = $order_discount;
565
                $order_detail_hash{discount} = $order_discount;
673
                $order_detail_hash{rrp}                   = @$itemprices[$i];
566
                $order_detail_hash{rrp}      = @$itemprices[$i];
674
                $order_detail_hash{ecost}                 = $order_discount ? @$itemprices[$i] * ( 1 - $order_discount / 100 ) : @$itemprices[$i];
567
                $order_detail_hash{ecost} =
675
                $order_detail_hash{listprice}             = $order_detail_hash{rrp} / $active_currency->rate;
568
                    $order_discount ? @$itemprices[$i] * ( 1 - $order_discount / 100 ) : @$itemprices[$i];
676
                $order_detail_hash{unitprice}             = $order_detail_hash{ecost};
569
                $order_detail_hash{listprice} = $order_detail_hash{rrp} / $active_currency->rate;
570
                $order_detail_hash{unitprice} = $order_detail_hash{ecost};
571
            } else {
677
            } else {
572
                $order_detail_hash{listprice} = 0;
678
                $order_detail_hash{listprice} = 0;
573
            }
679
            }
Lines 577-584 sub add_items_from_import_record { Link Here
577
            push @order_line_details, \%order_detail_hash;
683
            push @order_line_details, \%order_detail_hash;
578
        }
684
        }
579
685
580
        if ( !$itemcreation ) {
686
        if(!$itemcreation) {
581
            my $quantity          = GetMarcQuantity( $marcrecord, C4::Context->preference('marcflavour') ) || 1;
687
            my $quantity = GetMarcQuantity($marcrecord, C4::Context->preference('marcflavour')) || 1;
582
            my %order_detail_hash = (
688
            my %order_detail_hash = (
583
                biblionumber       => $biblionumber,
689
                biblionumber       => $biblionumber,
584
                basketno           => $basket_id,
690
                basketno           => $basket_id,
Lines 592-610 sub add_items_from_import_record { Link Here
592
                currency           => $client_item_fields->{all_currency},
698
                currency           => $client_item_fields->{all_currency},
593
                replacementprice   => $client_item_fields->{c_replacement_price},
699
                replacementprice   => $client_item_fields->{c_replacement_price},
594
            );
700
            );
595
            if ( $client_item_fields->{c_price} ) {
701
            if ($client_item_fields->{c_price}){
596
                $order_detail_hash{tax_rate_on_ordering}  = $vendor->tax_rate;
702
                $order_detail_hash{tax_rate_on_ordering}  = $vendor->tax_rate;
597
                $order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
703
                $order_detail_hash{tax_rate_on_receiving} = $vendor->tax_rate;
598
                my $order_discount =
704
                my $order_discount                        = $client_item_fields->{c_discount} ? $client_item_fields->{c_discount} : $vendor->discount;
599
                    $client_item_fields->{c_discount} ? $client_item_fields->{c_discount} : $vendor->discount;
705
                $order_detail_hash{discount}              = $order_discount;
600
                $order_detail_hash{discount} = $order_discount;
706
                $order_detail_hash{rrp}                   = $client_item_fields->{c_price};
601
                $order_detail_hash{rrp}      = $client_item_fields->{c_price};
707
                $order_detail_hash{ecost}                 = $order_discount ? $client_item_fields->{c_price} * ( 1 - $order_discount / 100 ) : $client_item_fields->{c_price};
602
                $order_detail_hash{ecost} =
708
                $order_detail_hash{listprice}             = $order_detail_hash{rrp} / $active_currency->rate;
603
                      $order_discount
709
                $order_detail_hash{unitprice}             = $order_detail_hash{ecost};
604
                    ? $client_item_fields->{c_price} * ( 1 - $order_discount / 100 )
605
                    : $client_item_fields->{c_price};
606
                $order_detail_hash{listprice} = $order_detail_hash{rrp} / $active_currency->rate;
607
                $order_detail_hash{unitprice} = $order_detail_hash{ecost};
608
            } else {
710
            } else {
609
                $order_detail_hash{listprice} = 0;
711
                $order_detail_hash{listprice} = 0;
610
            }
712
            }
Lines 612-618 sub add_items_from_import_record { Link Here
612
            $order_detail_hash{uncertainprice} = 0 if $order_detail_hash{listprice};
714
            $order_detail_hash{uncertainprice} = 0 if $order_detail_hash{listprice};
613
715
614
            # Add items if applicable parsing the item sent by the form, and create an item just for the import_record_id we are dealing with
716
            # Add items if applicable parsing the item sent by the form, and create an item just for the import_record_id we are dealing with
615
            my $basket = Koha::Acquisition::Baskets->find($basket_id);
717
            my $basket = Koha::Acquisition::Baskets->find( $basket_id );
616
            $order_detail_hash{itemnumbers} = ();
718
            $order_detail_hash{itemnumbers} = ();
617
            if ( $basket->effective_create_items eq 'ordering' && !$basket->is_standing ) {
719
            if ( $basket->effective_create_items eq 'ordering' && !$basket->is_standing ) {
618
                my @tags         = $client_item_fields->{tag};
720
                my @tags         = $client_item_fields->{tag};
Lines 621-627 sub add_items_from_import_record { Link Here
621
                my @serials      = $client_item_fields->{serial};
723
                my @serials      = $client_item_fields->{serial};
622
                my $xml          = TransformHtmlToXml( \@tags, \@subfields, \@field_values );
724
                my $xml          = TransformHtmlToXml( \@tags, \@subfields, \@field_values );
623
                my $record       = MARC::Record::new_from_xml( $xml, 'UTF-8' );
725
                my $record       = MARC::Record::new_from_xml( $xml, 'UTF-8' );
624
                for ( my $qtyloop = 1 ; $qtyloop <= $client_item_fields->{c_quantity} ; $qtyloop++ ) {
726
                for ( my $qtyloop=1; $qtyloop <= $client_item_fields->{c_quantity}; $qtyloop++ ) {
625
                    my ( $biblionumber, undef, $itemnumber ) = AddItemFromMarc( $record, $biblionumber );
727
                    my ( $biblionumber, undef, $itemnumber ) = AddItemFromMarc( $record, $biblionumber );
626
                    push @{ $order_detail_hash{itemnumbers} }, $itemnumber;
728
                    push @{ $order_detail_hash{itemnumbers} }, $itemnumber;
627
                }
729
                }
Lines 643-666 sub add_items_from_import_record { Link Here
643
=cut
745
=cut
644
746
645
sub create_order_lines {
747
sub create_order_lines {
646
    my ($args) = @_;
748
    my ( $args ) = @_;
647
749
648
    my $order_line_details = $args->{order_line_details};
750
    my $order_line_details = $args->{order_line_details};
649
751
650
    foreach my $order_detail ( @{$order_line_details} ) {
752
    foreach  my $order_detail ( @{ $order_line_details } ) {
651
        my @itemnumbers = $order_detail->{itemnumbers} || ();
753
        my @itemnumbers = $order_detail->{itemnumbers};
652
        delete( $order_detail->{itemnumbers} );
754
        delete($order_detail->{itemnumber});
653
        my $order = Koha::Acquisition::Order->new( \%{$order_detail} );
755
        my $order = Koha::Acquisition::Order->new( \%{ $order_detail } );
654
        $order->populate_with_prices_for_ordering();
756
        $order->populate_with_prices_for_ordering();
655
        $order->populate_with_prices_for_receiving();
757
        $order->populate_with_prices_for_receiving();
656
        $order->store;
758
        $order->store;
657
        foreach my $itemnumber (@itemnumbers) {
759
        foreach my $itemnumber ( @itemnumbers ) {
658
            $order->add_item($itemnumber);
760
            $order->add_item( $itemnumber );
659
        }
761
        }
660
    }
762
    }
661
    return;
763
    return;
662
}
764
}
663
765
766
767
=head3 import_batches_list
768
769
Fetches import batches matching the batch to be added to the basket and adds these to the $template
770
771
Koha::MarcOrder->import_batches_list($template);
772
773
=cut
774
664
sub import_batches_list {
775
sub import_batches_list {
665
    my ( $self, $template ) = @_;
776
    my ( $self, $template ) = @_;
666
    my $batches = GetImportBatchRangeDesc();
777
    my $batches = GetImportBatchRangeDesc();
Lines 699-704 sub import_batches_list { Link Here
699
    $template->param( num_results => $num_batches );
810
    $template->param( num_results => $num_batches );
700
}
811
}
701
812
813
=head3
814
815
For an import batch, this function reads the files and creates all the relevant data pertaining to that file
816
It then passes this to the $template variable to be shown in the UI
817
818
Koha::MarcOrder->import_biblios_list( $template, $cgiparams->{'import_batch_id'} );
819
820
=cut
821
702
sub import_biblios_list {
822
sub import_biblios_list {
703
    my ( $self, $template, $import_batch_id ) = @_;
823
    my ( $self, $template, $import_batch_id ) = @_;
704
    my $batch = GetImportBatch( $import_batch_id, 'staged' );
824
    my $batch = GetImportBatch( $import_batch_id, 'staged' );
Lines 896-901 sub import_biblios_list { Link Here
896
    _batch_info( $template, $batch );
1016
    _batch_info( $template, $batch );
897
}
1017
}
898
1018
1019
=head3
1020
1021
Creates a hash of information to be used about an import batch in the template
1022
1023
=cut
1024
899
sub _batch_info {
1025
sub _batch_info {
900
    my ( $template, $batch ) = @_;
1026
    my ( $template, $batch ) = @_;
901
    $template->param(
1027
    $template->param(
Lines 928-933 sub _batch_info { Link Here
928
    _add_matcher_list( $batch->{'matcher_id'}, $template );
1054
    _add_matcher_list( $batch->{'matcher_id'}, $template );
929
}
1055
}
930
1056
1057
=head3
1058
1059
Adds a list of available matchers based on an import batch
1060
1061
=cut
1062
931
sub _add_matcher_list {
1063
sub _add_matcher_list {
932
    my ( $current_matcher_id, $template ) = @_;
1064
    my ( $current_matcher_id, $template ) = @_;
933
    my @matchers = C4::Matcher::GetMatcherList();
1065
    my @matchers = C4::Matcher::GetMatcherList();
Lines 941-944 sub _add_matcher_list { Link Here
941
    $template->param( available_matchers => \@matchers );
1073
    $template->param( available_matchers => \@matchers );
942
}
1074
}
943
1075
944
1;
1076
1;
(-)a/misc/cronjobs/marc_ordering_process.pl (-1 / +128 lines)
Line 0 Link Here
0
- 
1
2
#!/usr/bin/perl
3
4
# This file is part of Koha.
5
#
6
# Copyright (C) 2023 PTFS Europe Ltd
7
#
8
# Koha is free software; you can redistribute it and/or modify it
9
# under the terms of the GNU General Public License as published by
10
# the Free Software Foundation; either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# Koha is distributed in the hope that it will be useful, but
14
# WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License
19
# along with Koha; if not, see <http://www.gnu.org/licenses>.
20
21
=head1 NAME
22
23
marc_ordering_process.pl - cron script to retrieve marc files and create order lines
24
25
=head1 SYNOPSIS
26
27
./marc_ordering_process.pl [-c|--confirm] [-v|--verbose]
28
29
or, in crontab:
30
# Once every day
31
0 3 * * * marc_ordering_process.pl -c
32
33
=head1 DESCRIPTION
34
35
This script searches for new marc files in an SFTP location
36
If there are new files, it stages those files, adds bilbios/items and creates order lines
37
38
=head1 OPTIONS
39
40
=over
41
42
=item B<-v|--verbose>
43
44
Print report to standard out.
45
46
=item B<-c|--confirm>
47
48
Without this parameter no changes will be made
49
50
=back
51
52
=cut
53
54
use Modern::Perl;
55
use Pod::Usage qw( pod2usage );
56
use Getopt::Long qw( GetOptions );
57
use File::Copy qw( copy move );
58
59
use Koha::Script -cron;
60
use Koha::MarcOrder;
61
use Koha::MarcOrderAccounts;
62
63
use C4::Log qw( cronlogaction );
64
65
my $command_line_options = join(" ",@ARGV);
66
67
my ( $help, $verbose, $confirm );
68
GetOptions(
69
    'h|help' => \$help,
70
    'v|verbose'    => \$verbose,
71
    'c|confirm'     => \$confirm,
72
) || pod2usage(1);
73
74
pod2usage(0) if $help;
75
76
cronlogaction({ info => $command_line_options });
77
78
$verbose = 1 unless $verbose or $confirm;
79
print "Test run only\n" unless $confirm;
80
81
print "Fetching marc ordering accounts\n" if $verbose;
82
my @accounts = Koha::MarcOrderAccounts->search(
83
    {},
84
    {
85
        join => ['vendor', 'budget']
86
    }
87
)->as_list;
88
89
if(scalar(@accounts) == 0) {
90
    print "No accounts found - you must create a Marc order account for this cronjob to run\n" if $verbose;
91
}
92
93
foreach my $acct ( @accounts ) {
94
    if($verbose) {
95
        say sprintf "Starting marc ordering process for %s", $acct->vendor->name;
96
        say sprintf "Looking for new files in %s", $acct->download_directory;
97
    }
98
99
    my $working_dir = $acct->download_directory;
100
    opendir my $dir, $working_dir or die "Can't open filepath";
101
    my @files = grep { /\.(mrc|marcxml|mrk)/i } readdir $dir;
102
    closedir $dir;
103
104
    foreach my $filename ( @files ) {
105
        say sprintf "Creating order lines from file %s", $filename if $verbose;
106
        if($confirm) {
107
            my $full_path = "$working_dir/$filename";
108
            my $args = {
109
                filename => $filename,
110
                filepath => $full_path,
111
                profile  => $acct,
112
                agent    => 'cron'
113
            };
114
            my $result = Koha::MarcOrder->create_order_lines_from_file($args);
115
            if($result->{success}) {
116
                say sprintf "Successfully processed file: %s", $filename if $verbose;
117
                unlink $full_path;
118
            } else {
119
                say sprintf "Error processing file: %s", $filename if $verbose;
120
                say sprintf "Error message: %s", $result->{error} if $verbose;
121
            };
122
        }
123
    }
124
    print "All files completed\n";
125
    print "Moving to next account\n\n";
126
}
127
print "Process complete\n";
128
cronlogaction({ action => 'End', info => "COMPLETED" });

Return to bug 34355