From 42e9c49934c87f17b3350955e7d5d0860ecbe8bd Mon Sep 17 00:00:00 2001 From: Julian Maurice Date: Wed, 20 Sep 2017 14:58:07 +0200 Subject: [PATCH] Bug 19349: Store record's creator and last modifier in record Test plan: 1. Run updatedatabase.pl 2. Set sysprefs MarcFieldForCreatorId, MarcFieldForCreatorName, MarcFieldForModifierId, MarcFieldForModifierName 3. Create a new biblio 4. Verify that the fields are correctly filled 5. Logout and login as another user 6. Modify the same biblio 7. Verify that only the fields for last modifier have been modified Works perfectly. Signed-off-by: Simon Pouchol Signed-off-by: Marcel de Rooy Signed-off-by: Nick Clemens --- C4/Biblio.pm | 28 ++++++++---- Koha/Util/MARC.pm | 43 +++++++++++++++++++ .../data/mysql/atomicupdate/bug_19349.perl | 13 ++++++ installer/data/mysql/sysprefs.sql | 4 ++ .../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 diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 647d1d0611..8e31dcd20b 100644 --- a/C4/Biblio.pm +++ b/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); @@ -3324,15 +3325,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; } diff --git a/Koha/Util/MARC.pm b/Koha/Util/MARC.pm index 63477ea4e3..a642b626ca 100644 --- a/Koha/Util/MARC.pm +++ b/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; diff --git a/installer/data/mysql/atomicupdate/bug_19349.perl b/installer/data/mysql/atomicupdate/bug_19349.perl new file mode 100644 index 0000000000..3412d1dedb --- /dev/null +++ b/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"; +} diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 2a7aaa9dcd..077d8e0d96 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -274,6 +274,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'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref index 0b17e881c4..b25bf338d1 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref @@ -139,6 +139,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 ' diff --git a/t/Koha/Util/MARC.t b/t/Koha/Util/MARC.t new file mode 100644 index 0000000000..aff28cbf7d --- /dev/null +++ b/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'); +}; diff --git a/t/db_dependent/Biblio.t b/t/db_dependent/Biblio.t index b5dd7ea60e..1f954dcca0 100755 --- a/t/db_dependent/Biblio.t +++ b/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; -- 2.39.5