From bf9dc858df1c9a2f9163c0356428e6d5a7eddd06 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 Content-Type: text/plain; charset=utf-8 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 --- 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 diff --git a/C4/Biblio.pm b/C4/Biblio.pm index e58e19c..e501ba4 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); @@ -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; } diff --git a/Koha/Util/MARC.pm b/Koha/Util/MARC.pm index 63477ea..a642b62 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 0000000..3412d1d --- /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 0f86627..9ca7c86 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/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'), 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 d730530..ac0a6ba 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 0000000..aff28cb --- /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 b5dd7ea..1f954dc 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.1.4