From 16734c0a9e968bb0ff59d24a39cc6d17e145a5a7 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Fri, 15 Mar 2013 16:03:51 -0300 Subject: [PATCH] [SIGNED-OFF] Bug 906 - ISBN Check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the MARC editor, have the ISBN checked. This feature is syspref-driven [1]. The patch adds the following javascript functions to cataloguing/addbiblio.tt: - _NormalizeISBN (for sanitizing the ISBN before algorithm checking) - _CheckISBNChecksum10 (for validating the checksum digit) - _CheckISBNChecksum13 (idem) - IsISBNOk (extract the isbn from the corresponding field, call the proper checker functions, return the string message) The Check function was hooked to call IsISBNOk and build a proper message dialog. AreMandatoriesNotOk got its message string rearranged too. To test: - Apply the patch, run updatedatabase.pl so the new syspref gets included on the DB. - Try adding a record: no matter what you introduce on the corresponding ISBN field Koha will behave as usual. - Go to the Sysprefs editor, under 'Cataloguing' set RequireValidISBN to 'Require'. - Reload your marc editor - Try different ISBN to see how it behaves: -- test cases -- * Empty ISBN should not stop you from saving your record. * Valid ISBN idem [2]. * Wrong ISBN should make Koha warn you and ask you to fix it [3]. [1] Added RequireValidISBN syspref. [2] Valid ISBN10: 291409891X ISBN13: 9784873113685 [3] Try To+ Sponsored-by: Universidad Nacional de Córdoba Signed-off-by: Bernardo Gonzalez Kriegel Comment: Work as described. No errors. Tested with 10 and 13 ISBN, and random string. Suggestion: If problem is in check digit, could suggest correct value? --- cataloguing/addbiblio.pl | 3 +- installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 10 ++ .../en/modules/admin/preferences/cataloguing.pref | 6 ++ .../prog/en/modules/cataloguing/addbiblio.tt | 104 +++++++++++++++++++- 5 files changed, 119 insertions(+), 5 deletions(-) diff --git a/cataloguing/addbiblio.pl b/cataloguing/addbiblio.pl index 3314f1a..bde5716 100755 --- a/cataloguing/addbiblio.pl +++ b/cataloguing/addbiblio.pl @@ -987,7 +987,8 @@ $template->param( popup => $mode, frameworkcode => $frameworkcode, itemtype => $frameworkcode, - borrowernumber => $loggedinuser, + borrowernumber => $loggedinuser, + RequireValidISBN => C4::Context->preference("RequireValidISBN") ); output_html_with_http_headers $input, $cookie, $template->output; diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 9c66df0..6ba954c 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -419,3 +419,4 @@ INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) V INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacItemLocation','callnum','Show the shelving location of items in the opac','callnum|ccode|location','Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('TrackClicks','0','Track links clicked',NULL,'Integer'); INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('PatronSelfRegistrationAdditionalInstructions','','A free text field to display additional instructions to newly self registered patrons.','','free'); +INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('RequireValidISBN',0,'Require a valid ISBN',NULL,'YesNo'); diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 9b4aa8e..437fe0f 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -6512,6 +6512,16 @@ if ( CheckVersion($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.11.00.XXX"; +if ( CheckVersion($DBversion) ) { + $dbh->do(q{ + INSERT INTO systempreferences (variable,value,explanation,options,type) + VALUES('RequireValidISBN', '0', 'Require a valid ISBN',NULL,'YesNo') + }); + print "Upgrade to $DBversion done (Bug 906: ISBN Check)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) 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 96f3603..6146e68 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 @@ -109,6 +109,12 @@ Cataloging: - pref: UNIMARCField100Language class: short - as default language in the UNIMARC field 100 when creating a new record or in the field plugin. + - + - pref: RequireValidISBN + choices: + yes: Require + no: Don't require + - a valid ISBN. Display: - - 'Separate multiple displayed authors, series or subjects with ' 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 7e439bf..0ace809 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt @@ -135,6 +135,90 @@ function showMARCdocLinks() { $.cookie("marcdocs_[% borrowernumber %]",'true', { path: "/", expires: 365 }); } +/* + * Functions to check ISBN validity + */ + +function _NormalizeISBN(isbn) { + // remove non-word characters + var normalized_isbn = isbn.replace(/\W|_/g,''); + // we want upper-case 'X' + return normalized_isbn.toUpperCase(); +} + +function _CheckISBNChecksum10(isbn) { + + var sum = 0; + var i,r; + + if ( isbn.match(/\d{10}|^\d{9}X$/) ) { + // its a 10 digit string, it might end with X + for ( i=0; i<9; i++ ) { + sum += (i+1) * parseInt(isbn[i],10); + } + r = sum % 11; + if ( r == 10 && isbn[9] == 'X' || + r == isbn[9] ) { + return isbn; + } + } + return null; +} + +function _CheckISBNChecksum13(isbn) { + + var sum = 0; + var i,r; + + if ( isbn.match(/^\d{13}$/) ) { + for (i=0;i<12;i++) { + if ( (i+1) % 2 == 0 ) { + // even + sum += 3 * parseInt(isbn[i],10); + } else { + // odd + sum += parseInt(isbn[i],10); + } + } + r = (10 - (sum % 10)) % 10; + if ( r == isbn[12] ) { + return isbn; + } + } + return null; +} + +function IsISBNOk() { + + var isbn; + var isbn_field; +[% IF ( marcflavour == 'MARC21' || marcflavour == 'NORMARC' ) %] + isbn = $('input[id^="tag_020_subfield_a"]').val(); + isbn_field = "020"; +[% ELSIF ( marcflavour == 'UNIMARC' ) %] + isbn = $('input[id^="tag_010_subfield_a"]').val(); + isbn_field = "010"; +[% END %] + var normalized_isbn = _NormalizeISBN(isbn); + + if ( normalized_isbn.length == 13 ) { + if ( normalized_isbn == _CheckISBNChecksum13(normalized_isbn) ) { + return 0; + } + } else if ( normalized_isbn.length == 10 ) { + if ( normalized_isbn == _CheckISBNChecksum10(normalized_isbn) ) { + return 0; + } + } else if ( normalized_isbn.length == 0 ) { + // no ISBN, no check + return 0; + } + // Invalid ISBN + var StrAlert = "- "+_("The ISBN you entered seems invalid. If you entered it exactly ")+"\n"; + StrAlert += _("as it appears on the item, put it in ") + isbn_field + "$z."; + return StrAlert; +} + /** * check if mandatory subfields are written */ @@ -158,8 +242,8 @@ function AreMandatoriesNotOk(){ [% END %] [% END %] [% END %] - var StrAlert = _("Can't save this record because the following field aren't filled:"); - StrAlert += "\n\n"; + var StrAlert = "- "+_("The following fields aren't filled:"); + StrAlert += "\n"; for(var i=0,len=mandatories.length; i