@@ -, +, @@ --- C4/AuthoritiesMarc.pm | 1 - C4/Biblio.pm | 115 +++++++++++++++++++----------------- C4/Context.pm | 40 ------------- admin/biblio_framework.pl | 2 + admin/marc_subfields_structure.pl | 2 + admin/marctagstructure.pl | 3 + t/db_dependent/Biblio.t | 121 ++++++++++++++++++-------------------- t/db_dependent/Items.t | 37 ++++++------ 8 files changed, 144 insertions(+), 177 deletions(-) --- a/C4/AuthoritiesMarc.pm +++ a/C4/AuthoritiesMarc.pm @@ -88,7 +88,6 @@ sub GetAuthMARCFromKohaField { my $dbh=C4::Context->dbh; return 0, 0 unless $kohafield; $authtypecode="" unless $authtypecode; - my $marcfromkohafield; my $sth = $dbh->prepare("select tagfield,tagsubfield from auth_subfield_structure where kohafield= ? and authtypecode=? "); $sth->execute($kohafield,$authtypecode); my ($tagfield,$tagsubfield) = $sth->fetchrow; --- a/C4/Biblio.pm +++ a/C4/Biblio.pm @@ -1209,18 +1209,44 @@ C<$frameworkcode> is the framework code. sub GetUsedMarcStructure { my $frameworkcode = shift || ''; - my $query = qq/ + my $query = q{ SELECT * FROM marc_subfield_structure WHERE tab > -1 AND frameworkcode = ? ORDER BY tagfield, tagsubfield - /; + }; my $sth = C4::Context->dbh->prepare($query); $sth->execute($frameworkcode); return $sth->fetchall_arrayref( {} ); } +=head2 GetMarcSubfieldStructure + +=cut + +sub GetMarcSubfieldStructure { + my ( $frameworkcode ) = @_; + + $frameworkcode //= ''; + + my $cache = Koha::Cache->get_instance(); + my $cache_key = "MarcSubfieldStructure-$frameworkcode"; + my $cached = $cache->get_from_cache($cache_key); + return $cached if $cached; + + my $dbh = C4::Context->dbh; + my $subfield_structure = $dbh->selectall_hashref( q| + SELECT * + FROM marc_subfield_structure + WHERE frameworkcode = ? + AND kohafield > '' + |, 'kohafield', {}, $frameworkcode ); + + $cache->set_in_cache( $cache_key, $subfield_structure ); + return $subfield_structure; +} + =head2 GetMarcFromKohaField ($MARCfield,$MARCsubfield)=GetMarcFromKohaField($kohafield,$frameworkcode); @@ -1231,14 +1257,10 @@ for the given frameworkcode or default framework if $frameworkcode is missing =cut sub GetMarcFromKohaField { - my $kohafield = shift; - my $frameworkcode = shift || ''; + my ( $kohafield, $frameworkcode ) = @_; return (0, undef) unless $kohafield; - my $relations = C4::Context->marcfromkohafield; - if ( my $mf = $relations->{$frameworkcode}->{$kohafield} ) { - return @$mf; - } - return (0, undef); + my $mss = GetMarcSubfieldStructure( $frameworkcode ); + return ( $mss->{$kohafield}{tagfield}, $mss->{$kohafield}{tagsubfield} ); } =head2 GetMarcSubfieldStructureFromKohaField @@ -1253,24 +1275,14 @@ $frameworkcode is optional. If not given, then the default framework is used. =cut sub GetMarcSubfieldStructureFromKohaField { - my ($kohafield, $frameworkcode) = @_; + my ( $kohafield, $frameworkcode ) = @_; - return undef unless $kohafield; - $frameworkcode //= ''; + return unless $kohafield; - my $dbh = C4::Context->dbh; - my $query = qq{ - SELECT * - FROM marc_subfield_structure - WHERE kohafield = ? - AND frameworkcode = ? - }; - my $sth = $dbh->prepare($query); - $sth->execute($kohafield, $frameworkcode); - my $result = $sth->fetchrow_hashref; - $sth->finish; - - return $result; + my $mss = GetMarcSubfieldStructure( $frameworkcode ); + return exists $mss->{$kohafield} + ? $mss->{$kohafield} + : undef; } =head2 GetMarcBiblio @@ -2231,17 +2243,18 @@ sub TransformKohaToMarc { my $hash = shift; my $record = MARC::Record->new(); SetMarcUnicodeFlag( $record, C4::Context->preference("marcflavour") ); - my $db_to_marc = C4::Context->marcfromkohafield; + # FIXME Do not we want to get the marc subfield structure for the biblio framework? + my $mss = GetMarcSubfieldStructure(); my $tag_hr = {}; - while ( my ($name, $value) = each %$hash ) { - next unless my $dtm = $db_to_marc->{''}->{$name}; - next unless ( scalar( @$dtm ) ); - my ($tag, $letter) = @$dtm; - $tag .= ''; + while ( my ($kohafield, $value) = each %$hash ) { + next unless exists $mss->{$kohafield}; + next unless $mss->{$kohafield}; + my $tagfield = $mss->{$kohafield}{tagfield} . ''; + my $tagsubfield = $mss->{$kohafield}{tagsubfield}; foreach my $value ( split(/\s?\|\s?/, $value, -1) ) { next if $value eq ''; - $tag_hr->{$tag} //= []; - push @{$tag_hr->{$tag}}, [($letter, $value)]; + $tag_hr->{$tagfield} //= []; + push @{$tag_hr->{$tagfield}}, [($tagsubfield, $value)]; } } foreach my $tag (sort keys %$tag_hr) { @@ -2606,9 +2619,6 @@ sub TransformHtmlToMarc { return $record; } -# cache inverted MARC field map -our $inverted_field_map; - =head2 TransformMarcToKoha $result = TransformMarcToKoha( $record, $frameworkcode ) @@ -2632,9 +2642,7 @@ sub TransformMarcToKoha { $limit_table = $limit_table || 0; $frameworkcode = '' unless defined $frameworkcode; - unless ( defined $inverted_field_map ) { - $inverted_field_map = _get_inverted_marc_field_map(); - } + my $inverted_field_map = _get_inverted_marc_field_map($frameworkcode); my %tables = (); if ( defined $limit_table && $limit_table eq 'items' ) { @@ -2648,9 +2656,9 @@ sub TransformMarcToKoha { # traverse through record MARCFIELD: foreach my $field ( $record->fields() ) { my $tag = $field->tag(); - next MARCFIELD unless exists $inverted_field_map->{$frameworkcode}->{$tag}; + next MARCFIELD unless exists $inverted_field_map->{$tag}; if ( $field->is_control_field() ) { - my $kohafields = $inverted_field_map->{$frameworkcode}->{$tag}->{list}; + my $kohafields = $inverted_field_map->{$tag}->{list}; ENTRY: foreach my $entry ( @{$kohafields} ) { my ( $subfield, $table, $column ) = @{$entry}; next ENTRY unless exists $tables{$table}; @@ -2668,9 +2676,9 @@ sub TransformMarcToKoha { # deal with subfields MARCSUBFIELD: foreach my $sf ( $field->subfields() ) { my $code = $sf->[0]; - next MARCSUBFIELD unless exists $inverted_field_map->{$frameworkcode}->{$tag}->{sfs}->{$code}; + next MARCSUBFIELD unless exists $inverted_field_map->{$tag}->{sfs}->{$code}; my $value = $sf->[1]; - SFENTRY: foreach my $entry ( @{ $inverted_field_map->{$frameworkcode}->{$tag}->{sfs}->{$code} } ) { + SFENTRY: foreach my $entry ( @{ $inverted_field_map->{$tag}->{sfs}->{$code} } ) { my ( $table, $column ) = @{$entry}; next SFENTRY unless exists $tables{$table}; my $key = _disambiguate( $table, $column ); @@ -2713,18 +2721,17 @@ sub TransformMarcToKoha { } sub _get_inverted_marc_field_map { + my ( $frameworkcode ) = @_; my $field_map = {}; - my $relations = C4::Context->marcfromkohafield; - - foreach my $frameworkcode ( keys %{$relations} ) { - foreach my $kohafield ( keys %{ $relations->{$frameworkcode} } ) { - next unless @{ $relations->{$frameworkcode}->{$kohafield} }; # not all columns are mapped to MARC tag & subfield - my $tag = $relations->{$frameworkcode}->{$kohafield}->[0]; - my $subfield = $relations->{$frameworkcode}->{$kohafield}->[1]; - my ( $table, $column ) = split /[.]/, $kohafield, 2; - push @{ $field_map->{$frameworkcode}->{$tag}->{list} }, [ $subfield, $table, $column ]; - push @{ $field_map->{$frameworkcode}->{$tag}->{sfs}->{$subfield} }, [ $table, $column ]; - } + my $mss = GetMarcSubfieldStructure( $frameworkcode ); + + foreach my $kohafield ( keys %{ $mss } ) { + next unless exists $mss->{$kohafield}; # not all columns are mapped to MARC tag & subfield + my $tag = $mss->{$kohafield}{tagfield}; + my $subfield = $mss->{$kohafield}{tagsubfield}; + my ( $table, $column ) = split /[.]/, $kohafield, 2; + push @{ $field_map->{$tag}->{list} }, [ $subfield, $table, $column ]; + push @{ $field_map->{$tag}->{sfs}->{$subfield} }, [ $table, $column ]; } return $field_map; } --- a/C4/Context.pm +++ a/C4/Context.pm @@ -373,7 +373,6 @@ sub new { return if !defined($self->{"config"}); $self->{"Zconn"} = undef; # Zebra Connections - $self->{"marcfromkohafield"} = undef; # the hash with relations between koha table fields and MARC field/subfield $self->{"userenv"} = undef; # User env $self->{"activeuser"} = undef; # current active user $self->{"shelves"} = undef; @@ -931,45 +930,6 @@ sub _new_queryparser { return; } -=head2 marcfromkohafield - - $dbh = C4::Context->marcfromkohafield; - -Returns a hash with marcfromkohafield. - -This hash is cached for future use: if you call -Cmarcfromkohafield> twice, you will get the same hash without real DB access - -=cut - -#' -sub marcfromkohafield -{ - my $retval = {}; - - # If the hash already exists, return it. - return $context->{"marcfromkohafield"} if defined($context->{"marcfromkohafield"}); - - # No hash. Create one. - $context->{"marcfromkohafield"} = &_new_marcfromkohafield(); - - return $context->{"marcfromkohafield"}; -} - -# _new_marcfromkohafield -sub _new_marcfromkohafield -{ - my $dbh = C4::Context->dbh; - my $marcfromkohafield; - my $sth = $dbh->prepare("select frameworkcode,kohafield,tagfield,tagsubfield from marc_subfield_structure where kohafield > ''"); - $sth->execute; - while (my ($frameworkcode,$kohafield,$tagfield,$tagsubfield) = $sth->fetchrow) { - my $retval = {}; - $marcfromkohafield->{$frameworkcode}->{$kohafield} = [$tagfield,$tagsubfield]; - } - return $marcfromkohafield; -} - =head2 userenv C4::Context->userenv; --- a/admin/biblio_framework.pl +++ a/admin/biblio_framework.pl @@ -81,6 +81,7 @@ if ( $op eq 'add_form' ) { $cache->clear_from_cache("MarcStructure-0-$frameworkcode"); $cache->clear_from_cache("MarcStructure-1-$frameworkcode"); $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode"); + $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode"); $op = 'list'; } elsif ( $op eq 'delete_confirm' ) { my $framework = Koha::BiblioFrameworks->find($frameworkcode); @@ -111,6 +112,7 @@ if ( $op eq 'add_form' ) { $cache->clear_from_cache("MarcStructure-0-$frameworkcode"); $cache->clear_from_cache("MarcStructure-1-$frameworkcode"); $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode"); + $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode"); $op = 'list'; } --- a/admin/marc_subfields_structure.pl +++ a/admin/marc_subfields_structure.pl @@ -342,6 +342,7 @@ elsif ( $op eq 'add_validate' ) { $cache->clear_from_cache("MarcStructure-0-$frameworkcode"); $cache->clear_from_cache("MarcStructure-1-$frameworkcode"); $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode"); + $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode"); print $input->redirect("/cgi-bin/koha/admin/marc_subfields_structure.pl?tagfield=$tagfield&frameworkcode=$frameworkcode"); exit; @@ -386,6 +387,7 @@ elsif ( $op eq 'delete_confirmed' ) { $cache->clear_from_cache("MarcStructure-0-$frameworkcode"); $cache->clear_from_cache("MarcStructure-1-$frameworkcode"); $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode"); + $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode"); print $input->redirect("/cgi-bin/koha/admin/marc_subfields_structure.pl?tagfield=$tagfield&frameworkcode=$frameworkcode"); exit; --- a/admin/marctagstructure.pl +++ a/admin/marctagstructure.pl @@ -165,6 +165,7 @@ if ($op eq 'add_form') { $cache->clear_from_cache("MarcStructure-0-$frameworkcode"); $cache->clear_from_cache("MarcStructure-1-$frameworkcode"); $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode"); + $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode"); } print $input->redirect("/cgi-bin/koha/admin/marctagstructure.pl?searchfield=$tagfield&frameworkcode=$frameworkcode"); exit; @@ -192,6 +193,7 @@ if ($op eq 'add_form') { $cache->clear_from_cache("MarcStructure-0-$frameworkcode"); $cache->clear_from_cache("MarcStructure-1-$frameworkcode"); $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode"); + $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode"); } $template->param( searchfield => $searchfield, @@ -358,5 +360,6 @@ sub duplicate_framework { $cache->clear_from_cache("MarcStructure-0-$newframeworkcode"); $cache->clear_from_cache("MarcStructure-1-$newframeworkcode"); $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode"); + $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode"); } --- a/t/db_dependent/Biblio.t +++ a/t/db_dependent/Biblio.t @@ -33,10 +33,63 @@ my $dbh = C4::Context->dbh; $dbh->{AutoCommit} = 0; $dbh->{RaiseError} = 1; -# Mocking variables -my $context = new Test::MockModule('C4::Context'); +subtest 'GetMarcSubfieldStructureFromKohaField' => sub { + plan tests => 23; + + my @columns = qw( + tagfield tagsubfield liblibrarian libopac repeatable mandatory kohafield tab + authorised_value authtypecode value_builder isurl hidden frameworkcode + seealso link defaultvalue maxlength + ); + + # biblio.biblionumber must be mapped so this should return something + my $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('biblio.biblionumber', ''); + + ok(defined $marc_subfield_structure, "There is a result"); + is(ref $marc_subfield_structure, "HASH", "Result is a hashref"); + foreach my $col (@columns) { + ok(exists $marc_subfield_structure->{$col}, "Hashref contains key '$col'"); + } + is($marc_subfield_structure->{kohafield}, 'biblio.biblionumber', "Result is the good result"); + like($marc_subfield_structure->{tagfield}, qr/^\d{3}$/, "tagfield is a valid tagfield"); -mock_marcfromkohafield(); + # foo.bar does not exist so this should return undef + $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('foo.bar', ''); + is($marc_subfield_structure, undef, "invalid kohafield returns undef"); +}; + + +# Mocking variables +my $biblio_module = new Test::MockModule('C4::Biblio'); +$biblio_module->mock( + 'GetMarcSubfieldStructure', + sub { + my ($self) = shift; + + if ( C4::Context->preference('marcflavour') eq 'MARC21' + || C4::Context->preference('marcflavour') eq 'NORMARC' ) { + + return { + 'biblio.title' => { tagfield => '245', tagsubfield => 'a' }, + 'biblio.biblionumber' => { tagfield => '999', tagsubfield => 'c' }, + 'biblioitems.isbn' => { tagfield => '020', tagsubfield => 'a' }, + 'biblioitems.issn' => { tagfield => '022', tagsubfield => 'a' }, + 'biblioitems.biblioitemnumber' => { tagfield => '999', tagsubfield => 'd' }, + 'items.itemnumber' => { tagfield => '952', tagsubfield => '9' }, + }; + } elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) { + + return { + 'biblio.title' => { tagfield => '200', tagsubfield => 'a' }, + 'biblio.biblionumber' => { tagfield => '999', tagsubfield => 'c' }, + 'biblioitems.isbn' => { tagfield => '010', tagsubfield => 'a' }, + 'biblioitems.issn' => { tagfield => '011', tagsubfield => 'a' }, + 'biblioitems.biblioitemnumber' => { tagfield => '090', tagsubfield => 'a' }, + 'items.itemnumber' => { tagfield => '995', tagsubfield => '9' }, + }; + } + } +); my $currency = new Test::MockModule('Koha::Acquisition::Currencies'); $currency->mock( @@ -54,10 +107,6 @@ $currency->mock( sub run_tests { - # Undef C4::Biblio::inverted_field_map to avoid problems introduced - # by caching in TransformMarcToKoha - undef $C4::Biblio::inverted_field_map; - my $marcflavour = shift; t::lib::Mocks::mock_preference('marcflavour', $marcflavour); @@ -226,39 +275,6 @@ sub run_tests { 'Check the number of returned notes of GetMarcNotes' ); } -sub mock_marcfromkohafield { - - $context->mock('marcfromkohafield', - sub { - my ( $self ) = shift; - - if ( C4::Context->preference('marcflavour') eq 'MARC21' || - C4::Context->preference('marcflavour') eq 'NORMARC' ) { - - return { - '' => { - 'biblio.title' => [ '245', 'a' ], - 'biblio.biblionumber' => [ '999', 'c' ], - 'biblioitems.isbn' => [ '020', 'a' ], - 'biblioitems.issn' => [ '022', 'a' ], - 'biblioitems.biblioitemnumber' => [ '999', 'd' ] - } - }; - } elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) { - - return { - '' => { - 'biblio.title' => [ '200', 'a' ], - 'biblio.biblionumber' => [ '999', 'c' ], - 'biblioitems.isbn' => [ '010', 'a' ], - 'biblioitems.issn' => [ '011', 'a' ], - 'biblioitems.biblioitemnumber' => [ '090', 'a' ] - } - }; - } - }); -} - sub create_title_field { my ( $title, $marcflavour ) = @_; @@ -307,31 +323,6 @@ subtest 'NORMARC' => sub { $dbh->rollback; }; -subtest 'GetMarcSubfieldStructureFromKohaField' => sub { - plan tests => 23; - - my @columns = qw( - tagfield tagsubfield liblibrarian libopac repeatable mandatory kohafield tab - authorised_value authtypecode value_builder isurl hidden frameworkcode - seealso link defaultvalue maxlength - ); - - # biblio.biblionumber must be mapped so this should return something - my $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('biblio.biblionumber', ''); - - ok(defined $marc_subfield_structure, "There is a result"); - is(ref $marc_subfield_structure, "HASH", "Result is a hashref"); - foreach my $col (@columns) { - ok(exists $marc_subfield_structure->{$col}, "Hashref contains key '$col'"); - } - is($marc_subfield_structure->{kohafield}, 'biblio.biblionumber', "Result is the good result"); - like($marc_subfield_structure->{tagfield}, qr/^\d{3}$/, "tagfield is a valid tagfield"); - - # foo.bar does not exist so this should return undef - $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('foo.bar', ''); - is($marc_subfield_structure, undef, "invalid kohafield returns undef"); -}; - subtest 'IsMarcStructureInternal' => sub { plan tests => 6; my $tagslib = GetMarcStructure(); --- a/t/db_dependent/Items.t +++ a/t/db_dependent/Items.t @@ -377,15 +377,19 @@ subtest 'SearchItems test' => sub { } ok($found, "item1 found"); - my ($itemfield) = GetMarcFromKohaField('items.itemnumber', ''); + my $frameworkcode = q||; + my ($itemfield) = GetMarcFromKohaField('items.itemnumber', $frameworkcode); # Create item subfield 'z' without link - $dbh->do('DELETE FROM marc_subfield_structure WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=""', undef, $itemfield); - $dbh->do('INSERT INTO marc_subfield_structure (tagfield, tagsubfield, frameworkcode) VALUES (?, "z", "")', undef, $itemfield); + $dbh->do('DELETE FROM marc_subfield_structure WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=?', undef, $itemfield, $frameworkcode); + $dbh->do('INSERT INTO marc_subfield_structure (tagfield, tagsubfield, frameworkcode) VALUES (?, "z", ?)', undef, $itemfield, $frameworkcode); # Clear cache - $C4::Context::context->{marcfromkohafield} = undef; - $C4::Biblio::inverted_field_map = undef; + my $cache = Koha::Cache->get_instance(); + $cache->clear_from_cache("MarcStructure-0-$frameworkcode"); + $cache->clear_from_cache("MarcStructure-1-$frameworkcode"); + $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode"); + $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode"); my $item3_record = new MARC::Record; $item3_record->append_fields( @@ -405,12 +409,14 @@ subtest 'SearchItems test' => sub { # Link $z to items.itemnotes (and make sure there is no other subfields # linked to it) - $dbh->do('DELETE FROM marc_subfield_structure WHERE kohafield="items.itemnotes" AND frameworkcode=""', undef, $itemfield); - $dbh->do('UPDATE marc_subfield_structure SET kohafield="items.itemnotes" WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=""', undef, $itemfield); + $dbh->do('DELETE FROM marc_subfield_structure WHERE kohafield="items.itemnotes" AND frameworkcode=?', undef, $itemfield, $frameworkcode); + $dbh->do('UPDATE marc_subfield_structure SET kohafield="items.itemnotes" WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=?', undef, $itemfield, $frameworkcode); # Clear cache - $C4::Context::context->{marcfromkohafield} = undef; - $C4::Biblio::inverted_field_map = undef; + $cache->clear_from_cache("MarcStructure-0-$frameworkcode"); + $cache->clear_from_cache("MarcStructure-1-$frameworkcode"); + $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode"); + $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode"); ModItemFromMarc($item3_record, $biblionumber, $item3_itemnumber); @@ -564,10 +570,6 @@ subtest 'C4::Items::_build_default_values_for_mod_marc' => sub { $schema->storage->txn_begin(); - # Clear cache - $C4::Context::context->{marcfromkohafield} = undef; - $C4::Biblio::inverted_field_map = undef; - my $builder = t::lib::TestBuilder->new; my $framework = $builder->build({ source => 'BiblioFramework', @@ -647,10 +649,11 @@ subtest 'C4::Items::_build_default_values_for_mod_marc' => sub { |, undef, $framework->{frameworkcode} ); # And make sure the caches are cleared - $C4::Context::context->{marcfromkohafield} = undef; - $C4::Biblio::inverted_field_map = undef; - my $cache = Koha::Cache->get_instance(); - $cache->clear_from_cache("default_value_for_mod_marc-" . $framework->{frameworkcode} ); + my $cache = Koha::Cache->get_instance(); + $cache->clear_from_cache("MarcStructure-0-" . $framework->{frameworkcode}); + $cache->clear_from_cache("MarcStructure-1-" . $framework->{frameworkcode}); + $cache->clear_from_cache("default_value_for_mod_marc-" . $framework->{frameworkcode}); + $cache->clear_from_cache("MarcSubfieldStructure-" . $framework->{frameworkcode}); # Update the MARC field with another value $item_record->delete_fields( $barcode_field ); --