Bug 5608 - command-line tool to switch information in 440 and 490 tags
[koha.git] / misc / migration_tools / switch_marc21_series_info.pl
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 # Script to switch the MARC21 440$anv and 490$av information
7
8 BEGIN {
9     # find Koha's Perl modules
10     # test carefully before changing this
11     use FindBin;
12     eval { require "$FindBin::Bin/../kohalib.pl" };
13 }
14
15 use C4::Biblio;
16 use C4::Context;
17 use Getopt::Long;
18
19 my $commit;
20 my $update_frameworks;
21 my $show_help;
22 my $verbose;
23 my $result = GetOptions(
24     'c'      => \$commit,
25     'm'      => \$update_frameworks,
26     'h|help' => \$show_help,
27     'v'      => \$verbose,
28     );
29
30 if ( ! $result || $show_help ) {
31     print_usage();
32     exit 0;
33 }
34
35 my $dbh = C4::Context->dbh;
36
37 my $count_sth = $dbh->prepare( 'SELECT COUNT(biblionumber) FROM biblio CROSS JOIN biblioitems USING (biblionumber) WHERE ExtractValue(marcxml,\'//datafield[@tag="440"]/subfield[@code="a"]\') OR ExtractValue(marcxml,\'//datafield[@tag="440"]/subfield[@code="v"]\') OR ExtractValue(marcxml,\'//datafield[@tag="440"]/subfield[@code="n"]\') OR ExtractValue(marcxml,\'//datafield[@tag="490"]/subfield[@code="a"]\') OR ExtractValue(marcxml,\'//datafield[@tag="490"]/subfield[@code="v"]\')' );
38
39 my $bibs_sth = $dbh->prepare( 'SELECT biblionumber FROM biblio CROSS JOIN biblioitems USING (biblionumber) WHERE ExtractValue(marcxml,\'//datafield[@tag="440"]/subfield[@code="a"]\') OR ExtractValue(marcxml,\'//datafield[@tag="440"]/subfield[@code="v"]\') OR ExtractValue(marcxml,\'//datafield[@tag="440"]/subfield[@code="n"]\') OR ExtractValue(marcxml,\'//datafield[@tag="490"]/subfield[@code="a"]\') OR ExtractValue(marcxml,\'//datafield[@tag="490"]/subfield[@code="v"]\')' );
40
41 unless ( $commit ) {
42     print_usage();
43 }
44
45 print "Examining MARC records...\n";
46 $count_sth->execute();
47 my ( $num_records ) = $count_sth->fetchrow;
48
49 unless ( $commit ) {
50     if ( $num_records ) {
51         print "This action would change $num_records MARC records\n";
52     }
53     else {
54         print "There appears to be no series information to change\n";
55     }
56     exit 0;
57 }
58
59 print "Changing $num_records MARC records...\n";
60
61 $bibs_sth->execute();
62 while ( my ( $biblionumber ) = $bibs_sth->fetchrow ) {
63     my $framework = GetFrameworkCode( $biblionumber ) || '';
64     my ( @newfields );
65
66     #  MARC21 specific
67     my ( $series1_t, $series1_f ) = ( '440', 'a' );
68     my ( $volume1_t, $volume1_f ) = ( '440', 'v' );
69     my ( $number1_t, $number1_f ) = ( '440', 'n' );
70
71     my ( $series2_t, $series2_f ) = ( '490', 'a' );
72     my ( $volume2_t, $volume2_f ) = ( '490', 'v' );
73
74     # Get biblio marc
75     my $biblio = GetMarcBiblio( $biblionumber );
76
77     foreach my $field ( $biblio->field( $series1_t ) ) {
78         my @newsubfields;
79         my @series1 = $field->subfield( $series1_f );
80         my @volume1 = $field->subfield( $volume1_f );
81         my @number1 = $field->subfield( $number1_f );
82         my $i = 0;
83         foreach my $num ( @number1 ) {
84             $volume1[$i] .= " " if ( $volume1[$i] );
85             $volume1[$i++] .= $num if ( $num );
86         }
87
88         while ( @series1 || @volume1 ) {
89             if ( @series1 ) {
90                 push @newsubfields, ( $series2_f, shift @series1 );
91             }
92             if ( @volume1 ) {
93                 push @newsubfields, ( $volume2_f, shift @volume1 );
94             }
95         }
96
97         my $new_field = MARC::Field->new( $series2_t, '', '',
98                                           @newsubfields );
99
100         $biblio->delete_fields( $field );
101         push @newfields, $new_field;
102     }
103
104     foreach my $field ( $biblio->field( $series2_t ) ) {
105         my @newsubfields;
106         my @series2 = $field->subfield( $series2_f );
107         my @volume2 = $field->subfield( $volume2_f );
108
109         while ( @series2 || @volume2 ) {
110             if ( @series2 ) {
111                 push @newsubfields, ( $series1_f, shift @series2 );
112             }
113             if ( @volume2 ) {
114                 push @newsubfields, ( $volume1_f, shift @volume2 );
115             }
116         }
117
118         my $new_field = MARC::Field->new( $series1_t, '', '',
119                                           @newsubfields );
120
121         $biblio->delete_fields( $field );
122         push @newfields, $new_field;
123     }
124     $biblio->insert_fields_ordered( @newfields );
125
126     ModBiblioMarc( $biblio, $biblionumber, $framework );
127     if ( $verbose ) {
128         print "Changing MARC for biblio number $biblionumber.\n";
129     }
130     else {
131         print ".";
132     }
133 }
134 print "\n";
135
136 if ( $update_frameworks ) {
137     print "Updating Koha to MARC mappings for seriestitle and volume\n";
138
139     # set new mappings for koha fields
140     $dbh->do(
141 "UPDATE marc_subfield_structure SET kohafield='seriestitle'
142   WHERE tagfield='490' AND tagsubfield='a'"
143     );
144     $dbh->do(
145 "UPDATE marc_subfield_structure SET kohafield='volume'
146   WHERE tagfield='490' AND tagsubfield='v'"
147     );
148
149     # empty old koha fields
150     $dbh->do(
151 "UPDATE marc_subfield_structure SET kohafield=''
152   WHERE kohafield='seriestitle' AND tagfield='440' AND tagsubfield='a'"
153         );
154     $dbh->do(
155 "UPDATE marc_subfield_structure SET kohafield=''
156   WHERE kohafield='volume' AND tagfield='440' AND tagsubfield='v'"
157         );
158 }
159
160 sub print_usage {
161     print <<_USAGE_;
162 $0: switch MARC21 440 tag and 490 tag contents
163
164 Parameters:
165     -c            Commit the changes to the marc records
166
167     -m            Also update the Koha field to MARC framework mappings for the
168                   seriestitle and volume Koha fields.
169
170     --help or -h  show this message.
171
172 _USAGE_
173 }