From ac39b7772ddae5335b148472e39d3f6eadd91f9d Mon Sep 17 00:00:00 2001 From: Aleisha Amohia Date: Fri, 5 Mar 2021 15:59:45 +1300 Subject: [PATCH] Bug 29980: Validate ISBNs when saving biblio records This enhancement adds a new system preference ValidateISBN. When enabled, Koha will apply a valid checksum algorithm to ISBN fields (020$a for MARC21 and 010$a for UNIMARC) to validate the ISBN when cataloguing bibliographic records. The user will be prompted to fix their invalid ISBN, or have the option to bypass the ISBN check and save anyway. This will work for both 10-digit and 13-digit ISBNs. This patch also cleans up some bad indentation in cataloguing/addbiblio.pl. To test: 1) Apply patch, update database. 2) Go to Koha administration -> global system preferences -> cataloguing tab -> Record structure heading. Note the new ValidateISBN system preference. It should be disabled by default. Leave it disabled. 3) Set marcflavour system preference to MARC21. 4) In a new tab, go to add a new biblio record, or edit an existing one. 5) Find the 020$a field and input an incorrect ISBN. Save the record and confirm the ISBN is not validated and does not block saving the record. 6) Go back to your system preferences tab. Set the ValidateISBN tab to "Validate" to enable it. 7) Go back to your cataloguing tab. Edit the record. Save the record without making any changes. 8) Confirm an Invalid ISBN error pops up, blocking you from saving. Click Continue to bypass the ISBN check and save the record with the invalid ISBN. 9) Edit the record again. Save the record without making any changes. 10) When the Invalid ISBN error pops up, this time fix the invalid ISBN, then save the record again. Confirm you are able to save the record. 11) Go back to the system preferences tab and change the marcflavour system preference to UNIMARC. Repeat the above steps, but this time use the 010$a field instead of 020$a for ISBN. Sponsored-by: Education Services Australia SCIS --- cataloguing/addbiblio.pl | 103 ++++++++++++--------- .../prog/en/modules/cataloguing/addbiblio.tt | 17 ++++ 2 files changed, 77 insertions(+), 43 deletions(-) diff --git a/cataloguing/addbiblio.pl b/cataloguing/addbiblio.pl index 036764417c..ded4714c2d 100755 --- a/cataloguing/addbiblio.pl +++ b/cataloguing/addbiblio.pl @@ -56,6 +56,7 @@ use Koha::Patrons; use MARC::File::USMARC; use MARC::File::XML; use URI::Escape qw( uri_escape_utf8 ); +use Business::ISBN qw( valid_isbn_checksum ); if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) { MARC::File::XML->default_record_format('UNIMARC'); @@ -862,8 +863,19 @@ if ( $op eq "addbiblio" ) { ( $duplicatebiblionumber, $duplicatetitle ) = FindDuplicate($record); } my $confirm_not_duplicate = $input->param('confirm_not_duplicate'); + my @input_isbns = ( C4::Context->preference('marcflavour') eq "UNIMARC" ) ? $record->subfield('010','a') : $record->subfield('020','a'); + my $valid_isbn = 1; + if ( C4::Context->preference('ValidateISBN') ) { + foreach my $input_isbn ( @input_isbns ) { + $valid_isbn = valid_isbn_checksum( $input_isbn ); + unless ( $valid_isbn ) { + last; + } + } + } + my $bypass_isbn = C4::Context->preference('ValidateISBN') ? $input->param('bypass_isbn') : 1; # it is not a duplicate (determined either by Koha itself or by user checking it's not a duplicate) - if ( !$duplicatebiblionumber or $confirm_not_duplicate ) { + if ( ( !$duplicatebiblionumber or $confirm_not_duplicate ) and ( $valid_isbn or $bypass_isbn ) ) { my $oldbibitemnum; if ( $is_a_modif ) { my $member = Koha::Patrons->find($loggedinuser); @@ -884,27 +896,27 @@ if ( $op eq "addbiblio" ) { ( $biblionumber, $oldbibitemnum ) = AddBiblio( $record, $frameworkcode ); } if ($redirect eq "items" || ($mode ne "popup" && !$is_a_modif && $redirect ne "view" && $redirect ne "just_save")){ - if ($frameworkcode eq 'FA'){ - print $input->redirect( - '/cgi-bin/koha/cataloguing/additem.pl?' - .'biblionumber='.$biblionumber - .'&frameworkcode='.$frameworkcode - .'&circborrowernumber='.$fa_circborrowernumber - .'&branch='.$fa_branch - .'&barcode='.uri_escape_utf8($fa_barcode) - .'&stickyduedate='.$fa_stickyduedate - .'&duedatespec='.$fa_duedatespec - ); - exit; - } - else { - print $input->redirect( - "/cgi-bin/koha/cataloguing/additem.pl?biblionumber=$biblionumber&frameworkcode=$frameworkcode&searchid=$searchid" - ); - exit; - } + if ($frameworkcode eq 'FA'){ + print $input->redirect( + '/cgi-bin/koha/cataloguing/additem.pl?' + .'biblionumber='.$biblionumber + .'&frameworkcode='.$frameworkcode + .'&circborrowernumber='.$fa_circborrowernumber + .'&branch='.$fa_branch + .'&barcode='.uri_escape_utf8($fa_barcode) + .'&stickyduedate='.$fa_stickyduedate + .'&duedatespec='.$fa_duedatespec + ); + exit; + } + else { + print $input->redirect( + "/cgi-bin/koha/cataloguing/additem.pl?biblionumber=$biblionumber&frameworkcode=$frameworkcode&searchid=$searchid" + ); + exit; + } } - elsif(($is_a_modif || $redirect eq "view") && $redirect ne "just_save"){ + elsif(($is_a_modif || $redirect eq "view") && $redirect ne "just_save"){ my $defaultview = C4::Context->preference('IntranetBiblioDefaultView'); my $views = { C4::Search::enabled_staff_search_views }; if ($defaultview eq 'isbd' && $views->{can_view_ISBD}) { @@ -917,29 +929,34 @@ if ( $op eq "addbiblio" ) { print $input->redirect("/cgi-bin/koha/catalogue/detail.pl?biblionumber=$biblionumber&searchid=$searchid"); } exit; - - } - elsif ($redirect eq "just_save"){ - my $tab = $input->param('current_tab'); - print $input->redirect("/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=$biblionumber&framework=$frameworkcode&tab=$tab&searchid=$searchid"); - } - else { - $template->param( - biblionumber => $biblionumber, - done =>1, - popup =>1 - ); - if ( $record ne '-1' ) { - my $title = C4::Context->preference('marcflavour') eq "UNIMARC" ? $record->subfield('200', 'a') : $record->title; - $template->param( title => $title ); - } - $template->param( - popup => $mode, - itemtype => $frameworkcode, - ); - output_html_with_http_headers $input, $cookie, $template->output; - exit; } + elsif ($redirect eq "just_save"){ + my $tab = $input->param('current_tab'); + print $input->redirect("/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=$biblionumber&framework=$frameworkcode&tab=$tab&searchid=$searchid"); + } + else { + $template->param( + biblionumber => $biblionumber, + done =>1, + popup =>1 + ); + if ( $record ne '-1' ) { + my $title = C4::Context->preference('marcflavour') eq "UNIMARC" ? $record->subfield('200', 'a') : $record->title; + $template->param( title => $title ); + } + $template->param( + popup => $mode, + itemtype => $frameworkcode, + ); + output_html_with_http_headers $input, $cookie, $template->output; + exit; + } + } elsif ( !$valid_isbn ) { + build_tabs ($template, $record, $dbh,$encoding,$input); + $template->param( + biblionumber => $biblionumber, + invalid_isbn => 1, + ); } else { # it may be a duplicate, warn the user and do nothing build_tabs ($template, $record, $dbh,$encoding,$input); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt index 5325d6e91f..c8b85d1a2f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt @@ -436,6 +436,12 @@ function PopupMARCFieldDoc(field) { Check(); } + function bypass_isbn(redirect){ + $("#bypass_isbn").attr("value","1"); + $("#redirect").attr("value",redirect); + Check(); + } + function Dopop(link,i) { defaultvalue = document.getElementById(i).value; window.open(link+"&result="+defaultvalue,"valuebuilder",'width=700,height=550,toolbar=false,scrollbars=yes'); @@ -838,6 +844,16 @@ function PopupMARCFieldDoc(field) { [% END # /IF duplicatebiblionumber %] + + [% IF ( invalid_isbn ) %] +
+

Invalid ISBN detected

+

An invalid ISBN has been detected [% IF Koha.Preference('marcflavour') == "UNIMARC" %](010$a)[% ELSE %](020$a)[% END %]. Fix the record and Save again, or Continue to save the current record.

+
+ +
+
+ [% END # /IF invalid_isbn %] [% END # /UNLESS number %] [% IF ( done ) %] @@ -851,6 +867,7 @@ function PopupMARCFieldDoc(field) { + [% END %]
-- 2.11.0