From 9266c963053333ce5798f140b44d8c9f55326df0 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Thu, 3 Jul 2025 16:09:41 +0100 Subject: [PATCH] Bug 22439: Remove C4::Biblio::PrepHostMarcField and consolidate with Koha::Biblio::generate_marc_host_field This patch removes the PrepHostMarcField function from C4::Biblio and enhances the modern generate_marc_host_field method in Koha::Biblio to handle item-specific data when needed. The refactoring eliminates code duplication while maintaining all existing functionality. Item-specific subfields (barcode, itemnumber, biblionumber) are now only included when EasyAnalyticalRecords is enabled, ensuring the implementation continues to be compliant with MARC standards. Changes: - Remove PrepHostMarcField function from C4::Biblio - Enhance generate_marc_host_field to accept optional item parameter - Update cataloguing/addbiblio.pl to use the modern method - Update cataloguing/linkitem.pl to use the modern method - Add EasyAnalyticalRecords preference checking to ensure we only add the additional non-standard fields when the preference is enabled. Test plan: 1. Apply patch 2. Enable EasyAnalyticalRecords system preference 3. Create a parent bibliographic record with items 4. Create a child analytical record: - Go to Cataloging > New Record - Use "Add child record" option for the parent record - Choose a specific item from the parent record - Verify the 773 field contains subfields $0 (biblionumber), $9 (itemnumber), $o (barcode) 5. Test the linkitem.pl functionality: - Create an analytical record without using "Add child record" - Go to cataloguing/linkitem.pl with appropriate parameters - Link an item using its barcode - Verify the 773 field is properly populated 6. Disable EasyAnalyticalRecords system preference 7. Repeat steps 4-5 and verify that subfields $0, $9, and $o are NOT added to the 773 field 8. Verify that other 773 subfields (title, author, etc.) are still properly populated 9. Test with both MARC21 and UNIMARC if available 10. Run tests: prove t/db_dependent/Koha/Biblio.t --- C4/Biblio.pm | 78 ---------------------------------------- Koha/Biblio.pm | 42 ++++++++++++++++++---- cataloguing/addbiblio.pl | 11 +++--- cataloguing/linkitem.pl | 4 +-- 4 files changed, 44 insertions(+), 91 deletions(-) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 3d6a4fca60d..6113c4961fe 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -49,7 +49,6 @@ BEGIN { GetMarcSubfieldStructureFromKohaField GetFrameworkCode TransformKohaToMarc - PrepHostMarcField CountItemsIssued ModBiblio ModZebra @@ -1999,83 +1998,6 @@ sub _check_split { return; } -=head2 PrepHostMarcField - - $hostfield = PrepHostMarcField ( $hostbiblionumber,$hostitemnumber,$marcflavour ) - -This function returns a host field populated with data from the host record, the field can then be added to an analytical record - -=cut - -sub PrepHostMarcField { - my ( $hostbiblionumber, $hostitemnumber, $marcflavour ) = @_; - $marcflavour ||= "MARC21"; - - my $biblio = Koha::Biblios->find($hostbiblionumber); - my $hostrecord = $biblio->metadata->record; - my $item = Koha::Items->find($hostitemnumber); - - my $hostmarcfield; - if ( $marcflavour eq "MARC21" ) { - - #main entry - my $mainentry; - if ( $hostrecord->subfield( '100', 'a' ) ) { - $mainentry = $hostrecord->subfield( '100', 'a' ); - } elsif ( $hostrecord->subfield( '110', 'a' ) ) { - $mainentry = $hostrecord->subfield( '110', 'a' ); - } else { - $mainentry = $hostrecord->subfield( '111', 'a' ); - } - - # qualification info - my $qualinfo; - if ( my $field260 = $hostrecord->field('260') ) { - $qualinfo = $field260->as_string('abc'); - } - - #other fields - my $ed = $hostrecord->subfield( '250', 'a' ); - my $barcode = $item->barcode; - my $title = $hostrecord->subfield( '245', 'a' ); - - # record control number, 001 with 003 and prefix - my $recctrlno; - if ( $hostrecord->field('001') ) { - $recctrlno = $hostrecord->field('001')->data(); - if ( $hostrecord->field('003') ) { - $recctrlno = '(' . $hostrecord->field('003')->data() . ')' . $recctrlno; - } - } - - # issn/isbn - my $issn = $hostrecord->subfield( '022', 'a' ); - my $isbn = $hostrecord->subfield( '020', 'a' ); - - $hostmarcfield = MARC::Field->new( - 773, '0', '', - '0' => $hostbiblionumber, - '9' => $hostitemnumber, - 'a' => $mainentry, - 'b' => $ed, - 'd' => $qualinfo, - 'o' => $barcode, - 't' => $title, - 'w' => $recctrlno, - 'x' => $issn, - 'z' => $isbn - ); - } elsif ( $marcflavour eq "UNIMARC" ) { - $hostmarcfield = MARC::Field->new( - 461, '', '', - '0' => $hostbiblionumber, - 't' => $hostrecord->subfield( '200', 'a' ), - '9' => $hostitemnumber - ); - } - - return $hostmarcfield; -} =head2 TransformHtmlToXml diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index 4c88bcd8a58..c457c45dee8 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -1905,19 +1905,26 @@ sub get_marc_hostinfo_only { =head3 generate_marc_host_field my $link_field = $biblio->generate_marc_host_field; + my $link_field = $biblio->generate_marc_host_field( { item => $item } ); $child->link_marc_host( $link_field ); This method generates a MARC link field from the host record that can be added to child records to link them to the host record. -NOTE: This replicates and partially enhances C4::Biblio::prepare_marc_host(). We should merge -functionality from C4::Biblio::PrepareMarcHost() too and then replace all calls to those methods -with this one and remove those alternatives from the codebase. +When an item is passed and EasyAnalyticalRecords is enabled, item-specific data (barcode and +itemnumber) will be included in the host field. This is non-standard MARC and should only be +used when the easy analytics workflow is specifically enabled. + +NOTE: This replaces C4::Biblio::PrepHostMarcField() which has been removed to eliminate +code duplication. =cut sub generate_marc_host_field { - my ($self) = @_; + my ( $self, $params ) = @_; + $params //= {}; + + my $item = $params->{item}; my $marcflavour = C4::Context->preference('marcflavour'); my $marc_host = $self->metadata->record; @@ -2050,6 +2057,18 @@ sub generate_marc_host_field { } } + # Item-specific subfields (only when EasyAnalyticalRecords is enabled) + if ( $item && C4::Context->preference('EasyAnalyticalRecords') ) { + # Subfield 0 - host biblionumber + push @sfd, ( '0' => $self->biblionumber ); + + # Subfield 9 - host itemnumber + push @sfd, ( '9' => $item->itemnumber ); + + # Subfield o - barcode + push @sfd, ( 'o' => $item->barcode ) if $item->barcode; + } + # Construct 773 link field $link_field = MARC::Field->new( 773, '0', ' ', @sfd ); @@ -2103,9 +2122,18 @@ sub generate_marc_host_field { push @sfd, ( y => $s ) if ($s); } - # Control number (001) - if ( $host_field = $marc_host->field('001') ) { - push @sfd, ( 0 => $host_field->data() ); + # Item-specific subfields (only when EasyAnalyticalRecords is enabled) + if ( $item && C4::Context->preference('EasyAnalyticalRecords') ) { + # Subfield 0 - host biblionumber (takes precedence over control number) + push @sfd, ( 0 => $self->biblionumber ); + + # Subfield 9 - host itemnumber + push @sfd, ( 9 => $item->itemnumber ); + } else { + # Control number (001) - only when not using item-specific data + if ( $host_field = $marc_host->field('001') ) { + push @sfd, ( 0 => $host_field->data() ); + } } # Construct 461 link field diff --git a/cataloguing/addbiblio.pl b/cataloguing/addbiblio.pl index 51fbb1a31d9..506b7e2e063 100755 --- a/cataloguing/addbiblio.pl +++ b/cataloguing/addbiblio.pl @@ -33,7 +33,6 @@ use C4::Biblio qw( GetMarcStructure GetUsedMarcStructure ModBiblio - PrepHostMarcField TransformHtmlToMarc ApplyMarcOverlayRules ); @@ -49,6 +48,7 @@ use Koha::DateUtils qw( dt_from_string ); use Koha::Acquisition::Orders; use Koha::Biblios; +use Koha::Items; use Koha::ItemTypes; use Koha::Libraries; @@ -633,11 +633,14 @@ if ( $record && $op eq 'duplicate' ) { #populate hostfield if hostbiblionumber is available if ($hostbiblionumber) { - my $marcflavour = C4::Context->preference("marcflavour"); $record = MARC::Record->new(); $record->leader(''); - my $field = PrepHostMarcField( $hostbiblionumber, $hostitemnumber, $marcflavour ); - $record->append_fields($field); + my $host_biblio = Koha::Biblios->find($hostbiblionumber); + if ($host_biblio) { + my $item = $hostitemnumber ? Koha::Items->find($hostitemnumber) : undef; + my $field = $host_biblio->generate_marc_host_field({ item => $item }); + $record->append_fields($field) if $field; + } } # This is a child record diff --git a/cataloguing/linkitem.pl b/cataloguing/linkitem.pl index d7bf9497d9b..4af39826835 100755 --- a/cataloguing/linkitem.pl +++ b/cataloguing/linkitem.pl @@ -24,7 +24,7 @@ use Modern::Perl; use CGI qw ( -utf8 ); use C4::Auth qw( get_template_and_user ); use C4::Output qw( output_html_with_http_headers ); -use C4::Biblio qw( ModBiblio PrepHostMarcField ); +use C4::Biblio qw( ModBiblio ); use C4::Context; use Koha::Biblios; @@ -59,7 +59,7 @@ if ( $op eq 'cud-linkitem' && $barcode && $biblionumber ) { my $item = Koha::Items->find( { barcode => $barcode } ); if ($item) { - my $field = PrepHostMarcField( $item->biblio->biblionumber, $item->itemnumber, $marcflavour ); + my $field = $item->biblio->generate_marc_host_field({ item => $item }); $record->append_fields($field); my $modresult = ModBiblio( $record, $biblionumber, '' ); -- 2.50.0