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

(-)a/Koha/Exporter/Record.pm (-17 / +67 lines)
Lines 82-108 sub _get_record_for_export { Link Here
82
        }
82
        }
83
    }
83
    }
84
84
85
    if ($dont_export_fields) {
85
    _strip_unwanted_fields($record, $dont_export_fields) if $dont_export_fields;
86
        for my $f ( split / /, $dont_export_fields ) {
86
    C4::Biblio::RemoveAllNsb($record) if $clean;
87
            if ( $f =~ m/^(\d{3})(.)?$/ ) {
87
    return $record;
88
                my ( $field, $subfield ) = ( $1, $2 );
88
}
89
89
90
                # skip if this record doesn't have this field
90
sub _strip_unwanted_fields {
91
                if ( defined $record->field($field) ) {
91
    my ($record, $dont_export_fields) = @_;
92
                    if ( defined $subfield ) {
92
93
                        my @tags = $record->field($field);
93
    for my $f ( split / /, $dont_export_fields ) {
94
                        foreach my $t (@tags) {
94
        if ( $f =~ m/^(\d{3})(.)?$/ ) {
95
                            $t->delete_subfields($subfield);
95
            my ( $field, $subfield ) = ( $1, $2 );
96
                        }
96
97
                    } else {
97
            # skip if this record doesn't have this field
98
                        $record->delete_fields( $record->field($field) );
98
            if ( defined $record->field($field) ) {
99
                if ( defined $subfield ) {
100
                    my @tags = $record->field($field);
101
                    foreach my $t (@tags) {
102
                        $t->delete_subfields($subfield);
99
                    }
103
                    }
104
                } else {
105
                    $record->delete_fields( $record->field($field) );
100
                }
106
                }
101
            }
107
            }
102
        }
108
        }
103
    }
109
    }
104
    C4::Biblio::RemoveAllNsb($record) if $clean;
105
    return $record;
106
}
110
}
107
111
108
sub _get_authority_for_export {
112
sub _get_authority_for_export {
Lines 128-134 sub _get_biblio_for_export { Link Here
128
        C4::Biblio::EmbedItemsInMarcBiblio({
132
        C4::Biblio::EmbedItemsInMarcBiblio({
129
            marc_record  => $record,
133
            marc_record  => $record,
130
            biblionumber => $biblionumber,
134
            biblionumber => $biblionumber,
131
            item_numbers => $itemnumbers });
135
            item_numbers => $itemnumbers,
136
            skip_holdings => 1 });
132
        if ($only_export_items_for_branches && @$only_export_items_for_branches) {
137
        if ($only_export_items_for_branches && @$only_export_items_for_branches) {
133
            my %export_items_for_branches = map { $_ => 1 } @$only_export_items_for_branches;
138
            my %export_items_for_branches = map { $_ => 1 } @$only_export_items_for_branches;
134
            my ( $homebranchfield, $homebranchsubfield ) = GetMarcFromKohaField( 'items.homebranch', '' );    # Should be GetFrameworkCode( $biblionumber )?
139
            my ( $homebranchfield, $homebranchsubfield ) = GetMarcFromKohaField( 'items.homebranch', '' );    # Should be GetFrameworkCode( $biblionumber )?
Lines 144-149 sub _get_biblio_for_export { Link Here
144
    return $record;
149
    return $record;
145
}
150
}
146
151
152
sub _get_holdings_for_export {
153
    my ($params)           = @_;
154
    my $dont_export_fields = $params->{dont_export_fields};
155
    my $clean              = $params->{clean};
156
    my $biblionumber       = $params->{biblionumber};
157
158
    my @records;
159
    my $holdings = Koha::Holdings->search({ biblionumber => $biblionumber, deleted_on => undef });
160
    while (my $holding = $holdings->next()) {
161
        my $record = $holding->metadata()->record();
162
        _strip_unwanted_fields($record, $dont_export_fields) if $dont_export_fields;
163
        C4::Biblio::RemoveAllNsb($record) if $clean;
164
        C4::Biblio::UpsertMarcControlField($record, '004', $biblionumber);
165
        my $leader = $record->leader();
166
        if ($leader !~ /^.{6}[uvxy]/) {
167
            $leader =~ s/^(.{6})./$1u/;
168
            $record->leader($leader);
169
        }
170
        push @records, $record;
171
    }
172
    return \@records;
173
}
174
147
sub export {
175
sub export {
148
    my ($params) = @_;
176
    my ($params) = @_;
149
177
Lines 155-160 sub export { Link Here
155
    my $dont_export_fields = $params->{dont_export_fields};
183
    my $dont_export_fields = $params->{dont_export_fields};
156
    my $csv_profile_id     = $params->{csv_profile_id};
184
    my $csv_profile_id     = $params->{csv_profile_id};
157
    my $output_filepath    = $params->{output_filepath};
185
    my $output_filepath    = $params->{output_filepath};
186
    my $export_holdings    = $params->{export_holdings} // 0;
158
187
159
    if( !$record_type ) {
188
    if( !$record_type ) {
160
        Koha::Logger->get->warn( "No record_type given." );
189
        Koha::Logger->get->warn( "No record_type given." );
Lines 184-189 sub export { Link Here
184
                next;
213
                next;
185
            }
214
            }
186
            print $record->as_usmarc();
215
            print $record->as_usmarc();
216
            if ($export_holdings && $record_type eq 'bibs') {
217
                my $holdings = _get_holdings_for_export( { %$params, biblionumber => $record_id } );
218
                foreach my $holding (@$holdings) {
219
                    my $errorcount_on_decode = eval { scalar( MARC::File::USMARC->decode( $holding->as_usmarc )->warnings() ) };
220
                    if ( $errorcount_on_decode or $@ ) {
221
                        my $msg = "Holdings record for biblio $record_id could not be exported. " .
222
                            ( $@ // '' );
223
                        chomp $msg;
224
                        Koha::Logger->get->info( $msg );
225
                        next;
226
                    }
227
                    print $holding->as_usmarc();
228
                }
229
            }
187
        }
230
        }
188
    } elsif ( $format eq 'xml' ) {
231
    } elsif ( $format eq 'xml' ) {
189
        my $marcflavour = C4::Context->preference("marcflavour");
232
        my $marcflavour = C4::Context->preference("marcflavour");
Lines 196-201 sub export { Link Here
196
            next unless $record;
239
            next unless $record;
197
            print MARC::File::XML::record($record);
240
            print MARC::File::XML::record($record);
198
            print "\n";
241
            print "\n";
242
            if ($export_holdings && $record_type eq 'bibs') {
243
                my $holdings = _get_holdings_for_export( { %$params, biblionumber => $record_id } );
244
                foreach my $holding (@$holdings) {
245
                    print MARC::File::XML::record($holding);
246
                    print "\n";
247
                }
248
            }
199
        }
249
        }
200
        print MARC::File::XML::footer();
250
        print MARC::File::XML::footer();
201
        print "\n";
251
        print "\n";
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt (-1 / +8 lines)
Lines 117-123 Link Here
117
    </fieldset>
117
    </fieldset>
118
    <fieldset class="rows">
118
    <fieldset class="rows">
119
    <legend> Options</legend>
119
    <legend> Options</legend>
120
<ol>        <li>
120
<ol>
121
        [% IF ( show_summary_holdings ) %]
122
        <li>
123
        <label for="export_holdings">Export holdings records (MARC 21 biblios only):</label>
124
        <input id="export_holdings" type="checkbox" name="export_holdings" />
125
        </li>
126
        [% END %]
127
        <li>
121
        <label for="dont_export_item">Don't export items:</label>
128
        <label for="dont_export_item">Don't export items:</label>
122
        <input id="dont_export_item" type="checkbox" name="dont_export_item" />
129
        <input id="dont_export_item" type="checkbox" name="dont_export_item" />
123
        </li>
130
        </li>
(-)a/misc/export_records.pl (-1 / +14 lines)
Lines 53-58 my ( Link Here
53
    $start_accession,
53
    $start_accession,
54
    $end_accession,
54
    $end_accession,
55
    $marc_conditions,
55
    $marc_conditions,
56
    $export_holdings,
56
    $help
57
    $help
57
);
58
);
58
59
Lines 77-82 GetOptions( Link Here
77
    'start_accession=s'       => \$start_accession,
78
    'start_accession=s'       => \$start_accession,
78
    'end_accession=s'         => \$end_accession,
79
    'end_accession=s'         => \$end_accession,
79
    'marc_conditions=s'       => \$marc_conditions,
80
    'marc_conditions=s'       => \$marc_conditions,
81
    'holdings'                => \$export_holdings,
80
    'h|help|?'                => \$help
82
    'h|help|?'                => \$help
81
) || pod2usage(1);
83
) || pod2usage(1);
82
84
Lines 111-116 if ( $deleted_barcodes and $record_type ne 'bibs' ) { Link Here
111
    pod2usage(q|--deleted_barcodes can only be used with biblios|);
113
    pod2usage(q|--deleted_barcodes can only be used with biblios|);
112
}
114
}
113
115
116
my $marcFlavour = C4::Context->preference('marcflavour') || 'MARC21';
117
if ( $export_holdings and ( $record_type ne 'bibs' or $marcFlavour ne 'MARC21' ) ) {
118
    pod2usage(q|--holdings can only be used with MARC 21 biblios|);
119
}
120
114
$start_accession = dt_from_string( $start_accession ) if $start_accession;
121
$start_accession = dt_from_string( $start_accession ) if $start_accession;
115
$end_accession   = dt_from_string( $end_accession )   if $end_accession;
122
$end_accession   = dt_from_string( $end_accession )   if $end_accession;
116
123
Lines 243-248 else { Link Here
243
            format             => $output_format,
250
            format             => $output_format,
244
            csv_profile_id     => $csv_profile_id,
251
            csv_profile_id     => $csv_profile_id,
245
            export_items       => (not $dont_export_items),
252
            export_items       => (not $dont_export_items),
253
            export_holdings    => $export_holdings,
246
            clean              => $clean || 0,
254
            clean              => $clean || 0,
247
        }
255
        }
248
    );
256
    );
Lines 256-262 export records - This script exports record (biblios or authorities) Link Here
256
264
257
=head1 SYNOPSIS
265
=head1 SYNOPSIS
258
266
259
export_records.pl [-h|--help] [--format=format] [--date=datetime] [--record-type=TYPE] [--dont_export_items] [--deleted_barcodes] [--clean] [--id_list_file=PATH] --filename=outputfile
267
export_records.pl [-h|--help] [--format=format] [--date=datetime] [--record-type=TYPE] [--holdings] [--dont_export_items] [--deleted_barcodes] [--clean] [--id_list_file=PATH] --filename=outputfile
260
268
261
=head1 OPTIONS
269
=head1 OPTIONS
262
270
Lines 281-286 Print a brief help message. Link Here
281
289
282
 --record-type=TYPE     TYPE is 'bibs' or 'auths'.
290
 --record-type=TYPE     TYPE is 'bibs' or 'auths'.
283
291
292
=item B<--holdings>
293
294
 --holdings             Export MARC 21 holding records interleaved with bibs. Used only if TYPE
295
                        is 'bibs' and FORMAT is 'xml' or 'marc'.
296
284
=item B<--dont_export_items>
297
=item B<--dont_export_items>
285
298
286
 --dont_export_items    If enabled, the item infos won't be exported.
299
 --dont_export_items    If enabled, the item infos won't be exported.
(-)a/misc/migration_tools/bulkmarcimport.pl (-9 / +55 lines)
Lines 33-38 use IO::File; Link Here
33
use Pod::Usage;
33
use Pod::Usage;
34
34
35
use Koha::Biblios;
35
use Koha::Biblios;
36
use Koha::Holdings;
36
use Koha::SearchEngine;
37
use Koha::SearchEngine;
37
use Koha::SearchEngine::Search;
38
use Koha::SearchEngine::Search;
38
39
Lines 40-46 use open qw( :std :encoding(UTF-8) ); Link Here
40
binmode( STDOUT, ":encoding(UTF-8)" );
41
binmode( STDOUT, ":encoding(UTF-8)" );
41
my ( $input_marc_file, $number, $offset) = ('',0,0);
42
my ( $input_marc_file, $number, $offset) = ('',0,0);
42
my ($version, $delete, $test_parameter, $skip_marc8_conversion, $char_encoding, $verbose, $commit, $fk_off,$format,$biblios,$authorities,$keepids,$match, $isbn_check, $logfile);
43
my ($version, $delete, $test_parameter, $skip_marc8_conversion, $char_encoding, $verbose, $commit, $fk_off,$format,$biblios,$authorities,$keepids,$match, $isbn_check, $logfile);
43
my ( $insert, $filters, $update, $all, $yamlfile, $authtypes, $append );
44
my ( $insert, $filters, $update, $all, $yamlfile, $authtypes, $append, $import_holdings );
44
my $cleanisbn = 1;
45
my $cleanisbn = 1;
45
my ($sourcetag,$sourcesubfield,$idmapfl, $dedup_barcode);
46
my ($sourcetag,$sourcesubfield,$idmapfl, $dedup_barcode);
46
my $framework = '';
47
my $framework = '';
Lines 84-96 GetOptions( Link Here
84
    'framework=s' => \$framework,
85
    'framework=s' => \$framework,
85
    'custom:s'    => \$localcust,
86
    'custom:s'    => \$localcust,
86
    'marcmodtemplate:s' => \$marc_mod_template,
87
    'marcmodtemplate:s' => \$marc_mod_template,
88
    'holdings' => \$import_holdings,
87
);
89
);
88
$biblios ||= !$authorities;
90
$biblios ||= !$authorities;
89
$insert  ||= !$update;
91
$insert  ||= !$update;
90
my $writemode = ($append) ? "a" : "w";
92
my $writemode = ($append) ? "a" : "w";
93
my $marcFlavour = C4::Context->preference('marcflavour') || 'MARC21';
91
94
92
pod2usage( -msg => "\nYou must specify either --biblios or --authorities, not both.\n", -exitval ) if $biblios && $authorities;
95
pod2usage( -msg => "\nYou must specify either --biblios or --authorities, not both.\n", -exitval ) if $biblios && $authorities;
93
96
97
pod2usage( -msg => "\nHoldings only supported for MARC 21 biblios.\n", -exitval ) if $import_holdings && (!$biblios || $marcFlavour ne 'MARC21');
98
94
if ($all) {
99
if ($all) {
95
    $insert = 1;
100
    $insert = 1;
96
    $update = 1;
101
    $update = 1;
Lines 174-185 if ($fk_off) { Link Here
174
179
175
180
176
if ($delete) {
181
if ($delete) {
177
	if ($biblios){
182
    if ($biblios) {
178
    	print "deleting biblios\n";
183
        print "deleting biblios\n";
179
        $dbh->do("DELETE FROM biblio");
184
        $dbh->do("DELETE FROM biblio");
180
        $dbh->do("ALTER TABLE biblio AUTO_INCREMENT = 1");
185
        $dbh->do("ALTER TABLE biblio AUTO_INCREMENT = 1");
181
        $dbh->do("DELETE FROM biblioitems");
186
        $dbh->do("DELETE FROM biblioitems");
182
        $dbh->do("ALTER TABLE biblioitems AUTO_INCREMENT = 1");
187
        $dbh->do("ALTER TABLE biblioitems AUTO_INCREMENT = 1");
188
        $dbh->do("DELETE FROM holdings");
189
        $dbh->do("ALTER TABLE holdings AUTO_INCREMENT = 1");
183
        $dbh->do("DELETE FROM items");
190
        $dbh->do("DELETE FROM items");
184
        $dbh->do("ALTER TABLE items AUTO_INCREMENT = 1");
191
        $dbh->do("ALTER TABLE items AUTO_INCREMENT = 1");
185
	}
192
	}
Lines 196-203 if ($test_parameter) { Link Here
196
    print "TESTING MODE ONLY\n    DOING NOTHING\n===============\n";
203
    print "TESTING MODE ONLY\n    DOING NOTHING\n===============\n";
197
}
204
}
198
205
199
my $marcFlavour = C4::Context->preference('marcflavour') || 'MARC21';
200
201
print "Characteristic MARC flavour: $marcFlavour\n" if $verbose;
206
print "Characteristic MARC flavour: $marcFlavour\n" if $verbose;
202
my $starttime = gettimeofday;
207
my $starttime = gettimeofday;
203
my $batch;
208
my $batch;
Lines 224-229 if (defined $format && $format =~ /XML/i) { Link Here
224
$batch->warnings_off();
229
$batch->warnings_off();
225
$batch->strict_off();
230
$batch->strict_off();
226
my $i=0;
231
my $i=0;
232
my $holdings_count = 0;
227
my $commitnum = $commit ? $commit : 50;
233
my $commitnum = $commit ? $commit : 50;
228
my $yamlhash;
234
my $yamlhash;
229
235
Lines 263-268 my $searcher = Koha::SearchEngine::Search->new( Link Here
263
    }
269
    }
264
);
270
);
265
271
272
my $biblionumber;
266
RECORD: while (  ) {
273
RECORD: while (  ) {
267
    my $record;
274
    my $record;
268
    # get records
275
    # get records
Lines 311-321 RECORD: while ( ) { Link Here
311
            $field->update('a' => $isbn);
318
            $field->update('a' => $isbn);
312
        }
319
        }
313
    }
320
    }
321
322
    # check for holdings records
323
    my $holdings_record = 0;
324
    if ($biblios && $marcFlavour eq 'MARC21') {
325
        my $leader = $record->leader();
326
        $holdings_record = $leader =~ /^.{6}[uvxy]/;
327
    }
328
314
    my $id;
329
    my $id;
315
    # search for duplicates (based on Local-number)
330
    # search for duplicates (based on Local-number)
316
    my $originalid;
331
    my $originalid;
317
    $originalid = GetRecordId( $record, $tagid, $subfieldid );
332
    $originalid = GetRecordId( $record, $tagid, $subfieldid );
318
    if ($match) {
333
    if ($match && !$holdings_record) {
319
        require C4::Search;
334
        require C4::Search;
320
        my $query = build_query( $match, $record );
335
        my $query = build_query( $match, $record );
321
        my $server = ( $authorities ? 'authorityserver' : 'biblioserver' );
336
        my $server = ( $authorities ? 'authorityserver' : 'biblioserver' );
Lines 431-438 RECORD: while ( ) { Link Here
431
            $yamlhash->{$originalid}->{'subfields'} = \@subfields;
446
            $yamlhash->{$originalid}->{'subfields'} = \@subfields;
432
            }
447
            }
433
        }
448
        }
449
        elsif ($holdings_record) {
450
            if ($import_holdings) {
451
                if (!defined $biblionumber) {
452
                    warn "ERROR: Encountered holdings record without preceding biblio record\n";
453
                } else {
454
                    if ($insert) {
455
                        my $holding = Koha::Holding->new({ biblionumber => $biblionumber });
456
                        $holding->set_marc({ record => $record });
457
                        my $branchcode = $holding->holdingbranch();
458
                        if (defined $branchcode && !Koha::Libraries->find({ branchcode => $branchcode})) {
459
                            printlog( { id => 0, op => 'insert', status => "warning : library $branchcode not defined, holdings record skipped" } ) if ($logfile);
460
                        } else {
461
                            $holding->store();
462
                            ++$holdings_count;
463
                            printlog( { id => $holding->holding_id(), op => 'insert', status => 'ok' } ) if ($logfile);
464
                        }
465
                    } else {
466
                        printlog( { id => 0, op => 'update', status => 'warning : not in database' } ) if ($logfile);
467
                    }
468
                }
469
            }
470
        }
434
        else {
471
        else {
435
            my ( $biblionumber, $biblioitemnumber, $itemnumbers_ref, $errors_ref );
472
            my ( $biblioitemnumber, $itemnumbers_ref, $errors_ref );
436
            $biblionumber = $id;
473
            $biblionumber = $id;
437
            # check for duplicate, based on ISBN (skip it if we already have found a duplicate with match parameter
474
            # check for duplicate, based on ISBN (skip it if we already have found a duplicate with match parameter
438
            if (!$biblionumber && $isbn_check && $isbn) {
475
            if (!$biblionumber && $isbn_check && $isbn) {
Lines 569-575 C4::Context->set_preference( 'CataloguingLog', $CataloguingLog ); Link Here
569
C4::Context->set_preference( 'AuthoritiesLog', $AuthoritiesLog );
606
C4::Context->set_preference( 'AuthoritiesLog', $AuthoritiesLog );
570
607
571
my $timeneeded = gettimeofday - $starttime;
608
my $timeneeded = gettimeofday - $starttime;
572
print "\n$i MARC records done in $timeneeded seconds\n";
609
if ($import_holdings) {
610
    printf("\n%i MARC bibliographic records and %i holdings records done in %0.3f seconds\n", $i, $holdings_count, $timeneeded);
611
} else {
612
    printf("\n%i MARC records done in %0.3f seconds\n", $i, $timeneeded);
613
}
573
if ($logfile){
614
if ($logfile){
574
  print $loghandle "file : $input_marc_file\n";
615
  print $loghandle "file : $input_marc_file\n";
575
  print $loghandle "$i MARC records done in $timeneeded seconds\n";
616
  print $loghandle "$i MARC records done in $timeneeded seconds\n";
Lines 704-709 Type of import: authority records Link Here
704
745
705
The I<FILE> to import
746
The I<FILE> to import
706
747
748
=item B<-holdings>
749
750
Import MARC 21 holdings records when interleaved with bibliographic records
751
(insert only, update not supported). Used only with -biblios.
752
707
=item  B<-v>
753
=item  B<-v>
708
754
709
Verbose mode. 1 means "some infos", 2 means "MARC dumping"
755
Verbose mode. 1 means "some infos", 2 means "MARC dumping"
Lines 749-755 I<UNIMARC> are supported. MARC21 by default. Link Here
749
=item B<-d>
795
=item B<-d>
750
796
751
Delete EVERYTHING related to biblio in koha-DB before import. Tables: biblio,
797
Delete EVERYTHING related to biblio in koha-DB before import. Tables: biblio,
752
biblioitems, items
798
biblioitems, items, holdings
753
799
754
=item B<-m>=I<FORMAT>
800
=item B<-m>=I<FORMAT>
755
801
(-)a/t/db_dependent/Exporter/Record.t (-1 / +115 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 6;
20
use Test::More tests => 8;
21
use Test::Warn;
21
use Test::Warn;
22
use t::lib::TestBuilder;
22
use t::lib::TestBuilder;
23
23
Lines 34-40 use Koha::Database; Link Here
34
use Koha::Biblio;
34
use Koha::Biblio;
35
use Koha::Biblioitem;
35
use Koha::Biblioitem;
36
use Koha::Exporter::Record;
36
use Koha::Exporter::Record;
37
use Koha::Biblio::Metadata;
37
use Koha::Biblio::Metadatas;
38
use Koha::Biblio::Metadatas;
39
use Koha::BiblioFramework;
40
use Koha::BiblioFrameworks;
41
use Koha::Holdings;
38
42
39
my $schema  = Koha::Database->new->schema;
43
my $schema  = Koha::Database->new->schema;
40
$schema->storage->txn_begin;
44
$schema->storage->txn_begin;
Lines 62-68 my $bad_biblio = Koha::Biblio->new()->store(); Link Here
62
Koha::Biblio::Metadata->new( { biblionumber => $bad_biblio->id, format => 'marcxml', metadata => 'something wrong', schema => C4::Context->preference('marcflavour') } )->store();
66
Koha::Biblio::Metadata->new( { biblionumber => $bad_biblio->id, format => 'marcxml', metadata => 'something wrong', schema => C4::Context->preference('marcflavour') } )->store();
63
my $bad_biblionumber = $bad_biblio->id;
67
my $bad_biblionumber = $bad_biblio->id;
64
68
69
# Add a framework for holdings
70
my $frameworkcode = 'HLD';
71
my $existing_mss = Koha::MarcSubfieldStructures->search({frameworkcode => $frameworkcode});
72
$existing_mss->delete() if $existing_mss;
73
my $existing_fw = Koha::BiblioFrameworks->find({frameworkcode => $frameworkcode});
74
$existing_fw->delete() if $existing_fw;
75
Koha::BiblioFramework->new({
76
    frameworkcode => $frameworkcode,
77
    frameworktext => 'Holdings'
78
})->store();
79
Koha::MarcSubfieldStructure->new({
80
    frameworkcode => $frameworkcode,
81
    tagfield => 852,
82
    tagsubfield => 'b',
83
    kohafield => 'holdings.holdingbranch'
84
})->store();
85
Koha::MarcSubfieldStructure->new({
86
    frameworkcode => $frameworkcode,
87
    tagfield => 852,
88
    tagsubfield => 'c',
89
    kohafield => 'holdings.location'
90
})->store();
91
Koha::MarcSubfieldStructure->new({
92
    frameworkcode => $frameworkcode,
93
    tagfield => 942,
94
    tagsubfield => 'n',
95
    kohafield => 'holdings.suppress'
96
})->store();
97
Koha::MarcSubfieldStructure->new({
98
    frameworkcode => $frameworkcode,
99
    tagfield => 999,
100
    tagsubfield => 'c',
101
    kohafield => 'biblio.biblionumber'
102
})->store();
103
Koha::MarcSubfieldStructure->new({
104
    frameworkcode => $frameworkcode,
105
    tagfield => 999,
106
    tagsubfield => 'e',
107
    kohafield => 'holdings.holding_id'
108
})->store();
109
65
my $builder = t::lib::TestBuilder->new;
110
my $builder = t::lib::TestBuilder->new;
111
my $holdingbranch = $builder->build({ source => 'Branch' });
112
113
my $holding_marc_1 = MARC::Record->new();
114
$holding_marc_1->leader('00202cx  a22000973  4500');
115
$holding_marc_1->append_fields(
116
    MARC::Field->new('852', '8', ' ', b => $holdingbranch->{branchcode}, c => 'Location', k => '1973', h => 'Tb', t => 'Copy 1')
117
);
118
my $holding = Koha::Holding->new();
119
$holding->biblionumber($biblionumber_1);
120
$holding->set_marc({ record => $holding_marc_1 });
121
$holding->store();
122
66
my $item_1_1 = $builder->build({
123
my $item_1_1 = $builder->build({
67
    source => 'Item',
124
    source => 'Item',
68
    value => {
125
    value => {
Lines 199-204 subtest 'export iso2709' => sub { Link Here
199
    is( $title, $biblio_2_title, 'Export ISO2709: The title is correctly encoded' );
256
    is( $title, $biblio_2_title, 'Export ISO2709: The title is correctly encoded' );
200
};
257
};
201
258
259
subtest 'export xml with holdings' => sub {
260
    plan tests => 3;
261
    my $generated_xml_file = '/tmp/test_export.xml';
262
    Koha::Exporter::Record::export(
263
        {   record_type     => 'bibs',
264
            record_ids      => [ $biblionumber_1, $biblionumber_2 ],
265
            format          => 'xml',
266
            output_filepath => $generated_xml_file,
267
            export_holdings => 1,
268
        }
269
    );
270
271
    my $generated_xml_content = read_file( $generated_xml_file );
272
    $MARC::File::XML::_load_args{BinaryEncoding} = 'utf-8';
273
    open my $fh, '<', $generated_xml_file;
274
    my $records = MARC::Batch->new( 'XML', $fh );
275
    my @records;
276
    # The following statement produces
277
    # Use of uninitialized value in concatenation (.) or string at /usr/share/perl5/MARC/File/XML.pm line 398, <$fh> chunk 5.
278
    # Why?
279
    while ( my $record = $records->next ) {
280
        push @records, $record;
281
    }
282
    is( scalar( @records ), 3, 'Export XML with holdings: 3 records should have been exported' );
283
    my $holding_record = $records[1];
284
    my $branch = $holding_record->subfield('852', 'b');
285
    is( $branch, $holdingbranch->{branchcode}, 'Export XML with holdings: The holding record contains correct branch code' );
286
    my $location = $holding_record->subfield('852', 'c');
287
    is( $location, 'Location', 'Export XML with holdings: The holding record contains correct location' );
288
};
289
290
subtest 'export iso2709 with holdings' => sub {
291
    plan tests => 3;
292
    my $generated_mrc_file = '/tmp/test_export.mrc';
293
    # Get all item infos
294
    Koha::Exporter::Record::export(
295
        {   record_type     => 'bibs',
296
            record_ids      => [ $biblionumber_1, $biblionumber_2 ],
297
            format          => 'iso2709',
298
            output_filepath => $generated_mrc_file,
299
            export_holdings => 1,
300
        }
301
    );
302
303
    my $records = MARC::File::USMARC->in( $generated_mrc_file );
304
    my @records;
305
    while ( my $record = $records->next ) {
306
        push @records, $record;
307
    }
308
    is( scalar( @records ), 3, 'Export ISO2709 with holdings: 3 records should have been exported' );
309
    my $holding_record = $records[1];
310
    my $branch = $holding_record->subfield('852', 'b');
311
    is( $branch, $holdingbranch->{branchcode}, 'Export ISO2709 with holdings: The holding record contains correct branch code' );
312
    my $location = $holding_record->subfield('852', 'c');
313
    is( $location, 'Location', 'Export ISO2709 with holdings: The holding record contains correct location' );
314
};
315
202
subtest 'export without record_type' => sub {
316
subtest 'export without record_type' => sub {
203
    plan tests => 1;
317
    plan tests => 1;
204
318
(-)a/tools/export.pl (-1 / +3 lines)
Lines 35-40 use Koha::Libraries; Link Here
35
my $query = new CGI;
35
my $query = new CGI;
36
36
37
my $dont_export_items = $query->param("dont_export_item") || 0;
37
my $dont_export_items = $query->param("dont_export_item") || 0;
38
my $export_holdings   = $query->param("export_holdings") || 0;
38
my $record_type       = $query->param("record_type");
39
my $record_type       = $query->param("record_type");
39
my $op                = $query->param("op") || '';
40
my $op                = $query->param("op") || '';
40
my $output_format     = $query->param("format") || $query->param("output_format") || 'iso2709';
41
my $output_format     = $query->param("format") || $query->param("output_format") || 'iso2709';
Lines 208-213 if ( $op eq "export" ) { Link Here
208
                dont_export_fields => $export_remove_fields,
209
                dont_export_fields => $export_remove_fields,
209
                csv_profile_id     => $csv_profile_id,
210
                csv_profile_id     => $csv_profile_id,
210
                export_items       => (not $dont_export_items),
211
                export_items       => (not $dont_export_items),
212
                export_holdings    => $export_holdings,
211
                only_export_items_for_branches => $only_export_items_for_branches,
213
                only_export_items_for_branches => $only_export_items_for_branches,
212
            }
214
            }
213
        );
215
        );
Lines 302-307 else { Link Here
302
        export_remove_fields     => C4::Context->preference("ExportRemoveFields"),
304
        export_remove_fields     => C4::Context->preference("ExportRemoveFields"),
303
        csv_profiles             => [ Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' }) ],
305
        csv_profiles             => [ Koha::CsvProfiles->search({ type => 'marc', used_for => 'export_records' }) ],
304
        messages                 => \@messages,
306
        messages                 => \@messages,
307
        show_summary_holdings    => C4::Context->preference('SummaryHoldings') ? 1 : 0,
305
    );
308
    );
306
309
307
    output_html_with_http_headers $query, $cookie, $template->output;
310
    output_html_with_http_headers $query, $cookie, $template->output;
308
- 

Return to bug 20447