@@ -, +, @@ MarcFieldForModifierId, MarcFieldForModifierName --- C4/Biblio.pm | 28 ++++++++++---- Koha/Util/MARC.pm | 43 ++++++++++++++++++++++ installer/data/mysql/atomicupdate/bug_19349.perl | 13 +++++++ installer/data/mysql/sysprefs.sql | 4 ++ .../en/modules/admin/preferences/cataloguing.pref | 10 +++++ t/Koha/Util/MARC.t | 42 +++++++++++++++++++++ t/db_dependent/Biblio.t | 31 +++++++++++++++- 7 files changed, 162 insertions(+), 9 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_19349.perl create mode 100644 t/Koha/Util/MARC.t --- a/C4/Biblio.pm +++ a/C4/Biblio.pm @@ -107,6 +107,7 @@ use Koha::Holds; use Koha::ItemTypes; use Koha::SearchEngine; use Koha::Libraries; +use Koha::Util::MARC; use vars qw($debug $cgi_debug); @@ -3290,15 +3291,26 @@ sub ModBiblioMarc { }; $record->as_usmarc; # Bug 20126/10455 This triggers field length calculation - # FIXME To replace with ->find_or_create? - if ( my $m_rs = Koha::Biblio::Metadatas->find($metadata) ) { - $m_rs->metadata( $record->as_xml_record($encoding) ); - $m_rs->store; - } else { - my $m_rs = Koha::Biblio::Metadata->new($metadata); - $m_rs->metadata( $record->as_xml_record($encoding) ); - $m_rs->store; + my $m_rs = Koha::Biblio::Metadatas->find($metadata); + unless ($m_rs) { + $m_rs = Koha::Biblio::Metadata->new($metadata); + } + + my $userenv = C4::Context->userenv; + if ($userenv) { + my $borrowernumber = $userenv->{number}; + my $borrowername = join ' ', @$userenv{qw(firstname surname)}; + unless ($m_rs->in_storage) { + Koha::Util::MARC::set_marc_field($record, C4::Context->preference('MarcFieldForCreatorId'), $borrowernumber); + Koha::Util::MARC::set_marc_field($record, C4::Context->preference('MarcFieldForCreatorName'), $borrowername); + } + Koha::Util::MARC::set_marc_field($record, C4::Context->preference('MarcFieldForModifierId'), $borrowernumber); + Koha::Util::MARC::set_marc_field($record, C4::Context->preference('MarcFieldForModifierName'), $borrowername); } + + $m_rs->metadata( $record->as_xml_record($encoding) ); + $m_rs->store; + ModZebra( $biblionumber, "specialUpdate", "biblioserver", $record ); return $biblionumber; } --- a/Koha/Util/MARC.pm +++ a/Koha/Util/MARC.pm @@ -179,4 +179,47 @@ sub getAuthorityAuthorizedHeading { return; } +=head2 set_marc_field + + set_marc_field($record, $marcField, $value); + +Set the value of $marcField to $value in $record. If the field exists, it will +be updated. If not, it will be created. + +=head3 Parameters + +=over 4 + +=item C<$record> + +MARC::Record object + +=item C<$marcField> + +the MARC field to modify, a string in the form of 'XXX$y' + +=item C<$value> + +the value + +=back + +=cut + +sub set_marc_field { + my ($record, $marcField, $value) = @_; + + if ($marcField) { + my ($fieldTag, $subfieldCode) = split /\$/, $marcField; + my $field = $record->field($fieldTag); + if ($field) { + $field->update($subfieldCode => $value); + } else { + $field = MARC::Field->new($fieldTag, ' ', ' ', + $subfieldCode => $value); + $record->append_fields($field); + } + } +} + 1; --- a/installer/data/mysql/atomicupdate/bug_19349.perl +++ a/installer/data/mysql/atomicupdate/bug_19349.perl @@ -0,0 +1,13 @@ +$DBversion = 'XXX'; +if( CheckVersion( $DBversion ) ) { + $dbh->do(q{ + INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`, `type`) VALUES + ('MarcFieldForCreatorId','',NULL,'Where to store the borrowernumber of the record''s creator','Free'), + ('MarcFieldForCreatorName','',NULL,'Where to store the name of the record''s creator','Free'), + ('MarcFieldForModifierId','',NULL,'Where to store the borrowernumber of the record''s last modifier','Free'), + ('MarcFieldForModifierName','',NULL,'Where to store the name of the record''s last modifier','Free') + }); + + SetVersion( $DBversion ); + print "Upgrade to $DBversion done (Bug 19349 - Add system preferences MarcFieldForCreatorId, MarcFieldForCreatorName, MarcFieldForModifierId, MarcFieldForModifierName)\n"; +} --- a/installer/data/mysql/sysprefs.sql +++ a/installer/data/mysql/sysprefs.sql @@ -271,6 +271,10 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('ManInvInNoissuesCharge','1',NULL,'MANUAL_INV charges block checkouts (added to noissuescharge).','YesNo'), ('MARCAuthorityControlField008','|| aca||aabn | a|a d',NULL,'Define the contents of MARC21 authority control field 008 position 06-39','Textarea'), ('MarcFieldDocURL', NULL, NULL, 'URL used for MARC field documentation. Following substitutions are available: {MARC} = marc flavour, eg. "MARC21" or "UNIMARC". {FIELD} = field number, eg. "000" or "048". {LANG} = user language, eg. "en" or "fi-FI"', 'free'), +('MarcFieldForCreatorId','',NULL,'Where to store the borrowernumber of the record''s creator','Free'), +('MarcFieldForCreatorName','',NULL,'Where to store the name of the record''s creator','Free'), +('MarcFieldForModifierId','',NULL,'Where to store the borrowernumber of the record''s last modifier','Free'), +('MarcFieldForModifierName','',NULL,'Where to store the name of the record''s last modifier','Free'), ('MarcFieldsToOrder','',NULL,'Set the mapping values for a new order line created from a MARC record in a staged file. In a YAML format.','textarea'), ('MarcItemFieldsToOrder','',NULL,'Set the mapping values for new item records created from a MARC record in a staged file. In a YAML format.','textarea'), ('MarkLostItemsAsReturned','batchmod|moredetail|cronjob|additem','batchmod|moredetail|cronjob|additem','Mark items as returned when flagged as lost','multiple'), --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref @@ -138,6 +138,16 @@ Cataloging: - 'MARC21: "952$a 952$b 952$c"' - Note that the FA framework is excluded from the permission. - If the pref is empty, no fields are restricted. + - + - Store record's creator borrowernumber in MARC subfield + - pref: MarcFieldForCreatorId + - and record's creator name in MARC subfield + - pref: MarcFieldForCreatorName + - + - Store record's last modifier borrowernumber in MARC subfield + - pref: MarcFieldForModifierId + - and record's last modifier name in MARC subfield + - pref: MarcFieldForModifierName Display: - - 'Separate multiple displayed authors, series or subjects with ' --- a/t/Koha/Util/MARC.t +++ a/t/Koha/Util/MARC.t @@ -0,0 +1,42 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 2; + +BEGIN { use_ok('Koha::Util::MARC'); } + +subtest 'set_marc_field' => sub { + plan tests => 6; + + my $record = MARC::Record->new(); + + Koha::Util::MARC::set_marc_field($record, '999$9', 'foobar'); + my @fields = $record->field('999'); + is(scalar @fields, 1, 'Created one field'); + my @subfields = $fields[0]->subfield('9'); + is(scalar @subfields, 1, 'Created one subfield'); + is($subfields[0], 'foobar', 'Created subfield has correct value'); + + Koha::Util::MARC::set_marc_field($record, '999$9', 'foobaz'); + @fields = $record->field('999'); + is(scalar @fields, 1, 'No additional field created'); + @subfields = $fields[0]->subfield('9'); + is(scalar @subfields, 1, 'No additional subfield created'); + is($subfields[0], 'foobaz', 'Subfield value has been changed'); +}; --- a/t/db_dependent/Biblio.t +++ a/t/db_dependent/Biblio.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 10; +use Test::More tests => 11; use Test::MockModule; use List::MoreUtils qw( uniq ); use MARC::Record; @@ -466,6 +466,35 @@ subtest 'DelBiblio' => sub { is( $deleted, undef, 'DelBiblo should return undef is the record did not exist'); }; +subtest 'MarcFieldForCreatorAndModifier' => sub { + plan tests => 8; + + t::lib::Mocks::mock_preference('MarcFieldForCreatorId', '998$a'); + t::lib::Mocks::mock_preference('MarcFieldForCreatorName', '998$b'); + t::lib::Mocks::mock_preference('MarcFieldForModifierId', '998$c'); + t::lib::Mocks::mock_preference('MarcFieldForModifierName', '998$d'); + my $c4_context = Test::MockModule->new('C4::Context'); + $c4_context->mock('userenv', sub { return { number => 123, firstname => 'John', surname => 'Doe'}; }); + + my $record = MARC::Record->new(); + my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); + + $record = GetMarcBiblio({biblionumber => $biblionumber}); + is($record->subfield('998', 'a'), 123, '998$a = 123'); + is($record->subfield('998', 'b'), 'John Doe', '998$b = John Doe'); + is($record->subfield('998', 'c'), 123, '998$c = 123'); + is($record->subfield('998', 'd'), 'John Doe', '998$d = John Doe'); + + $c4_context->mock('userenv', sub { return { number => 321, firstname => 'Jane', surname => 'Doe'}; }); + C4::Biblio::ModBiblio($record, $biblionumber, ''); + + $record = GetMarcBiblio({biblionumber => $biblionumber}); + is($record->subfield('998', 'a'), 123, '998$a = 123'); + is($record->subfield('998', 'b'), 'John Doe', '998$b = John Doe'); + is($record->subfield('998', 'c'), 321, '998$c = 321'); + is($record->subfield('998', 'd'), 'Jane Doe', '998$d = Jane Doe'); +}; + # Cleanup Koha::Caches->get_instance->clear_from_cache( "MarcSubfieldStructure-" ); $schema->storage->txn_rollback; --