From 138aaef409bb26202f5fb9060734df880f3f6d47 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 --- 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 0c5a917c6b..c6ec83960b 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -48,6 +48,7 @@ use Koha::Holds; use Koha::ItemTypes; use Koha::SearchEngine; use Koha::Libraries; +use Koha::Util::MARC; use vars qw(@ISA @EXPORT); use vars qw($debug $cgi_debug); @@ -3306,15 +3307,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 753bc57d0a..9aa7bb7695 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -265,6 +265,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 cc75b6dfb4..584b83ffb9 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 @@ -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 ' 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 bb43bb1dd0..a366cf923b 100755 --- a/t/db_dependent/Biblio.t +++ b/t/db_dependent/Biblio.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 9; +use Test::More tests => 10; use Test::MockModule; use List::MoreUtils qw( uniq ); use MARC::Record; @@ -455,6 +455,35 @@ subtest 'deletedbiblio_metadata' => sub { is( $moved, $biblionumber, 'Found in deletedbiblio_metadata' ); }; +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.17.1