From ce82b97a99beb667edd20e8322c6bf8fdf9e039d Mon Sep 17 00:00:00 2001 From: Janusz Kaczmarek Date: Fri, 24 Nov 2017 22:21:48 +0100 Subject: [PATCH] Bug 14769: Authorities merge: Set correct indicators in biblio field Correctly sets indicators while merging authorities--relying on values from authority record. The strategy is similar to that of Bug 5262 (copying indicators from auth rec while in editor). UNIMARC (the simple case) and MARC 21 (more complex) are covered. In particular, attention has been paid to the proper application of 008/11 while controlling 6XX in MARC 21., specially if 008/11 =~ /[rsz]/ (and if it is 'z' and 040 $f is defined). Indicators set by catalogers and/or not controlled by authority record are not modified by the patch (e.g. 2nd ind in 7XX, 1st ind in 240). To test -- have some authority recs. with different tags (eg. 100, 130, 150), use them in biblio, especially in 6XX, 7XX (setting 2nd ind). Have running indexer and proper value of AuthorityMergeLimit, i.e. not 0. Then play with indicators in authorities. For MARC 21 auth used in 6XX play also with 008/11 and 040 $f (if 008/11 set to 'z'). Have a look at the results in biblio (see subfield $2 in MARC 21 6XX if 008/11 = z and 040 $f defined). --- C4/AuthoritiesMarc.pm | 69 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/C4/AuthoritiesMarc.pm b/C4/AuthoritiesMarc.pm index 6dbe516208..514a7ad700 100644 --- a/C4/AuthoritiesMarc.pm +++ b/C4/AuthoritiesMarc.pm @@ -1451,6 +1451,11 @@ sub merge { $skip_subfields->{9} = 1 if !$overwrite; my $counteditedbiblio = 0; + my ($auth_ind1, $auth_ind2, $auth_008_11, $auth_040_f); + $auth_ind1 = $MARCto->field($auth_tag_to_report_to)->indicator('1'); + $auth_ind2 = $MARCto->field($auth_tag_to_report_to)->indicator('2'); + $auth_008_11 = substr($MARCto->field('008')->data, 11, 1) if C4::Context->preference("marcflavour") eq "MARC21" && $MARCto->field('008'); + $auth_040_f = $MARCto->subfield('040', 'f') if C4::Context->preference("marcflavour") eq "MARC21"; foreach my $biblionumber ( @biblionumbers ) { my $marcrecord = GetMarcBiblio({ biblionumber => $biblionumber }); next if !$marcrecord; @@ -1473,10 +1478,20 @@ sub merge { my $newtag = $tags_new && @$tags_new ? _merge_newtag( $tag, $tags_new ) : $tag; + my ($indicator1, $indicator2, $subfield_2) = _merge_indicators({ + biblio_tag_to => $newtag, + auth_tag => $auth_tag_to_report_to, + auth_ind1 => $auth_ind1, + auth_ind2 => $auth_ind2, + auth_008_11 => $auth_008_11, + auth_040_f => $auth_040_f + }); + $indicator1 //= $field->indicator(1); + $indicator2 //= $field->indicator(2); my $field_to = MARC::Field->new( $newtag, - $field->indicator(1), - $field->indicator(2), + $indicator1, + $indicator2, "9" => $mergeto, ); foreach my $subfield ( grep { $_->[0] ne '9' } @record_to ) { @@ -1489,6 +1504,11 @@ sub merge { $field_to->add_subfields( $subfield->[0], $subfield->[1] ); } } + if ($subfield_2) { + $field_to->update(2 => $subfield_2); # update -- if there was one, should be updated, otherwise will be added + } elsif (defined $subfield_2) { # defined but empty = MARC 21 6XX, auth 008/11 !~ /[rsz]/ -> $2 should be removed if exist + $field_to->delete_subfield(code => '2'); + } if ($tags_new && @$tags_new) { $marcrecord->delete_field($field); append_fields_ordered( $marcrecord, $field_to ); @@ -1522,6 +1542,51 @@ sub _merge_newtag { return @same_block ? $same_block[0] : $new_tags->[0]; } +sub _merge_indicators { + my $params = shift; + my ($indicator1, $indicator2, $subfield_2); + if (C4::Context->preference('marcflavour') eq 'UNIMARC') { + $indicator1 = $params->{auth_ind1}; + $indicator2 = $params->{auth_ind2}; + } elsif (C4::Context->preference('marcflavour') eq 'MARC21') { + if ($params->{biblio_tag_to} =~ /^6/) { # MARC 21 subject heading - 2nd ind. depends on 008/11 of auth. rec. + my %thes_mapping = qw / a 0 + b 1 + c 2 + d 3 + k 5 + n 4 + r 7 + s 7 + v 6 + z 7 + | 4 /; + $indicator2 = defined $thes_mapping{$params->{auth_008_11}} ? $thes_mapping{$params->{auth_008_11}} : ($params->{auth_008_11} ? $params->{auth_008_11} : '4'); + if ($indicator2 eq '7') { + if ($params->{auth_008_11} eq 'r') { + $subfield_2 = 'aat'; + } elsif ($params->{auth_008_11} eq 's') { + $subfield_2 = 'sears'; + } else { # z -- let's check 040 $f + $subfield_2 = $params->{auth_040_f}; # OK if undefined -- will do nothing to $2 in biblio, if there is + } + } else { + $subfield_2 //= ''; # ind2 != 7 --> there shouldn't be $2 in 6XX field (MARC 21) + } + } + if ($params->{auth_tag} eq '130') { # unified title -- the special case + if ($params->{biblio_tag_to} =~ /830|240/) { + $indicator2 = $params->{auth_ind2}; + } else { + $indicator1 = $params->{auth_ind2}; + } + } else { + $indicator1 = $params->{auth_ind1}; + } + } + return ($indicator1, $indicator2, $subfield_2); +} + sub append_fields_ordered { # while we lack this function in MARC::Record # we do not want insert_fields_ordered since it inserts before -- 2.11.0