From 252e333485fec4c754e9025306c59d13b7d0f09e 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 | 71 +++++++++++++++++++--- installer/data/mysql/atomicupdate/bug_19349.perl | 13 ++++ installer/data/mysql/sysprefs.sql | 4 ++ .../en/modules/admin/preferences/cataloguing.pref | 10 +++ t/db_dependent/Biblio.t | 50 ++++++++++++++- 5 files changed, 139 insertions(+), 9 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_19349.perl diff --git a/C4/Biblio.pm b/C4/Biblio.pm index baaa325..7c10332 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -3420,15 +3420,27 @@ sub ModBiblioMarc { format => 'marcxml', marcflavour => C4::Context->preference('marcflavour'), }; - # 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) { + _set_marc_field($record, C4::Context->preference('MarcFieldForCreatorId'), $borrowernumber); + _set_marc_field($record, C4::Context->preference('MarcFieldForCreatorName'), $borrowername); + } + _set_marc_field($record, C4::Context->preference('MarcFieldForModifierId'), $borrowernumber); + _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; } @@ -3683,6 +3695,49 @@ sub RemoveAllNsb { return $record; } +=head2 _set_marc_field + + _set_marc_field($record, $marcField, $value); + +Set the value of $marcField to $value in $record + +=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 fc4e560..372abfd 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -253,6 +253,10 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('makePreviousSerialAvailable','0','','make previous serial automatically available when collecting a new serial. Please note that the item-level_itypes syspref must be set to specific item.','YesNo'), ('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'), +('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'), ('MARCOrgCode','OSt','','Define MARC Organization Code for MARC21 records - http://www.loc.gov/marc/organizations/orgshome.html','free'), 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 9adefc7..03576d4 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 @@ -129,6 +129,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/db_dependent/Biblio.t b/t/db_dependent/Biblio.t index 0890350..d666ea4 100755 --- a/t/db_dependent/Biblio.t +++ b/t/db_dependent/Biblio.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 7; +use Test::More tests => 9; use Test::MockModule; use List::MoreUtils qw( uniq ); @@ -391,3 +391,51 @@ subtest 'deletedbiblio_metadata' => sub { is( $moved, $biblionumber, 'Found in deletedbiblio_metadata' ); }; +subtest '_set_marc_field' => sub { + plan tests => 6; + + my $record = MARC::Record->new(); + + C4::Biblio::_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'); + + C4::Biblio::_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'); +}; + +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'); +}; -- 2.7.4