Bugzilla – Attachment 132690 Details for
Bug 18618
Mana - Add reading suggestions (crontab and scripts for Koha)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 18618: Mana readings pairs
Bug-18618-Mana-readings-pairs.patch (text/plain), 96.73 KB, created by
Alex Arnaud
on 2022-03-31 09:35:49 UTC
(
hide
)
Description:
Bug 18618: Mana readings pairs
Filename:
MIME Type:
Creator:
Alex Arnaud
Created:
2022-03-31 09:35:49 UTC
Size:
96.73 KB
patch
obsolete
>From eb10148d92d6131b433e4db80a73db634a8abedc Mon Sep 17 00:00:00 2001 >From: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com> >Date: Thu, 27 Apr 2017 15:44:09 +0000 >Subject: [PATCH] Bug 18618: Mana readings pairs > >- There are 2 differents scripts: >misc/cronjobs/mana_send_pairs.pl -> please use it if Mana is installed >misc/cronjobs/mana_send_pairs_without_mana.pl -> designed to work if mana isn't enabled > >- Both of scripts anonymize the datas and send them to mana. > >Bug 18618: Mana - Add reading suggestion > >There is now a module to get suggestions from Mana. > >- It is activated by default on Mana. >- When you browse on a notice, there is now a tab called "Suggestions" >- On click on the tab, it will check in the database if it has suggestions. >- Else, it will ask to Mana for suggestions and will store in the database. > >- The suggestions are stored in the NEW table reading_pairs >- Implement new dbix objets: Reading_suggestion and Reading_suggestions > >Bug 18618: Add a pagination for suggestions > >*** Suggestions are now sent from Mana as follows > >- Koha requests the first 20 suggestions >- It processes them and estimates how much it will need to get all suggestions >- It requests Mana the number of suggestions needed >- It repeats the 3 first steps until > (1) Mana doesn't have suggestions anymore > (2) It got 10 suggestions to display > >*** Koha interface is a bit more verbose while searching (just a bit). > >Bug 18618: Correct Plack issues > >Split one command line into two in order to be accepted by Plack > >Bug 18618: Rebase modification > >Remove mana_send_pairs_without_mana.pl > This script was here for testing purpose and is not usefull anymore >Fix name issues (some function have been renamed) >Fix a compilation issues (redeclared variable) >Remove an unused variable >Remove an extra % in an sql request >Fix display problem when getting info from mana > When getting info from mana the biblios array contain blessed references > but the template don't deal with that properly. > It work fine whe koha is getting info from it's interne database because > biblios array contain unblessed references. > >Bug 18618 : Many small refacto and improvement > >* change duration before refresh and improve the use of $temp variable >* improve SQL request for extracting pairs > fix condition > create pair with old_issues > use placeholders >* improve SQL request for getting suggestion > add the possibility to look in metadata for the id >* execute the script only if mana is activated >* optimize imbricate foreach loop >* add a max number of simultaneous issues >* remove unused option > >Bug 18618: Add a better support for different id types > >Add a better support for ISMN, ISRN, ISRC and UPC > >Add normalization function for some of these ids. > >When sending pairs to mana and when getting suggestions these ids are >now taken into account correctly. > >Documents with multiple identifier were causing various trouble. >It was needed to add functions to normalize all ids > >This patch add the possibility to: >- create pairs with documents with multiple ids (all the possible pairs will be created) >- get suggestion for a document with multiple ids >- display correctly the document when the suggested document has multiple ids > >Bug 18618: Add MARC21 support > >This functionnality is now working for both MARC21 and UNIMARC. > >Bug 18618 : refacto to allow unit test and add unit test > >Re-write pairs extraction script to use testable function >Re-write getSuggestion script to use testable function >Add unit test for normalizaation functions >Add unit test for pairs extractions function >Add unit test for getSuggestion function >Fix many small problems found while writing unit test >--- > Koha/Biblio.pm | 13 + > Koha/Reading_suggestion.pm | 50 ++ > Koha/Reading_suggestions.pm | 58 ++ > Koha/SharedContent.pm | 454 ++++++++++++++ > Koha/Util/Normalize.pm | 387 +++++++++++- > .../atomicupdate/mana_add_table_reading_pairs.sql | 16 + > .../bootstrap/en/modules/mana/mana_suggestions.tt | 40 ++ > .../opac-tmpl/bootstrap/en/modules/opac-detail.tt | 28 + > misc/cronjobs/mana_send_pairs.pl | 48 ++ > opac/svc/mana/getSuggestion | 103 ++++ > t/Koha/Util/Normalize.t | 303 ++++++++- > t/db_dependent/Koha/SharedContent.t | 678 ++++++++++++++++++++- > 12 files changed, 2171 insertions(+), 7 deletions(-) > create mode 100644 Koha/Reading_suggestion.pm > create mode 100644 Koha/Reading_suggestions.pm > create mode 100644 installer/data/mysql/atomicupdate/mana_add_table_reading_pairs.sql > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/mana/mana_suggestions.tt > create mode 100644 misc/cronjobs/mana_send_pairs.pl > create mode 100755 opac/svc/mana/getSuggestion > >diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm >index fc1affe..c306c95 100644 >--- a/Koha/Biblio.pm >+++ b/Koha/Biblio.pm >@@ -893,6 +893,19 @@ sub to_api_mapping { > > =cut > >+=head3 normalized_isbn >+ >+my $normalized_isbn = $biblio->normalizedisbn(); >+ >+Return the normalized isbn of the biblio ( isbn-10 without hyphens ) >+ >+=cut >+ >+sub normalized_isbn { >+ my $self = shift; >+ return NormalizeISBN({ isbn => $self->biblioitem->isbn, format => 'ISBN-10', strip_hyphens => 1 }); >+} >+ > sub _type { > return 'Biblio'; > } >diff --git a/Koha/Reading_suggestion.pm b/Koha/Reading_suggestion.pm >new file mode 100644 >index 0000000..485cdce >--- /dev/null >+++ b/Koha/Reading_suggestion.pm >@@ -0,0 +1,50 @@ >+package Koha::Reading_suggestion; >+ >+# Copyright Biblibre 2017 - Baptiste Wojtkowski >+# >+# 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, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Carp; >+ >+use Koha::Database; >+use Koha::DateUtils qw( dt_from_string ); >+ >+use base qw(Koha::Object); >+ >+ >+=head1 NAME >+ >+Koha::Biblio - Koha Biblio Object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+sub _type { >+ return 'ReadingSuggestion'; >+} >+ >+=head1 AUTHOR >+ >+Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com> >+ >+=cut >+ >+1; >diff --git a/Koha/Reading_suggestions.pm b/Koha/Reading_suggestions.pm >new file mode 100644 >index 0000000..93c7c14 >--- /dev/null >+++ b/Koha/Reading_suggestions.pm >@@ -0,0 +1,58 @@ >+package Koha::Reading_suggestions; >+ >+# Copiright Biblibre 2017 - Baptiste Wojtkowski >+# >+# 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, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+use Carp; >+use Koha::Database; >+use Koha::Reading_suggestion; >+use base qw(Koha::Objects); >+ >+=head1 NAME >+ >+Koha::Reading_suggestions - Koha Reading_suggestion object set class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'ReadingSuggestion'; >+} >+ >+=head3 object_class >+ >+=cut >+ >+sub object_class { >+ return 'Koha::Reading_suggestion'; >+} >+ >+=head1 AUTHOR >+ >+Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com> >+ >+=cut >+ >+1 >diff --git a/Koha/SharedContent.pm b/Koha/SharedContent.pm >index 7082fe0..d46a05c 100644 >--- a/Koha/SharedContent.pm >+++ b/Koha/SharedContent.pm >@@ -262,4 +262,458 @@ sub get_sharing_url { > return C4::Context->config('mana_config'); > } > >+=head2 get_identifier_field_marc >+ >+my ($fields_ref, $inds1_ref) = get_identifier_field_marc(); >+ >+Return two hash with the field and the first indicator for each identifier. >+ >+=cut >+ >+sub get_identifier_field_marc{ >+ #choose the field to select depending on marc flavour >+ my $marcflavour = C4::Context->preference("marcflavour"); >+ my %fields; >+ my %inds1; >+ if ($marcflavour eq "UNIMARC"){ >+ %fields = (isbn => "010", issn => "011", ismn => "013", isrn => "015", isrc => "016", upc => "072", ean => "073"); >+ %inds1 = (isbn => "", issn => "", ismn => "", isrn => "", isrc => "", upc => "", ean => ""); >+ } >+ else{ >+ #if nor UNIMARC, assume MARC21 >+ %fields = (isbn => "020", issn => "022", ismn => "024", isrn => "027", isrc => "024", upc => "024", ean => "024"); >+ %inds1 = (isbn => "", issn => "", ismn => " and \@ind1=\"2\"", isrn => "", isrc => " and \@ind1=\"0\"", upc => " and \@ind1=\"1\"", ean => " and \@ind1=\"3\""); >+ } >+ >+ return (\%fields, \%inds1); >+} >+ >+=head2 extract_reading_pairs >+ >+my @reading_pairs = extract_reading_pairs(); >+ >+Extract reading pairs from Koha Database. >+ >+=cut >+ >+sub extract_reading_pairs{ >+ my ($fields_ref, $inds1_ref) = get_identifier_field_marc(); >+ my %fields = %$fields_ref; >+ my %inds1 = %$inds1_ref; >+ >+ my $date=DateTime->now()->strftime("%F")."%"; >+ my $oldest_date=DateTime->now()->subtract(months => 6)->strftime("%F"); >+ >+ #define the max number of simultaneous issues for a single borrower >+ #if a sigle borrower have more issues than this, no pairs will be created for this borrower >+ #It is used to exlude huge borrower such as libraries or instution (because the issues won't have any connection) >+ my $current_issues_max = 50; >+ >+ my $dbh = C4::Context->dbh; >+ my $query_part1 = " >+ SELECT >+ issues1.borrowernumber as borrowernumber, >+ biblio_metadata1.biblionumber as biblionumber1, >+ biblio_metadata2.biblionumber as biblionumber2, >+ ExtractValue(biblio_metadata1.metadata, '//datafield[\@tag=\"$fields{isbn}\" $inds1{isbn}]/subfield[\@code=\"a\"]') as isbn1, >+ ExtractValue(biblio_metadata2.metadata, '//datafield[\@tag=\"$fields{isbn}\" $inds1{isbn}]/subfield[\@code=\"a\"]') as isbn2, >+ ExtractValue(biblio_metadata1.metadata, '//datafield[\@tag=\"$fields{issn}\" $inds1{issn}]/subfield[\@code=\"a\"]') as issn1, >+ ExtractValue(biblio_metadata2.metadata, '//datafield[\@tag=\"$fields{issn}\" $inds1{issn}]/subfield[\@code=\"a\"]') as issn2, >+ ExtractValue(biblio_metadata1.metadata, '//datafield[\@tag=\"$fields{ismn}\" $inds1{ismn}]/subfield[\@code=\"a\"]') as ismn1, >+ ExtractValue(biblio_metadata2.metadata, '//datafield[\@tag=\"$fields{ismn}\" $inds1{ismn}]/subfield[\@code=\"a\"]') as ismn2, >+ ExtractValue(biblio_metadata1.metadata, '//datafield[\@tag=\"$fields{isrn}\" $inds1{isrn}]/subfield[\@code=\"a\"]') as isrn1, >+ ExtractValue(biblio_metadata2.metadata, '//datafield[\@tag=\"$fields{isrn}\" $inds1{isrn}]/subfield[\@code=\"a\"]') as isrn2, >+ ExtractValue(biblio_metadata1.metadata, '//datafield[\@tag=\"$fields{isrc}\" $inds1{isrc}]/subfield[\@code=\"a\"]') as isrc1, >+ ExtractValue(biblio_metadata2.metadata, '//datafield[\@tag=\"$fields{isrc}\" $inds1{isrc}]/subfield[\@code=\"a\"]') as isrc2, >+ ExtractValue(biblio_metadata1.metadata, '//datafield[\@tag=\"$fields{upc}\" $inds1{upc}]/subfield[\@code=\"a\"]') as upc1, >+ ExtractValue(biblio_metadata2.metadata, '//datafield[\@tag=\"$fields{upc}\" $inds1{upc}]/subfield[\@code=\"a\"]') as upc2, >+ ExtractValue(biblio_metadata1.metadata, '//datafield[\@tag=\"$fields{ean}\" $inds1{ean}]/subfield[\@code=\"a\"]') as ean1, >+ ExtractValue(biblio_metadata2.metadata, '//datafield[\@tag=\"$fields{ean}\" $inds1{ean}]/subfield[\@code=\"a\"]') as ean2 >+ FROM >+ issues AS issues1 >+ JOIN >+ (SELECT borrowernumber FROM issues GROUP BY borrowernumber HAVING COUNT(*) < $current_issues_max) AS number ON number.borrowernumber=issues1.borrowernumber >+ JOIN >+ issues AS issues2 ON issues1.borrowernumber=issues2.borrowernumber >+ JOIN >+ items AS items1 ON issues1.itemnumber=items1.itemnumber >+ JOIN >+ biblio_metadata AS biblio_metadata1 ON items1.biblionumber=biblio_metadata1.biblionumber >+ JOIN >+ items AS items2 ON issues2.itemnumber=items2.itemnumber >+ JOIN >+ biblio_metadata AS biblio_metadata2 ON items2.biblionumber=biblio_metadata2.biblionumber >+ WHERE >+ issues1.issuedate LIKE ? >+ AND items1.biblionumber != items2.biblionumber >+ AND (DATE(issues1.issuedate) != DATE(issues2.issuedate) OR items1.biblionumber < items2.biblionumber) >+ AND (DATE(issues2.issuedate) > '$oldest_date') >+ AND biblio_metadata1.format='marcxml' >+ AND biblio_metadata2.format='marcxml' >+ "; >+ my $query_part2 = $query_part1; >+ $query_part2 =~ s/issues AS issues2/old_issues AS issues2/; >+ >+ # query_part1 match issues of the day with current issues >+ # query-part2 match issues of the day with old issues >+ my $query = $query_part1."UNION ALL".$query_part2; >+ >+ my $sth = $dbh->prepare( $query ); >+ $sth->execute($date, $date); >+ >+ my $row; >+ my @reading_pairs; >+ >+ #for each reading pair, processes the id pairs >+ while ( $row = $sth->fetchrow_hashref ){ >+ #if necessary, normalize the ids >+ $row->{isbn1} = Koha::Util::Normalize::NormalizeISBNs({ isbns => $row->{isbn1}, pattern => ' ', format => 'ISBN-13', strip_hyphens => 1 }) if $row->{isbn1}; >+ $row->{isbn2} = Koha::Util::Normalize::NormalizeISBNs({ isbns => $row->{isbn2}, pattern => ' ', format => 'ISBN-13', strip_hyphens => 1 }) if $row->{isbn2}; >+ $row->{issn1} = Koha::Util::Normalize::NormalizeISSNs({ issns => $row->{issn1}, pattern => ' ', strip_hyphens => 0 }) if $row->{issn1}; >+ $row->{issn2} = Koha::Util::Normalize::NormalizeISSNs({ issns => $row->{issn2}, pattern => ' ', strip_hyphens => 0 }) if $row->{issn2}; >+ $row->{ismn1} = Koha::Util::Normalize::NormalizeISMNs({ ismns => $row->{ismn1}, pattern => ' ', format => 'ISMN-13', strip_hyphens => 1 }) if $row->{ismn1}; >+ $row->{ismn2} = Koha::Util::Normalize::NormalizeISMNs({ ismns => $row->{ismn2}, pattern => ' ', format => 'ISMN-13', strip_hyphens => 1 }) if $row->{ismn2}; >+ $row->{isrc1} = Koha::Util::Normalize::NormalizeISRCs({ isrcs => $row->{isrc1}, pattern => ' ', strip_hyphens => 1 }) if $row->{isrc1}; >+ $row->{isrc2} = Koha::Util::Normalize::NormalizeISRCs({ isrcs => $row->{isrc2}, pattern => ' ', strip_hyphens => 1 }) if $row->{isrc2}; >+ $row->{isrn1} = Koha::Util::Normalize::NormalizeISRNs({ isrns => $row->{isrn1}, pattern => ' ', drop_local_suffix => 1 }) if $row->{isrn1}; >+ $row->{isrn2} = Koha::Util::Normalize::NormalizeISRNs({ isrns => $row->{isrn2}, pattern => ' ', drop_local_suffix => 1 }) if $row->{isrn2}; >+ >+ # try to make pairs between every id possible >+ foreach my $key1 ( qw ( isbn issn ismn isrn ean upc isrc ) ){ >+ if ( $row->{ $key1."1" }){ >+ my @id1_list = split(/ /, $row->{ $key1."1" }); >+ foreach my $key2 ( qw ( isbn issn ismn isrn ean upc isrc ) ){ >+ # if both selected ids exists >+ if ( $row->{ $key2."2" } ){ >+ my @id2_list = split(/ /, $row->{ $key2."2" }); >+ # make pairs between every ids of the given type >+ foreach my $id1 (@id1_list){ >+ foreach my $id2 (@id2_list){ >+ my $currentpair; >+ $currentpair->{ idtype1 } = $key1; >+ $currentpair->{ documentid1 } = $id1; >+ $currentpair->{ idtype2 } = $key2; >+ $currentpair->{ documentid2 } = $id2; >+ push @reading_pairs, $currentpair; >+ } >+ } >+ } >+ } >+ } >+ } >+ } >+ return @reading_pairs; >+} >+ >+=head2 get_identifiers >+ >+my ($idtype, $documentids) = get_identifiers($biblionumber); >+ >+Get all the identifiers of one type for the given biblio record (identified by it's biblionumber) >+ >+Retrun a string with the type of the ids and string with all the ids. >+ >+=cut >+ >+ >+sub get_identifiers { >+ my ($biblionumber) = @_; >+ >+ my $biblioitem = Koha::Biblioitems->find( $biblionumber ); >+ my $idtype; >+ my $documentid; >+ my $documentids; >+ my $found = 0; >+ >+ # Search in the biblioitem table witch can contain isbn, issn and ean >+ if ( $biblioitem && $biblioitem->isbn ){ >+ $idtype = "isbn"; >+ $documentids = Koha::Util::Normalize::NormalizeISBNs({ isbns => $biblioitem->isbn, pattern => ' \| ', format => 'ISBN-13', strip_hyphens => 1 }); >+ if ($documentids) { $found = 1; }; >+ } >+ elsif ( $biblioitem && $biblioitem->issn ){ >+ $idtype = "issn"; >+ $documentids = Koha::Util::Normalize::NormalizeISSNs({ issns => $biblioitem->issn, pattern => ' \| ', strip_hyphens => 0 }); >+ if ($documentids) { $found = 1; }; >+ } >+ elsif ( $biblioitem && $biblioitem->ean ){ >+ $idtype = "ean"; >+ $documentids = $biblioitem->ean; >+ $documentids =~ s/ \| / /; >+ if ($documentids) { $found = 1; }; >+ } >+ # Search in biblio_metadata table >+ if ($found == 0){ >+ my ($fields_ref, $inds1_ref) = get_identifier_field_marc(); >+ my %fields = %$fields_ref; >+ my %inds1 = %$inds1_ref; >+ >+ my $dbh = C4::Context->dbh; >+ my $query = " >+ SELECT >+ ExtractValue(metadata, '//datafield[\@tag=\"$fields{isbn}\"$inds1{isbn}]/subfield[\@code=\"a\"]') as isbn, >+ ExtractValue(metadata, '//datafield[\@tag=\"$fields{issn}\"$inds1{issn}]/subfield[\@code=\"a\"]') as issn, >+ ExtractValue(metadata, '//datafield[\@tag=\"$fields{ismn}\"$inds1{ismn}]/subfield[\@code=\"a\"]') as ismn, >+ ExtractValue(metadata, '//datafield[\@tag=\"$fields{isrn}\"$inds1{isrn}]/subfield[\@code=\"a\"]') as isrn, >+ ExtractValue(metadata, '//datafield[\@tag=\"$fields{isrc}\"$inds1{isrc}]/subfield[\@code=\"a\"]') as isrc, >+ ExtractValue(metadata, '//datafield[\@tag=\"$fields{upc}\"$inds1{upc}]/subfield[\@code=\"a\"]') as upc, >+ ExtractValue(metadata, '//datafield[\@tag=\"$fields{ean}\"$inds1{ean}]/subfield[\@code=\"a\"]') as ean >+ FROM biblio_metadata >+ WHERE biblionumber = ? >+ AND format=\"marcxml\" >+ "; >+ my $sth = $dbh->prepare( $query ); >+ $sth->execute($biblionumber); >+ my $row = $sth->fetchrow_hashref; >+ >+ if ($row->{isbn}){ >+ $idtype = "isbn"; >+ $documentids = Koha::Util::Normalize::NormalizeISBNs({ isbns => $row->{isbn}, pattern => ' ', format => 'ISBN-13', strip_hyphens => 1 }); >+ } >+ elsif ($row->{issn}){ >+ $idtype = "issn"; >+ $documentids = Koha::Util::Normalize::NormalizeISSNs({ issns => $row->{issn}, pattern => ' ', strip_hyphens => 0 }); >+ } >+ elsif ($row->{ismn}){ >+ $idtype = "ismn"; >+ $documentids = Koha::Util::Normalize::NormalizeISMNs({ ismns => $row->{ismn}, pattern => ' ', format => 'ISMN-13', strip_hyphens => 1 }); >+ } >+ elsif ($row->{isrn}){ >+ $idtype = "isrn"; >+ $documentids = Koha::Util::Normalize::NormalizeISRNs({isrns => $row->{isrn}, pattern => ' ', convert_slash => 1, drop_local_suffix => 1 }); >+ } >+ elsif ($row->{isrc}){ >+ $idtype = "isrc"; >+ $documentids = Koha::Util::Normalize::NormalizeISRCs({ isrcs => $row->{isrc}, pattern => ' ', strip_hyphens => 1 }) >+ } >+ elsif ($row->{upc}){ >+ $idtype = "upc"; >+ $documentids = $row->{upc}; >+ } >+ elsif ($row->{ean}){ >+ $idtype = "ean"; >+ $documentids = $row->{ean}; >+ } >+ } >+ if ($idtype && $documentids){ >+ return {code => 200, message => "OK", idtype => $idtype, documentids => $documentids}; >+ } >+ return {code => 404, message => "No usable id found"} >+} >+ >+=head2 ask_mana_reading_suggestion >+ >+my $response = ask_mana_reading_suggestion({ >+ documentid => $documentid, >+ idtype => $idtype, >+ offset => $offset, >+ length => $length >+}); >+ >+Construct a request for reading suggestion and send it to Mana. >+Retrun the response. >+ >+=cut >+ >+sub ask_mana_reading_suggestion { >+ my ($params) = @_; >+ my $documentid = $params->{documentid}; >+ my $idtype = $params->{idtype}; >+ my $offset = $params->{offset}; >+ my $length = $params->{length}; >+ >+ #request mana >+ my $mana_ip = C4::Context->config('mana_config'); >+ my $url = "$mana_ip/getsuggestion/$documentid/$idtype?offset=$offset&length=$length"; >+ my $request = HTTP::Request->new( GET => $url ); >+ $request->content_type('aplication/json'); >+ my $response = Koha::SharedContent::process_request( $request ); >+ >+ return $response; >+} >+ >+=head2 get_reading_suggestion >+ >+@biblios = Koha::SharedContent::get_reading_suggestion($biblionumber, $local_suggestions); >+ >+Get from Mana the reading suggestion for the given biblio record >+Store the suggestion in Koha >+Return them for display >+ >+=cut >+ >+sub get_reading_suggestion { >+ my ($biblionumber, $local_suggestions) = @_; >+ >+ my $result = get_identifiers( $biblionumber ); >+ if ($result->{code} != 200){ >+ return {code => $result->{code}, message => $result->{message}}; >+ }; >+ my $idtype = $result->{idtype}; >+ my $documentids = $result->{documentids}; >+ my $documentid = (split(/ /, $documentids, 2))[0]; >+ my $offset = 1; >+ my $length = 10; >+ my $mananotover; >+ my @biblios; >+ my @biblios_blessed; >+ my $added_biblionumbers; >+ >+ do{ >+ #request mana >+ my $response = ask_mana_reading_suggestion({ >+ documentid => $documentid, >+ idtype => $idtype, >+ offset => $offset, >+ length => $length >+ }); >+ >+ #error handling >+ my $resources = $response->{data}; >+ unless ( $resources ){ >+ my $msg = $response->{msg}; >+ my $code = $response->{code}; >+ if ( $code ){ >+ return {code => $response->{code}, message => $msg}; >+ } >+ else{ >+ return {code => 400, message => "Unknown error"}; >+ } >+ } >+ >+ if ( scalar @{ $resources } < $length ){ >+ $mananotover = 0; >+ } >+ else{ >+ $mananotover = 1; >+ } >+ >+ #create the list of owned suggested resources >+ my $ownedbiblioitem; >+ my $documentid2; >+ my $found = 0; >+ my $marcflavour = C4::Context->preference("marcflavour"); >+ my $ctr = 0; >+ my $resource = @{$resources}[$ctr]; >+ >+ # Treate each resources until we don't have any more resource or we found 10 resource >+ while ($resource && (scalar @biblios_blessed < 10 )){ >+ $found = 0; >+ >+ #isbn and issn can be search for with Koha::Biblioitems->search, ean too for unimarc but not for marc21 >+ if ($resource->{idtype} eq "isbn" || $resource->{idtype} eq "issn" || ($resource->{idtype} eq "ean" && $marcflavour eq "UNIMARC")){ >+ #isbn processsing >+ if ( $resource->{idtype} eq "isbn" ){ >+ $documentid2 = C4::Koha::NormalizeISBN({ isbn => $resource->{documentid}, format => 'ISBN-10', strip_hyphens => 1 }); >+ $ownedbiblioitem = Koha::Biblioitems->search({ $resource->{idtype} => $documentid2}) if $documentid2; >+ >+ #if we don't have such a biblioitem, we try to format else the isbn >+ unless ( scalar @{ $ownedbiblioitem->unblessed() } ){ >+ $documentid2 = C4::Koha::NormalizeISBN({ isbn => $resource->{documentid}, format => 'ISBN-13', strip_hyphens => 1 }); >+ $ownedbiblioitem = Koha::Biblioitems->search({ $resource->{idtype} => $documentid2}) if $documentid2; >+ } >+ >+ unless ( scalar @{ $ownedbiblioitem->unblessed() } ){ >+ $documentid2 = C4::Koha::NormalizeISBN({ isbn => $resource->{documentid}, format => 'ISBN-10', strip_hyphens => 0 }); >+ $ownedbiblioitem = Koha::Biblioitems->search({ $resource->{idtype} => $documentid2}) if $documentid2; >+ } >+ >+ unless ( scalar @{ $ownedbiblioitem->unblessed() } ){ >+ $documentid2 = C4::Koha::NormalizeISBN({ isbn => $resource->{documentid}, format => 'ISBN-13', strip_hyphens => 0 }); >+ $ownedbiblioitem = Koha::Biblioitems->search({ $resource->{idtype} => $documentid2}) if $documentid2; >+ } >+ } >+ >+ #issn and ean don't need special processing >+ elsif ($resource->{idtype} eq "issn" or $resource->{idtype} eq "ean"){ >+ $ownedbiblioitem = Koha::Biblioitems->search({ $resource->{idtype} => $resource->{documentid} }); >+ } >+ >+ #construct the tables with biblionumber >+ if (scalar @{ $ownedbiblioitem->unblessed() } ){ >+ $found = 1; >+ my $ownedbiblio = Koha::Biblios->find( @{ $ownedbiblioitem->unblessed() }[0]->{biblionumber} ); >+ #add the biblio if not already present >+ if ( not(exists($added_biblionumbers->{@{ $ownedbiblioitem->unblessed() }[0]->{biblionumber}})) ){ >+ push @biblios_blessed, $ownedbiblio; >+ push @biblios, $ownedbiblio->unblessed(); >+ $added_biblionumbers->{@{ $ownedbiblioitem->unblessed() }[0]->{biblionumber}}=1; >+ } >+ } >+ } >+ # if we don't have such a biblioitem, we try to look directly in metadata >+ # because if the document has multiple isbn they are store in biblioitem table like this >+ # "isbn1 | isbn2" and can't be found by biblioitems->seach >+ # other id need to be search with sql >+ if ($found != 1) { >+ my @params; >+ >+ my ($fields_ref, $inds1_ref) = get_identifier_field_marc(); >+ my %fields = %$fields_ref; >+ my %inds1 = %$inds1_ref; >+ >+ #pattern to be tolerent on the hyphens >+ my $pattern=""; >+ foreach my $p (split('', $resource->{documentid})){ >+ $pattern .= "$p-?"; >+ } >+ >+ my $dbh = C4::Context->dbh; >+ my $query = q{ >+ SELECT biblioitems.biblionumber as biblionumber >+ FROM biblioitems >+ LEFT JOIN biblio_metadata ON biblioitems.biblionumber=biblio_metadata.biblionumber >+ WHERE ExtractValue(biblio_metadata.metadata, '//datafield[@tag="}.$fields{$resource->{idtype}}.q{"}.$inds1{$resource->{idtype}}.q{]/subfield[@code="a"]') REGEXP "}.$pattern.q{" >+ AND biblio_metadata.format="marcxml" >+ }; >+ my $sth = $dbh->prepare( $query ); >+ $ownedbiblioitem = $sth->execute; >+ >+ #construct the tables with biblionumber >+ my $row = $sth->fetchrow_hashref; >+ if ( $row ){ >+ my $ownedbiblio = Koha::Biblios->find( $row->{biblionumber} ); >+ #add the biblio if not already present >+ if ( not(exists($added_biblionumbers->{$row->{biblionumber}})) ){ >+ push @biblios_blessed, $ownedbiblio; >+ push @biblios, $ownedbiblio->unblessed(); >+ $added_biblionumbers->{$row->{biblionumber}}=1; >+ } >+ } >+ } >+ >+ #prepare the next resource to be treated >+ $ctr++; >+ $resource = @{$resources}[$ctr]; >+ } >+ # Prepare the next requeste >+ # The number of requested resource is inversely proportionnal to the found_items/returned_items ratio, +1 is here just to avoid 0 >+ my $newlength = int( ( 10*( $length + $offset ) - $length ) / (scalar @biblios_blessed + 1 )); >+ if ( $newlength > 500 ){ >+ $newlength = 500; >+ } >+ $offset += $length; >+ $length = $newlength; >+ >+ } while( (scalar @biblios_blessed < 10 ) and $mananotover ); >+ >+ #preparing new suggestion for storing the result in koha >+ my $newSuggestion; >+ my $cter = scalar @biblios_blessed; >+ $cter = 10 unless ($cter < 10); >+ $newSuggestion->{ biblionumber } = $biblionumber; >+ while ( $cter > 0 ){ >+ if ( $biblios_blessed[ $cter-1 ] and $biblios_blessed[ $cter-1 ]->biblionumber){ >+ $newSuggestion->{ "biblionumber".$cter }=$biblios_blessed[ $cter-1 ]->biblionumber; >+ } >+ $cter--; >+ } >+ if ( $local_suggestions ){ >+ Koha::Reading_suggestions->find( $biblionumber )->delete(); >+ } >+ Koha::Reading_suggestion->new( $newSuggestion )->store; >+ >+ return {code => 200, message => "OK", data => \@biblios}; >+} >+ > 1; >diff --git a/Koha/Util/Normalize.pm b/Koha/Util/Normalize.pm >index f05999d..fe1a15d 100644 >--- a/Koha/Util/Normalize.pm >+++ b/Koha/Util/Normalize.pm >@@ -18,6 +18,7 @@ package Koha::Util::Normalize; > # along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; >+use Scalar::Util; > > use parent qw( Exporter ); > >@@ -27,6 +28,14 @@ our @EXPORT = qw( > upper_case > lower_case > ISBN >+ NormalizeISMN >+ NormalizeISRC >+ NormalizeISRN >+ NormalizeISBNs >+ NormalizeISSNs >+ NormalizeISMNs >+ NormalizeISRNs >+ NormalizeISRCs > ); > > =head1 NAME >@@ -121,11 +130,387 @@ sub ISBN { > return $isbn; > } > >+=head2 NormalizeISMN >+ >+Normalization function converting ISMN strings to ISMN13 >+my $ismn = NormalizeISMN({ >+ ismn => $ismn, >+ strip_hyphens => [0, 1], >+ format => ['ISMN-10', 'ISMN-13'] >+}); >+ >+=cut >+sub NormalizeISMN{ >+ my ( $params ) = @_; >+ >+ my $string = $params->{ismn}; >+ my $strip_hyphens = $params->{strip_hyphens}; >+ my $format = $params->{format} || q{}; >+ my $return_invalid = $params->{return_invalid}; >+ >+ return unless $string; >+ >+ my $ismn; >+ $string =~ s/^-*//; >+ $string =~ s/-*$//; >+ $string =~ s/--+/-/; >+ #test if the string seems valid >+ if (is_ismn($string)){ >+ $ismn = $string; >+ } >+ #if the string seems valid >+ if ($ismn){ >+ if ( $format eq 'ISMN-10' ) { >+ #grab the first digit, if it's an "9" then the format is ISMN-13 >+ my $first = substr $ismn, 0, 1; >+ #if the ismn is in ISMN-13 format >+ if ($first eq "9"){ >+ #replace the prefix of ISMN-10 by the prefix of ISMN-13 >+ length($ismn)==17 ? $ismn =~ s/979-0-/M-/ : $ismn =~ s/9790/M/; >+ } >+ } >+ elsif ($format eq 'ISMN-13' ) { >+ #grab the first digit, if it's an "M" then the format is ISMN-10 >+ my $first = substr $ismn, 0, 1; >+ #if the ismn is in ISMN-10 format >+ if ($first eq "M"){ >+ #replace the prefix of ISMN-10 by the prefix of ISMN-13 >+ length($ismn)==13 ? $ismn =~ s/M-/979-0-/ : $ismn =~ s/M/9790/; >+ } >+ } >+ if ($strip_hyphens) { >+ $ismn =~ s/-//g; >+ } >+ return $ismn; >+ } >+ elsif($return_invalid){ >+ return $string; >+ } >+ else { >+ return; >+ } >+} >+ >+=head2 is_ismn >+ >+Check if the string given looks like an ismn >+ >+=cut >+ >+sub is_ismn{ >+ my ( $string ) = @_; >+ >+ #check if length match the expected length of an ismn (with and withou hyphens) >+ return 0 unless ( (length($string)==10) or (length($string)==13) or (length($string)==14) or length($string)==17 ); >+ #check if the pattern look like an ismn >+ return 0 unless ( $string =~ m/^(((979-0-)|(M-))[0-9]{3,7}-[0-9]{1,5}-[0-9X])|((M|(9790))[0-9]{8}[0-9X])$/ ) ; >+ >+ return 1 >+} >+ >+=head2 NormalizeISRC >+ >+Normalization function removing hyphens >+my $isrc = NormalizeISRC({ >+ isrc => $isrc, >+ strip_hyphens => [0, 1] >+}); >+ >+=cut >+sub NormalizeISRC{ >+ my ( $params ) = @_; >+ >+ my $string = $params->{isrc}; >+ my $strip_hyphens = $params->{strip_hyphens}; >+ my $return_invalid = $params->{return_invalid}; >+ >+ return unless $string; >+ >+ my $isrc; >+ $string =~ s/^-*//; >+ $string =~ s/-*$//; >+ $string =~ s/--+/-/; >+ #test if the string seems valid >+ if (is_isrc($string)){ >+ $isrc = $string; >+ } >+ #if the string seems valid >+ if ($isrc){ >+ if ($strip_hyphens) { >+ $isrc =~ s/-//g; >+ } >+ return $isrc; >+ } >+ elsif($return_invalid){ >+ return $string; >+ } >+ else { >+ return; >+ } >+} >+ >+=head2 is_isrc >+ >+Check if the string given looks like an isrc >+ >+=cut >+ >+sub is_isrc{ >+ my ( $string ) = @_; >+ >+ #check if length match the expected length of an isrc (with and withou hyphens) >+ return 0 unless ( (length($string)==15) or (length($string)==12) ); >+ #check if the pattern look like an isrc >+ return 0 unless ( $string =~ m/^([A-Z]{2}-\w{3}-\w{2}-\w{5})|(([A-Z]{2}\w{10}))$/ ) ; >+ >+ return 1 >+} >+ >+=head2 NormalizeISRN >+ >+Normalization function removing hyphens >+my $isrn = NormalizeISRN({ >+ isrn => $isrn, >+ convert_slash, => [0, 1], >+ drop_local_suffix => [0, 1] >+}); >+ >+=cut >+sub NormalizeISRN{ >+ my ( $params ) = @_; >+ >+ my $string = $params->{isrn}; >+ my $convert_slash = $params->{convert_slash}; >+ my $drop_local_suffix = $params->{drop_local_suffix}; >+ my $return_invalid = $params->{return_invalid}; >+ >+ return unless $string; >+ >+ my $isrn; >+ $string =~ s/^-*//; >+ $string =~ s/-*$//; >+ #test if the string seems valid >+ if (is_isrn($string)){ >+ $isrn = $string; >+ } >+ #if the string seems valid >+ if ($isrn){ >+ if($convert_slash){ >+ $isrn =~ s/\//_/g; >+ } >+ if($drop_local_suffix){ >+ $isrn =~ s/\+.*$//; >+ } >+ return $isrn; >+ } >+ elsif($return_invalid){ >+ return $string; >+ } >+ else { >+ return; >+ } >+} >+ >+=head2 is_isrn >+ >+Check if the string given looks like an isrn >+ >+=cut >+ >+sub is_isrn{ >+ my ( $string ) = @_; >+ >+ my $truncated_string = $string; >+ $truncated_string =~ s/\+.*$//; >+ #check if length match the expected length of an isrn >+ return 0 unless ( length($truncated_string)<=36 ); >+ #check if the pattern look like an isrn >+ return 0 unless ( $string =~ m/^[A-Z](\w([\/-]\w+)?)*--(\d\d[\/-])?\d+([\/-]\w+)?(--[A-Z][A-Z])?(\+[A-Z0-9a-z,\.\/]+)?$/ ); >+ #check if each part has a valid length >+ $string =~ m/^([\w\/-]+)--([\d\/-]+[\w\/-]*)(--[A-Z][A-Z])?(\+[A-Za-z0-9,\.\/]+)?$/; >+ return 0 unless ( length($1)<=16 ); >+ return 0 unless ( length($2)<=14 ); >+ >+ return 1 >+} >+ > 1; >+ >+ >+=head2 NormalizeISBNs >+ >+Normalization function normalizing a string with a list of ISBNs seperated by a given pattern >+my $isbns = NormalizeISBNs({ >+ pattern => $pattern, >+ isbns => $isbns, >+ strip_hyphens => [0, 1] >+ format => ['ISBN-10', 'ISBN-13'] >+}); >+ >+=cut >+ >+sub NormalizeISBNs{ >+ my ( $params ) = @_; >+ >+ my $string = $params->{isbns}; >+ my $pattern = $params->{pattern}; >+ my $strip_hyphens = $params->{strip_hyphens}; >+ my $format = $params->{format} || q{}; >+ my $return_invalid = $params->{return_invalid}; >+ >+ if ($string){ >+ my @isbn_list = split(/$pattern/, $string); >+ my $result = ""; >+ foreach my $isbn (@isbn_list){ >+ my $normalized_isbn = C4::Koha::NormalizeISBN({ isbn => $isbn, format => $format, strip_hyphens => $strip_hyphens, return_invalid => $return_invalid }); >+ $result .= $normalized_isbn." " if ($normalized_isbn); >+ } >+ $result =~ s/ $//; >+ return $result; >+ } else { >+ return; >+ } >+} >+ >+=head2 NormalizeISSNs >+ >+Normalization function normalizing a string with a list of ISSNs seperated by a given pattern >+my $issns = NormalizeISSNs({ >+ issns => $issns, >+ pattern => $pattern, >+ strip_hyphens => [0, 1] >+}); >+ >+=cut >+ >+sub NormalizeISSNs{ >+ my ( $params ) = @_; >+ >+ my $string = $params->{issns}; >+ my $pattern = $params->{pattern}; >+ my $strip_hyphens = $params->{strip_hyphens}; >+ >+ if ($string){ >+ my @issn_list = split(/$pattern/, $string); >+ my $result = ""; >+ foreach my $issn (@issn_list){ >+ my $normalized_issn = C4::Koha::NormalizeISSN({ issn => $issn, strip_hyphen => $strip_hyphens }); >+ $result .= $normalized_issn." " if ($normalized_issn); >+ } >+ $result =~ s/ $//; >+ return $result; >+ } else { >+ return; >+ } >+} >+ >+=head2 NormalizeISMNs >+ >+Normalization function normalizing a string with a list of ISMNs seperated by a given pattern >+my $ismns = NormalizeISMNs({ >+ ismns => $ismns, >+ pattern => $pattern, >+ strip_hyphens => [0, 1] >+ format => ['ISMN-10', 'ISMN-13'] >+}); >+ >+=cut >+ >+sub NormalizeISMNs{ >+ my ( $params ) = @_; >+ >+ my $string = $params->{ismns}; >+ my $pattern = $params->{pattern}; >+ my $strip_hyphens = $params->{strip_hyphens}; >+ my $format = $params->{format} || q{}; >+ my $return_invalid = $params->{return_invalid}; >+ >+ if ($string){ >+ my @ismn_list = split(/$pattern/, $string); >+ my $result = ""; >+ foreach my $ismn (@ismn_list){ >+ my $normalized_ismn = Koha::Util::Normalize::NormalizeISMN({ ismn => $ismn, format => $format, strip_hyphens => $strip_hyphens, return_invalid => $return_invalid }); >+ $result .= $normalized_ismn." " if ($normalized_ismn); >+ } >+ $result =~ s/ $//; >+ return $result; >+ } else { >+ return; >+ } >+} >+ >+=head2 NormalizeISRCs >+ >+Normalization function normalizing a string with a list of ISRCs seperated by a given pattern >+my $isrcs = NormalizeISRCs({ >+ isrcs => $isrcs, >+ pattern => $pattern, >+ strip_hyphens => [0, 1] >+}); >+ >+=cut >+ >+sub NormalizeISRCs{ >+ my ( $params ) = @_; >+ >+ my $string = $params->{isrcs}; >+ my $pattern = $params->{pattern}; >+ my $strip_hyphens = $params->{strip_hyphens}; >+ my $return_invalid = $params->{return_invalid}; >+ >+ if ($string){ >+ my @isrc_list = split(/$pattern/, $string); >+ my $result = ""; >+ foreach my $isrc (@isrc_list){ >+ my $normalized_isrc = Koha::Util::Normalize::NormalizeISRC({ isrc => $isrc, strip_hyphens => $strip_hyphens, return_invalid => $return_invalid }); >+ $result .= $normalized_isrc." " if ($normalized_isrc); >+ } >+ $result =~ s/ $//; >+ return $result; >+ } else { >+ return; >+ } >+} >+ >+=head2 NormalizeISRNs >+ >+Normalization function normalizing a string with a list of ISRNs seperated by a given pattern >+my $isrns = NormalizeISRNs({ >+ isrns => $isrns, >+ pattern => $pattern, >+ convert_slash = [0, 1], >+ drop_local_suffix = [0, 1] >+}); >+ >+=cut >+ >+sub NormalizeISRNs{ >+ my ( $params ) = @_; >+ >+ my $string = $params->{isrns}; >+ my $pattern = $params->{pattern}; >+ my $drop_local_suffix = $params->{drop_local_suffix}; >+ my $convert_slash = $params->{convert_slash}; >+ my $return_invalid = $params->{return_invalid}; >+ >+ if ($string){ >+ my @isrn_list = split(/$pattern/, $string); >+ my $result = ""; >+ foreach my $isrn (@isrn_list){ >+ my $normalized_isrn = Koha::Util::Normalize::NormalizeISRN({ isrn => $isrn, drop_local_suffix => $drop_local_suffix, convert_slash => $convert_slash, return_invalid => $return_invalid }); >+ $result .= $normalized_isrn." " if ($normalized_isrn); >+ } >+ $result =~ s/ $//; >+ return $result; >+ } else { >+ return; >+ } >+} >+ >+ > __END__ > > =head1 AUTHOR >- > Koha Development Team <http://koha-community.org/> > > Tomas Cohen Arazi <tomascohen@theke.io> >diff --git a/installer/data/mysql/atomicupdate/mana_add_table_reading_pairs.sql b/installer/data/mysql/atomicupdate/mana_add_table_reading_pairs.sql >new file mode 100644 >index 0000000..eea656d >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/mana_add_table_reading_pairs.sql >@@ -0,0 +1,16 @@ >+-- biblionumber1 not null otherwise the data is useless >+CREATE TABLE `reading_suggestion` ( >+ `biblionumber` int(11) NOT NULL, >+ `biblionumber1` int(11) NOT NULL, >+ `biblionumber2` int(11) DEFAULT NULL, >+ `biblionumber3` int(11) DEFAULT NULL, >+ `biblionumber4` int(11) DEFAULT NULL, >+ `biblionumber5` int(11) DEFAULT NULL, >+ `biblionumber6` int(11) DEFAULT NULL, >+ `biblionumber7` int(11) DEFAULT NULL, >+ `biblionumber8` int(11) DEFAULT NULL, >+ `biblionumber9` int(11) DEFAULT NULL, >+ `biblionumber10` int(11) DEFAULT NULL, >+ `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, >+ PRIMARY KEY (`biblionumber`) >+); >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/mana/mana_suggestions.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/mana/mana_suggestions.tt >new file mode 100644 >index 0000000..5033a50 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/mana/mana_suggestions.tt >@@ -0,0 +1,40 @@ >+[% USE Koha %] >+[% IF suggestions %] >+ <table id="suggestions_tab" class="table table-bordered table-striped"> >+ <caption>[% issues_count %] Item(s) you should try</caption> >+ <thead> >+ <tr> >+ <th class="nosort">Cover Image</th> >+ <th class="anti-the">Title</th> >+ <th>Author</th> >+ <th>Publisher</th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH suggestion IN suggestions %] >+ <tr> >+ <td class="jacketcell"> >+ [% IF ( Koha.Preference('OPACAmazonCoverImages') ) %] >+ >+ [% IF ( suggestion.normalized_isbn() ) %] >+ <a href="http://www.amazon.com/gp/reader/[% suggestion.normalized_isbn() %]/ref=sib_dp_pt/002-7879865-0184864#reader-link" title="View on Amazon.com"><img src="https://images-na.ssl-images-amazon.com/images/P/[% suggestion.normalized_isbn() %].01.THUMBZZZ.jpg" alt="View on Amazon.com" class="item-thumbnail"/></a> >+ [% ELSE %] >+ <a href="#"><span class="no-image">No cover image available</span></a> >+ [% END %] >+ [% END %] >+ </td> >+ <td class="title"> >+ <a class="title" href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% suggestion.biblionumber %]">[% suggestion.title |html %] [% FOREACH subtitl IN suggestion.subtitles %] [% subtitl.subfield %][% END %]</a> >+ </td> >+ <td class="author">[% suggestion.author %]</td> >+ </td> >+ <td class="publisher"> >+ <span class="publisher">[% suggestion.biblioitem.publishercode %]</td> >+ </td> >+ </tr> >+ [% END # /FOREACH suggestions %] >+ </tbody> >+ </table> >+[% ELSE %] >+ <h1> There are no available suggestions on mana KB </h1> >+[% END # IF suggestions %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt >index a14c1e3..7c18298 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt >@@ -589,6 +589,9 @@ > [% IF ( defaulttab == 'media' ) %]<li id="tab_html5media" class="ui-tabs-active">[% ELSE %]<li id="tab_html5media">[% END %]<a href="#html5media">Play media</a></li> > [% END %] > >+ [% IF Koha.Preference( 'Mana' ) == 1 %] >+ <li id="tab_suggestions"><a href="#reading_suggestions">Suggestion </a></li> >+ [% END %] > </ul> > > [% IF ( serialcollection ) %] >@@ -881,6 +884,11 @@ > </div> > [% END # / IF LibraryThingForLibrariesID && LibraryThingForLibrariesTabbedView %] > >+ [% IF Koha.Preference( 'Mana' ) == 1 %] >+ <div id="reading_suggestions"> >+ </div> >+ [% END # / IF Koha.Preference( 'Mana') ==1 %] >+ > [% IF Koha.Preference( 'OPACComments' ) == 1 %] > <div id="comments"> > <div id="newcomment"></div> >@@ -1851,4 +1859,24 @@ > > } > </script> >+ [% IF Koha.Preference('Mana') %] >+ <script> >+ $("#reading_suggestions").html(""); >+ $(document).ready( function(){ >+ $( "#tab_suggestions" ).one( "click", function(){ >+ $.ajax({ >+ type: "POST", >+ url: "/cgi-bin/koha/svc/mana/getSuggestion", >+ data: { biblionumber : [% biblionumber %] }, >+ dataType: "html", >+ } ).done( function( data ) { >+ $( "#reading_suggestions" ).html(data) >+ } ).fail( function( error, msg, longmsg ) { >+ $( "#reading_suggestions" ).html( "<h1> An error occured: unknown error </h1>" ) >+ } ); >+ }); >+ }); >+ </script> >+ [% END %] >+ > [% END %] >diff --git a/misc/cronjobs/mana_send_pairs.pl b/misc/cronjobs/mana_send_pairs.pl >new file mode 100644 >index 0000000..bb97442 >--- /dev/null >+++ b/misc/cronjobs/mana_send_pairs.pl >@@ -0,0 +1,48 @@ >+#/!usr/bin/perl >+use Modern::Perl; >+ >+use C4::Context; >+use Getopt::Long; >+use Koha; >+use C4::Koha; >+use Koha; >+use Koha::Util::Normalize q/NormalizeISMN/; >+ >+use JSON; >+use HTTP::Request; >+use Koha::SharedContent; >+ >+my $help = 0; >+ >+GetOptions( >+ 'help|?' => \$help, >+); >+ >+if ($help){ >+ print "This script is used to send reading pairs to Mana KB.\nReading pairs are automatically extracted from Koha database.\n"; >+ exit; >+}; >+ >+#if mana is activated >+if (C4::Context->preference("Mana") == 1){ >+ my @reading_pairs = Koha::SharedContent::extract_reading_pairs(); >+ my $content; >+ >+ #informations for mana >+ my $MANA_IP=C4::Context->config("mana_config"); >+ >+ my $securitytoken = C4::Context->preference('ManaToken'); >+ $content->{ securitytoken } = $securitytoken; >+ $content->{ reading_pairs } = \@reading_pairs; >+ >+ my $url = "$MANA_IP/bulk/reading_pair.json"; >+ my $request = HTTP::Request->new( POST => $url ); >+ >+ my $json = to_json( $content, { utf8 => 1 } ); >+ #print $json; >+ >+ #send to mana >+ $request->content($json); >+ my $result = Koha::SharedContent::process_request( $request ); >+ #print Data::Dumper::Dumper( $result ); >+} >diff --git a/opac/svc/mana/getSuggestion b/opac/svc/mana/getSuggestion >new file mode 100755 >index 0000000..0f6d9e3 >--- /dev/null >+++ b/opac/svc/mana/getSuggestion >@@ -0,0 +1,103 @@ >+#!/usr/bin/perl >+ >+# Copyright 2017 BibLibre Baptiste Wojtkowski >+# >+# 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 <http://www.gnu.org/licenses>. >+# >+ >+use Modern::Perl; >+use Koha::SharedContent; >+use Koha::Biblioitems; >+use Koha::Biblioitem; >+use Koha::Reading_suggestions; >+use Koha::Reading_suggestion; >+use Koha::Util::Normalize q/NormalizeISMN/; >+ >+use Koha; >+use C4::Koha; >+use C4::Context; >+use C4::Auth qw(check_cookie_auth), qw(get_template_and_user); >+ >+use List::MoreUtils qw(uniq); >+ >+use CGI; >+use JSON; >+ >+use DateTime; >+use DateTime::Format::MySQL; >+use DateTime::Duration; >+ >+use constant DURATION_BEFORE_REFRESH => DateTime::Duration->new( weeks => 1 ); >+use C4::Output qw( output_with_http_headers ); >+my $input = CGI->new; >+binmode STDOUT, ":encoding(UTF-8)"; >+ >+ >+ >+ >+my $biblionumber = $input->param( "biblionumber" ); >+ >+#case we come with the script import_suggestions.pl >+my $temp_biblionumber; >+eval { $temp_biblionumber = from_json( $input->param( "POSTDATA" ) )->{biblionumber}; }; >+if ( $temp_biblionumber ){ >+ $biblionumber = $temp_biblionumber; >+} >+ >+my $local_suggestions; >+ >+my $now; >+my $timestamp; >+my $duration; >+#check it doesn't already have the informations localy stored >+eval { >+ $local_suggestions = Koha::Reading_suggestions->find( $biblionumber )->unblessed(); >+ $now = DateTime->now(); >+ $timestamp = DateTime::Format::MySQL->parse_timestamp( $local_suggestions->{timestamp} ); >+ $duration = $now - $timestamp; >+}; >+my @biblios; >+my $biblios_ref; >+if ( $local_suggestions and DateTime::Duration->compare( $duration, DURATION_BEFORE_REFRESH ) == -1 ){ >+ delete $local_suggestions->{timestamp}; >+ delete $local_suggestions->{biblionumber}; >+ foreach my $key ( sort keys %{ $local_suggestions }){ >+ my $biblio = Koha::Biblios->find( $local_suggestions->{ $key } ); >+ push @biblios, $biblio->unblessed() if $biblio; >+ } >+ $biblios_ref = \@biblios; >+} >+ >+else{ >+ my $result = Koha::SharedContent::get_reading_suggestion($biblionumber, $local_suggestions); >+ if ($result->{code} == 200){ >+ $biblios_ref = $result->{data}; >+ }; >+} >+ >+my ( $template, $loggedinuser, $cookie ) = get_template_and_user( >+ { >+ template_name => "mana/mana_suggestions.tt", >+ query => $input, >+ type => "opac", >+ authnotrequired => 1, >+ debug => 1, >+ } >+); >+$template->param( JacketImage => 1); >+$template->param( suggestions => $biblios_ref ); >+ >+output_with_http_headers $input, $cookie, $template->output, 'json'; >diff --git a/t/Koha/Util/Normalize.t b/t/Koha/Util/Normalize.t >index 317ad8c..b7966fa 100755 >--- a/t/Koha/Util/Normalize.t >+++ b/t/Koha/Util/Normalize.t >@@ -17,15 +17,16 @@ > > use Modern::Perl; > >-use Test::More tests => 6; >+use Test::More tests => 14; > use Test::Warn; >+use C4::Koha; > > BEGIN { > use_ok('Koha::Util::Normalize'); > } > > subtest 'pass undef' => sub { >- plan tests => 8; >+ plan tests => 24; > > is( legacy_default(), undef, 'legacy_default returns undef' ); > warning_is { legacy_default() } undef, 'no warn from legacy_default'; >@@ -38,6 +39,30 @@ subtest 'pass undef' => sub { > > is( lower_case(), undef, 'lower_case returns undef' ); > warning_is { lower_case() } undef, 'no warn from lower_case'; >+ >+ is( NormalizeISMN(), undef, 'NormalizeISMN returns undef' ); >+ warning_is { NormalizeISMN() } undef, 'no warn from NormalizeISMN'; >+ >+ is( NormalizeISRC(), undef, 'NormalizeISRC returns undef' ); >+ warning_is { NormalizeISRC() } undef, 'no warn from NormalizeISRC'; >+ >+ is( NormalizeISRN(), undef, 'NormalizeISRN returns undef' ); >+ warning_is { NormalizeISRN() } undef, 'no warn from NormalizeISRN'; >+ >+ is( NormalizeISBNs(), undef, 'NormalizeISBNs returns undef' ); >+ warning_is { NormalizeISBNs() } undef, 'no warn from NormalizeISBNs'; >+ >+ is( NormalizeISSNs(), undef, 'NormalizeISSNs returns undef' ); >+ warning_is { NormalizeISSNs() } undef, 'no warn from NormalizeISSNs'; >+ >+ is( NormalizeISMNs(), undef, 'NormalizeISMNs returns undef' ); >+ warning_is { NormalizeISMNs() } undef, 'no warn from NormalizeISMNs'; >+ >+ is( NormalizeISRNs(), undef, 'NormalizeISRNs returns undef' ); >+ warning_is { NormalizeISRNs() } undef, 'no warn from NormalizeISRNs'; >+ >+ is( NormalizeISRCs(), undef, 'NormalizeISRCs returns undef' ); >+ warning_is { NormalizeISRCs() } undef, 'no warn from NormalizeISRCs'; > }; > > >@@ -82,3 +107,277 @@ subtest 'lower_case() normalizer' => sub { > 'The \'lower_case\' normalizer only makes characters lower-case' ); > }; > >+subtest 'NormalizeISMN() normalizer' => sub { >+ >+ plan tests => 25; >+ >+ my $string = '979-0-2600-0043-8'; >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-13' } ), '979-0-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-13 from an ISMN-13' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-13' } ), '9790260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-13 from and ISMN-13' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-10' } ), 'M-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-10 from an ISMN-13' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-10' } ), 'M260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-10 from an ISMN-13' ); >+ >+ $string = 'M-2600-0043-8'; >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-13' } ), '979-0-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-13 from an ISMN-10' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-13' } ), '9790260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-13 from and ISMN-10' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-10' } ), 'M-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-10 from an ISMN-10' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-10' } ), 'M260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-10 from an ISMN-10' ); >+ >+ $string = ' .; kY[]:, (l)/E\'"'; >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-13' } ), undef, >+ 'NormalizeISMN correctly return undef is the parameter does not look like an ISMN' ); >+ >+ $string = '979-0-2600-0043-X'; >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-13' } ), '979-0-2600-0043-X', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-13 from an ISMN-10 : edge case checksum=X' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-13' } ), '979026000043X', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-13 from and ISMN-10 : edge case checksum=X' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-10' } ), 'M-2600-0043-X', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-10 from an ISMN-10 : edge case checksum=X' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-10' } ), 'M26000043X', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-10 from an ISMN-10 : edge case checksum=X' ); >+ >+ $string = '979-0-2600-0043-8-'; >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-13' } ), '979-0-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-13 from an ISMN-10 : edge case trailing -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-13' } ), '9790260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-13 from and ISMN-10 : edge case trailing -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-10' } ), 'M-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-10 from an ISMN-10 : edge case trailing -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-10' } ), 'M260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-10 from an ISMN-10 : edge case trailing -' ); >+ >+ $string = '-979-0-2600-0043-8'; >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-13' } ), '979-0-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-13 from an ISMN-10 : edge case leading -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-13' } ), '9790260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-13 from and ISMN-10 : edge case leading -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-10' } ), 'M-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-10 from an ISMN-10 : edge case leading -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-10' } ), 'M260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-10 from an ISMN-10 : edge case leading -' ); >+ >+ $string = '979-0-2600-0043--8'; >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-13' } ), '979-0-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-13 from an ISMN-10 : edge case double -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-13' } ), '9790260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-13 from and ISMN-10 : edge case double -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 0, format => 'ISMN-10' } ), 'M-2600-0043-8', >+ 'NormalizeISMN correctly leave hyphens and correctly format the ISMN-10 from an ISMN-10 : edge case double -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMN( { ismn => $string, strip_hyphens => 1, format => 'ISMN-10' } ), 'M260000438', >+ 'NormalizeISMN correctly strip hyphens and correctly format the ISMN-10 from an ISMN-10 : edge case double -' ); >+}; >+ >+subtest 'NormalizeISRC() normalizer' => sub { >+ >+ plan tests => 9; >+ >+ my $string = 'FR-R09-12-40970'; >+ >+ is( Koha::Util::Normalize::NormalizeISRC( { isrc => $string, strip_hyphens => 0 } ), 'FR-R09-12-40970', >+ 'NormalizeISRC correctly leave hyphens' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRC( { isrc => $string, strip_hyphens => 1 } ), 'FRR091240970', >+ 'NormalizeISRC correctly strip hyphens' ); >+ >+ $string = ' .; kY[]:, (l)/E\'"'; >+ is( Koha::Util::Normalize::NormalizeISRC( { isrc => $string, strip_hyphens => 1 } ), undef, >+ 'NormalizeISRC correctly return undef is the parameter does not look like an ISRC' ); >+ >+ $string = 'FR-R09-12--40970'; >+ is( Koha::Util::Normalize::NormalizeISRC( { isrc => $string, strip_hyphens => 1 } ), 'FRR091240970', >+ 'NormalizeISRC correctly return the ISRC without hyphens : edge case double -' ); >+ >+ $string = 'FR-R09--12-40970'; >+ is( Koha::Util::Normalize::NormalizeISRC( { isrc => $string, strip_hyphens => 0 } ), 'FR-R09-12-40970', >+ 'NormalizeISRC correctly return the ISRC with hyphens : edge case leading -' ); >+ >+ $string = 'FR-R09-12-40970-'; >+ is( Koha::Util::Normalize::NormalizeISRC( { isrc => $string, strip_hyphens => 1 } ), 'FRR091240970', >+ 'NormalizeISRC correctly return the ISRC without hyphens : edge case trailing -' ); >+ >+ $string = '-FR-R09-12-40970'; >+ is( Koha::Util::Normalize::NormalizeISRC( { isrc => $string, strip_hyphens => 0 } ), 'FR-R09-12-40970', >+ 'NormalizeISRC correctly return the ISRC with hyphens : edge case leading -' ); >+ >+ $string = '-FR-R09-12-40970'; >+ is( Koha::Util::Normalize::NormalizeISRC( { isrc => $string, strip_hyphens => 1 } ), 'FRR091240970', >+ 'NormalizeISRC correctly return the ISRC without hyphens : edge case leading -' ); >+ >+ $string = '-FR-R09-12-40970'; >+ is( Koha::Util::Normalize::NormalizeISRC( { isrc => $string, strip_hyphens => 0 } ), 'FR-R09-12-40970', >+ 'NormalizeISRC correctly return the ISRC with hyphens : edge case leading -' ); >+ >+ >+}; >+ >+subtest 'NormalizeISRN() normalizer' => sub { >+ >+ plan tests => 14; >+ >+ my $string = 'METPRO/CB/TR--74/216+PR.ENVR.WI'; >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 0, drop_local_suffix => 0 } ), 'METPRO/CB/TR--74/216+PR.ENVR.WI', >+ 'NormalizeISRN correctly leave slash and correclty leave local suffix' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 1, drop_local_suffix => 0 } ), 'METPRO_CB_TR--74_216+PR.ENVR.WI', >+ 'NormalizeISRC correctly convert slash and correctly leave local suffix' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 0, drop_local_suffix => 1 } ), 'METPRO/CB/TR--74/216', >+ 'NormalizeISRC correctly leave slash and correctly drop local suffix' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 1, drop_local_suffix => 1 } ), 'METPRO_CB_TR--74_216', >+ 'NormalizeISRC correctly convert slash and correctly drop local suffix' ); >+ >+ $string = ' .; kY[]:, (l)/E\'"'; >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 0, drop_local_suffix => 1 } ), undef, >+ 'NormalizeISRC correctly return undef is the parameter does not look like an ISRN' ); >+ >+ $string = '-METPRO/CB/TR--74/216+PR.ENVR.WI'; >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 0, drop_local_suffix => 0 } ), 'METPRO/CB/TR--74/216+PR.ENVR.WI', >+ 'NormalizeISRN correctly leave slash and correclty leave local suffix : edge case leading -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 1, drop_local_suffix => 0 } ), 'METPRO_CB_TR--74_216+PR.ENVR.WI', >+ 'NormalizeISRC correctly convert slash and correctly leave local suffix : edge case leading -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 0, drop_local_suffix => 1 } ), 'METPRO/CB/TR--74/216', >+ 'NormalizeISRC correctly leave slash and correctly drop local suffix : edge case leading -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 1, drop_local_suffix => 1 } ), 'METPRO_CB_TR--74_216', >+ 'NormalizeISRC correctly convert slash and correctly drop local suffix : edge case leading -' ); >+ >+ >+ $string = 'METPRO/CB/TR--74/216+PR.ENVR.WI-'; >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 0, drop_local_suffix => 0 } ), 'METPRO/CB/TR--74/216+PR.ENVR.WI', >+ 'NormalizeISRN correctly leave slash and correclty leave local suffix : edge case trailing -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 1, drop_local_suffix => 0 } ), 'METPRO_CB_TR--74_216+PR.ENVR.WI', >+ 'NormalizeISRC correctly convert slash and correctly leave local suffix : edge case trailing -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 0, drop_local_suffix => 1 } ), 'METPRO/CB/TR--74/216', >+ 'NormalizeISRC correctly leave slash and correctly drop local suffix : edge case trailing -' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 1, drop_local_suffix => 1 } ), 'METPRO_CB_TR--74_216', >+ 'NormalizeISRC correctly convert slash and correctly drop local suffix : edge case trailing -' ); >+ >+ >+ $string = 'METPRO/CB/TR---74/216+PR.ENVR.WI'; >+ is( Koha::Util::Normalize::NormalizeISRN( { isrn => $string, convert_slash => 0, drop_local_suffix => 1 } ), undef, >+ 'NormalizeISRC correctly return undef is the parameter does not look like an ISRN : edge case triple -' ); >+ >+}; >+ >+subtest 'NormalizeISBNs() normalizer' => sub { >+ >+ plan tests => 4; >+ >+ my $string = '9782379891113 | 978-0-321-49694-2 | 4274 | 2379891117 | 0-321-49694-9 | 542'; >+ >+ is( Koha::Util::Normalize::NormalizeISBNs( { isbns => $string, pattern => ' \| ', strip_hyphens => 0, format => 'ISBN-13' } ), '978-2-37989-111-3 978-0-321-49694-2 978-2-37989-111-3 978-0-321-49694-2', >+ 'NormalizeISBNs correctly normalize all id, leave hyphens and format ISBN-13' ); >+ >+ is( Koha::Util::Normalize::NormalizeISBNs( { isbns => $string, pattern => ' \| ', strip_hyphens => 1, format => 'ISBN-13' } ), '9782379891113 9780321496942 9782379891113 9780321496942', >+ 'NormalizeISBNs correctly normalize all id, strip hyphens and format ISBN-13' ); >+ >+ is( Koha::Util::Normalize::NormalizeISBNs( { isbns => $string, pattern => ' \| ', strip_hyphens => 0, format => 'ISBN-10' } ), '2-37989-111-7 0-321-49694-9 2-37989-111-7 0-321-49694-9', >+ 'NormalizeISBNs correctly normalize all id, leave hyphens and format ISBN-10' ); >+ >+ is( Koha::Util::Normalize::NormalizeISBNs( { isbns => $string, pattern => ' \| ', strip_hyphens => 1, format => 'ISBN-10' } ), '2379891117 0321496949 2379891117 0321496949', >+ 'NormalizeISBNs correctly normalize all id, strip hyphens and format ISBN-10' ); >+ >+}; >+ >+subtest 'NormalizeISSNs() normalizer' => sub { >+ >+ plan tests => 2; >+ >+ my $string = '03354725 | 1445 | 0220-1186 | 542'; >+ >+ is( Koha::Util::Normalize::NormalizeISSNs( { issns => $string, pattern => ' \| ', strip_hyphens => 0 } ), '0335-4725 0220-1186', >+ 'NormalizeISSNs correctly normalize all id, leave hyphens' ); >+ >+ is( Koha::Util::Normalize::NormalizeISSNs( { issns => $string, pattern => ' \| ', strip_hyphens => 1 } ), '03354725 02201186', >+ 'NormalizeISSNs correctly normalize all id, strip hyphens' ); >+}; >+ >+subtest 'NormalizeISMNs() normalizer' => sub { >+ >+ plan tests => 4; >+ >+ my $string = 'M-2309-7938-2 | 979-0-2309-7938-2 | 54 | M230971010 | 9790230971010 | 542'; >+ >+ is( Koha::Util::Normalize::NormalizeISMNs( { ismns => $string, pattern => ' \| ', strip_hyphens => 0, format => 'ISMN-13' } ), '979-0-2309-7938-2 979-0-2309-7938-2 9790230971010 9790230971010', >+ 'NormalizeISMNs correctly normalize all id, leave hyphens and format ISMN-13' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMNs( { ismns => $string, pattern => ' \| ', strip_hyphens => 1, format => 'ISMN-13' } ), '9790230979382 9790230979382 9790230971010 9790230971010', >+ 'NormalizeISMNs correctly normalize all id, strip hyphens and format ISMN-13' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMNs( { ismns => $string, pattern => ' \| ', strip_hyphens => 0, format => 'ISMN-10' } ), 'M-2309-7938-2 M-2309-7938-2 M230971010 M230971010', >+ 'NormalizeISMNs correctly normalize all id, leave hyphens and format ISMN-10' ); >+ >+ is( Koha::Util::Normalize::NormalizeISMNs( { ismns => $string, pattern => ' \| ', strip_hyphens => 1, format => 'ISMN-10' } ), 'M230979382 M230979382 M230971010 M230971010', >+ 'NormalizeISMNs correctly normalize all id, strip hyphens and format ISMN-10' ); >+ >+}; >+ >+subtest 'NormalizeISRCs() normalizer' => sub { >+ >+ plan tests => 2; >+ >+ my $string = 'FR-R09-12-40970 | 585 | FR6042000056 | 564'; >+ >+ is( Koha::Util::Normalize::NormalizeISRCs( { isrcs => $string, pattern => ' \| ', strip_hyphens => 0 } ), 'FR-R09-12-40970 FR6042000056', >+ 'NormalizeISRCs correctly normalize all id, leave hyphens' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRCs( { isrcs => $string, pattern => ' \| ', strip_hyphens => 1 } ), 'FRR091240970 FR6042000056', >+ 'NormalizeISRCs correctly normalize all id, strip hyphens' ); >+ >+}; >+ >+subtest 'NormalizeISRNs() normalizer' => sub { >+ >+ plan tests => 4; >+ >+ my $string = 'METPRO/CB/TR--74/216+PR.ENVR.WI | 4536er | COUCOU/ICI--00-45 | 542'; >+ >+ is( Koha::Util::Normalize::NormalizeISRNs( { isrns => $string, pattern => ' \| ', convert_slash => 0, drop_local_suffix => 0 } ), 'METPRO/CB/TR--74/216+PR.ENVR.WI COUCOU/ICI--00-45', >+ 'NormalizeISRNs correctly normalize all id, leave slash, leave local suffix' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRNs( { isrns => $string, pattern => ' \| ', convert_slash => 0, drop_local_suffix => 1 } ), 'METPRO/CB/TR--74/216 COUCOU/ICI--00-45', >+ 'NormalizeISMNs correctly normalize all id, leave slash, drop local suffix' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRNs( { isrns => $string, pattern => ' \| ', convert_slash => 1, drop_local_suffix => 0 } ), 'METPRO_CB_TR--74_216+PR.ENVR.WI COUCOU_ICI--00-45', >+ 'NormalizeISMNs correctly normalize all id, convert slash, leave local suffix' ); >+ >+ is( Koha::Util::Normalize::NormalizeISRNs( { isrns => $string, pattern => ' \| ', convert_slash => 1, drop_local_suffix => 1 } ), 'METPRO_CB_TR--74_216 COUCOU_ICI--00-45', >+ 'NormalizeISMNs correctly normalize all id, convert slash, drop local suffix' ); >+ >+}; >diff --git a/t/db_dependent/Koha/SharedContent.t b/t/db_dependent/Koha/SharedContent.t >index fab02d4..0ce6212 100755 >--- a/t/db_dependent/Koha/SharedContent.t >+++ b/t/db_dependent/Koha/SharedContent.t >@@ -1,5 +1,3 @@ >-#!/usr/bin/perl >- > # Copyright 2016 BibLibre Morgane Alonso > # > # This file is part of Koha >@@ -23,10 +21,14 @@ use t::lib::TestBuilder; > use t::lib::Mocks; > use Test::MockModule; > use Test::MockObject; >-use Test::More tests => 45; >+use Test::More tests => 49; >+use Test::Exception; > use Koha::Database; > use Koha::Patrons; > use Koha::Subscriptions; >+use Koha::DateUtils qw(dt_from_string); >+use Koha::Util::Normalize; >+use Koha::Reading_suggestions; > > use HTTP::Status qw(:constants :is status_message); > >@@ -42,7 +44,6 @@ my $post_request = 0; > my $query = {}; > > t::lib::Mocks::mock_config( 'mana_config', 'https://foo.bar'); >- > is(Koha::SharedContent::get_sharing_url(), 'https://foo.bar', 'Mana URL'); > > my $result = Koha::SharedContent::search_entities('report', $query); >@@ -240,4 +241,673 @@ is($query{resource}, 'subscription', 'Check ressource'); > > is($request->uri->path, '/subscription/12.json/increment/foo', 'Path is subscription'); > >+# Reading pair. >+my $record1 = MARC::Record->new(); >+my $record2 = MARC::Record->new(); >+my $record3 = MARC::Record->new(); >+my $record4 = MARC::Record->new(); >+ >+my $id1 = '9783161484100'; >+my $id2 = '9780321496942'; >+my $id3 = '9780914378266'; >+my $id4 = '9780491001304'; >+ >+my $field1 = MARC::Field->new('020','','','a' => $id1); >+my $field2 = MARC::Field->new('020','','','a' => $id2); >+my $field3 = MARC::Field->new('020','','','a' => $id3); >+my $field4 = MARC::Field->new('020','','','a' => $id4); >+ >+$record1->append_fields( $field1 ); >+$record2->append_fields( $field2 ); >+$record3->append_fields( $field3 ); >+$record4->append_fields( $field4 ); >+ >+my %biblionumbers; >+my ($biblionumber1) = C4::Biblio::AddBiblio($record1, ''); >+$biblionumbers{biblio1} = $biblionumber1; >+my ($biblionumber2) = C4::Biblio::AddBiblio($record2, ''); >+$biblionumbers{biblio2} = $biblionumber2; >+my ($biblionumber3) = C4::Biblio::AddBiblio($record3, ''); >+$biblionumbers{biblio3} = $biblionumber3; >+my ($biblionumber4) = C4::Biblio::AddBiblio($record4, ''); >+$biblionumbers{biblio4} = $biblionumber4; >+ >+my $biblio1 = Koha::Biblios->find( $biblionumber1 ); >+my $biblio2 = Koha::Biblios->find( $biblionumber2 ); >+my $biblio3 = Koha::Biblios->find( $biblionumber3 ); >+my $biblio4 = Koha::Biblios->find( $biblionumber4 ); >+ >+my $item1_0 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio1->biblionumber >+ } >+}); >+my $item1_1 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio1->biblionumber >+ } >+}); >+my $item1_2 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio1->biblionumber >+ } >+}); >+my $item1_3 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio1->biblionumber >+ } >+}); >+my $item1_4 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio1->biblionumber >+ } >+}); >+my $item1_5 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio1->biblionumber >+ } >+}); >+my $item2_0 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio2->biblionumber >+ } >+}); >+my $item3_0 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio3->biblionumber >+ } >+}); >+my $item4_0 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio4->biblionumber >+ } >+}); >+my $item3_1 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio3->biblionumber >+ } >+}); >+ >+my $item4_1 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblio4->biblionumber >+ } >+}); >+ >+ >+my $now=DateTime->now()->strftime('%F'); >+my $yesterday = DateTime->now()->add(days => -1)->strftime('%F'); >+ >+my $issue1 = $builder->build({source => 'Issue', value => { >+ itemnumber => $item1_0->{itemnumber}, >+ issuedate => $now >+ } >+}); >+#issue1 and issue2 test if we create a pair between todays issues and an older one >+my $issue2 = $builder->build({source => 'Issue', value => { >+ borrowernumber => $issue1->{borrowernumber}, >+ itemnumber => $item2_0->{itemnumber}, >+ issuedate => $yesterday >+ } >+}); >+my $issue3 = $builder->build({source => 'Issue', value => { >+ itemnumber => $item3_0->{itemnumber}, >+ issuedate => $now >+ } >+}); >+#issue3 and issue4 test if we create a pair between 2 todays issues (and not mixing borrowers) >+my $issue4 = $builder->build({source => 'Issue', value => { >+ borrowernumber => $issue3->{borrowernumber}, >+ itemnumber => $item4_0->{itemnumber}, >+ issuedate => $now >+ } >+}); >+#issue1 and issue5 test if we can create more than one pair for a single borrower >+my $issue5 = $builder->build({source => 'Issue', value => { >+ borrowernumber => $issue1->{borrowernumber}, >+ itemnumber => $item3_1->{itemnumber}, >+ issuedate => $yesterday >+ } >+}); >+#issue6 test if a borrower with a single issues does not create any pair >+my $issue6 = $builder->build({source => 'Issue', value => { >+ itemnumber => $item1_1->{itemnumber}, >+ issuedate => $now >+ } >+}); >+ >+#issue1 and issue7 test pairs are created between todays issues and old_issues table >+my $issue7 = $builder->build({source => 'OldIssue', value => { >+ borrowernumber => $issue1->{borrowernumber}, >+ itemnumber => $item4_1->{itemnumber}, >+ issuedate => $yesterday >+ } >+}); >+my $issue8 = $builder->build({source => 'OldIssue', value => { >+ itemnumber => $item1_0->{itemnumber}, >+ issuedate => $now >+ } >+}); >+#issue8 and issue9 test that no pairs are created between old_issues issues >+my $issue9 = $builder->build({source => 'OldIssue', value => { >+ borrowernumber => $issue8->{borrowernumber}, >+ itemnumber => $item2_0->{itemnumber}, >+ issuedate => $yesterday >+ } >+}); >+ >+my $issue10 = $builder->build({source => 'Issue', value => { >+ itemnumber => $item1_2->{itemnumber}, >+ issuedate => $now >+ } >+}); >+#issue10 and issue11 test that no pairs are created between same biblio >+my $issue11 = $builder->build({source => 'Issue', value => { >+ borrowernumber => $issue10->{borrowernumber}, >+ itemnumber => $item1_3->{itemnumber}, >+ issuedate => $yesterday >+ } >+}); >+ >+my $issue12 = $builder->build({source => 'Issue', value => { >+ itemnumber => $item1_4->{itemnumber}, >+ issuedate => $yesterday >+ } >+}); >+#issue12 and issue13 test that no pairs are created between two issues from yesterday >+my $issue13 = $builder->build({source => 'Issue', value => { >+ borrowernumber => $issue12->{borrowernumber}, >+ itemnumber => $item1_5->{itemnumber}, >+ issuedate => $yesterday >+ } >+}); >+ >+ >+ >+ >+my $issue_50 = $builder->build({source => 'Issue', value => { >+ issuedate => $now >+ } >+}); >+ >+#creating more than 50 issues for a specific borrower to check if, as expected, no pairs are created for this borrower >+for (my $i = 0; $i <= 50; $i++){ >+ $builder->build({source => 'Issue', value => { >+ borrowernumber => $issue6->{borrowernumber}, >+ issuedate => $now >+ }}); >+}; >+ >+ >+ >+my @reading_pairs = Koha::SharedContent::extract_reading_pairs(); >+subtest 'Create pair' => sub { >+ plan tests => 5; >+ >+ is($#reading_pairs, 3, "There are four pairs as exepected"); >+ >+ subtest '1st pair is as expected' => sub { >+ plan tests => 4; >+ >+ is($reading_pairs[0]->{documentid1}, $id1, "1st pair documentid1 is $id1 as expected"); >+ is($reading_pairs[0]->{documentid2}, $id2, "1st pair documentid2 is $id2 as expected"); >+ is($reading_pairs[0]->{idtype1}, "isbn", "1st pair idtype1 is isbn as expected"); >+ is($reading_pairs[0]->{idtype2}, "isbn", "1st pair idtype2 is isbn as expected"); >+ }; >+ >+ subtest '2nd pair is as expected' => sub { >+ plan tests => 4; >+ >+ is($reading_pairs[1]->{documentid1}, $id1, "2nd pair documentid1 is $id1 as expected"); >+ is($reading_pairs[1]->{documentid2}, $id3, "2nd pair documentid2 is $id3 as expected"); >+ is($reading_pairs[1]->{idtype1}, "isbn", "2nd pair idtype1 is isbn as expected"); >+ is($reading_pairs[1]->{idtype2}, "isbn", "2nd pair idtype2 is isbn as expected"); >+ }; >+ >+ subtest '3rd pair is as expected' => sub { >+ plan tests => 4; >+ >+ is($reading_pairs[2]->{documentid1}, $id3, "3rd pair documentid1 is $id3 is as expected"); >+ is($reading_pairs[2]->{documentid2}, $id4, "3rd pair documentid2 is $id4 as expected"); >+ is($reading_pairs[2]->{idtype1}, "isbn", "3rd pair idtype1 is isbn as expected"); >+ is($reading_pairs[2]->{idtype2}, "isbn", "3rd pair idtype2 is isbn as expected"); >+ }; >+ >+ subtest '4th pair is as expected' => sub { >+ plan tests => 4; >+ >+ is($reading_pairs[3]->{documentid1}, $id1, "4th pair documentid1 is $id4 as expected"); >+ is($reading_pairs[3]->{documentid2}, $id4, "4th pair documentid2 is $id4 as expected"); >+ is($reading_pairs[3]->{idtype1}, "isbn", "4th pair idtype1 is isbn as expected"); >+ is($reading_pairs[3]->{idtype2}, "isbn", "4th pair idtype2 is isbn as expected"); >+ }; >+}; >+ >+subtest 'get_identifier_field_marc' => sub { >+ plan tests => 28; >+ >+ t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' ); >+ my ($fields_ref, $inds1_ref) = Koha::SharedContent::get_identifier_field_marc(); >+ is($fields_ref->{isbn}, "010", "UNIMARC isbn is in fields 010"); >+ is($fields_ref->{issn}, "011", "UNIMARC issn is in fields 011"); >+ is($fields_ref->{ismn}, "013", "UNIMARC ismn is in fields 013"); >+ is($fields_ref->{isrn}, "015", "UNIMARC isrn is in fields 015"); >+ is($fields_ref->{isrc}, "016", "UNIMARC isbn is in fields 016"); >+ is($fields_ref->{upc}, "072", "UNIMARC upc is in fields 072"); >+ is($fields_ref->{ean}, "073", "UNIMARC ean is in fields 073"); >+ >+ is($inds1_ref->{isbn}, "", "UNIMARC isbn does not use inds1"); >+ is($inds1_ref->{issn}, "", "UNIMARC issn does not use inds1"); >+ is($inds1_ref->{ismn}, "", "UNIMARC ismn does not use inds1"); >+ is($inds1_ref->{isrn}, "", "UNIMARC isrn does not use inds1"); >+ is($inds1_ref->{isrc}, "", "UNIMARC isbn does not use inds1"); >+ is($inds1_ref->{upc}, "", "UNIMARC upc does not use inds1"); >+ is($inds1_ref->{ean}, "", "UNIMARC ean does not use inds1"); >+ >+ t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' ); >+ ($fields_ref, $inds1_ref) = Koha::SharedContent::get_identifier_field_marc(); >+ is($fields_ref->{isbn}, "020", "MARC21 isbn is in fields 020"); >+ is($fields_ref->{issn}, "022", "MARC21 issn is in fields 022"); >+ is($fields_ref->{ismn}, "024", "MARC21 ismn is in fields 024"); >+ is($fields_ref->{isrn}, "027", "MARC21 isrn is in fields 027"); >+ is($fields_ref->{isrc}, "024", "MARC21 isbn is in fields 024"); >+ is($fields_ref->{upc}, "024", "MARC21 upc is in fields 024"); >+ is($fields_ref->{ean}, "024", "MARC21 ean is in fields 024"); >+ >+ is($inds1_ref->{isbn}, "", "MARC21 isbn does not use inds1"); >+ is($inds1_ref->{issn}, "", "MARC21 issn does not use inds1"); >+ is($inds1_ref->{ismn}, " and \@ind1=\"2\"", "MARC21 ismn inds1 is 2"); >+ is($inds1_ref->{isrn}, "", "MARC21 isrn does not use inds1"); >+ is($inds1_ref->{isrc}, " and \@ind1=\"0\"", "MARC21 isbn inds1 is 0"); >+ is($inds1_ref->{upc}, " and \@ind1=\"1\"", "MARC21 upc inds1 is 1"); >+ is($inds1_ref->{ean}, " and \@ind1=\"3\"", "MARC21 ean inds1 is 3"); >+ >+}; >+ >+subtest 'Get identifiers' => sub { >+ plan tests => 10; >+ >+ subtest '1 isbn' => sub { >+ plan tests => 3; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblio1->biblionumber); >+ is($result->{idtype}, "isbn", "idtype"); >+ is($result->{documentids}, $id1, "documentid"); >+ is($result->{code}, 200, "code"); >+ }; >+ >+ subtest '2 isbn' => sub { >+ plan tests => 3; >+ >+ my $record = MARC::Record->new(); >+ my $ida = '9783161484100'; >+ my $idb = '9782765410058'; >+ my $fielda = MARC::Field->new('020','','','a' => $ida); >+ my $fieldb = MARC::Field->new('020','','','a' => $idb); >+ $record->append_fields( $fielda ); >+ $record->append_fields( $fieldb ); >+ my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); >+ $biblionumbers{isbn2} = $biblionumber; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblionumber); >+ is($result->{idtype}, "isbn", "idtype"); >+ is($result->{documentids}, "$ida $idb", "documentids"); >+ is($result->{code}, 200, "code"); >+ }; >+ >+ subtest '2 ean' => sub { >+ plan tests => 3; >+ >+ my $ida = '9783161484100'; >+ my $idb = '9782266247306'; >+ my $record = MARC::Record->new(); >+ my $fielda = MARC::Field->new('024','3','','a' => $ida); >+ my $fieldb = MARC::Field->new('024','3','','a' => $idb); >+ $record->append_fields( $fielda ); >+ $record->append_fields( $fieldb ); >+ my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); >+ $biblionumbers{ean2} = $biblionumber; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblionumber); >+ is($result->{idtype}, "ean", "idtype"); >+ is($result->{documentids}, "$ida $idb", "documentids"); >+ is($result->{code}, 200, "code"); >+ }; >+ >+ subtest '2 issn' => sub { >+ plan tests => 3; >+ >+ my $ida = '0335-4725'; >+ my $idb = '0151-0282'; >+ my $record = MARC::Record->new(); >+ my $fielda = MARC::Field->new('022','','','a' => $ida); >+ my $fieldb = MARC::Field->new('022','','','a' => $idb); >+ $record->append_fields( $fielda ); >+ $record->append_fields( $fieldb ); >+ my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); >+ $biblionumbers{issn2} = $biblionumber; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblionumber); >+ is($result->{idtype}, "issn", "idtype"); >+ is($result->{documentids}, "$ida $idb", "documentids"); >+ is($result->{code}, 200, "code"); >+ }; >+ >+ subtest '2 ismn' => sub { >+ plan tests => 3; >+ >+ my $ida = '9790260000438'; >+ my $idb = '9790000001213'; >+ my $record = MARC::Record->new(); >+ my $fielda = MARC::Field->new('024','2','','a' => $ida); >+ my $fieldb = MARC::Field->new('024','2','','a' => $idb); >+ $record->append_fields( $fielda ); >+ $record->append_fields( $fieldb ); >+ my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); >+ $biblionumbers{ismn2} = $biblionumber; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblionumber); >+ is($result->{idtype}, "ismn", "idtype"); >+ is($result->{documentids}, "$ida $idb", "documentids"); >+ is($result->{code}, 200, "code"); >+ }; >+ >+ subtest '2 isrn' => sub { >+ plan tests => 3; >+ >+ my $ida = 'METPRO-CB-TR--74-216'; >+ my $idb = 'COUCOU-ICI--00-45'; >+ my $record = MARC::Record->new(); >+ my $fielda = MARC::Field->new('027','','','a' => $ida); >+ my $fieldb = MARC::Field->new('027','','','a' => $idb); >+ $record->append_fields( $fielda ); >+ $record->append_fields( $fieldb ); >+ my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); >+ $biblionumbers{isrn2} = $biblionumber; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblionumber); >+ is($result->{idtype}, "isrn", "idtype"); >+ is($result->{documentids}, "$ida $idb", "documentids"); >+ is($result->{code}, 200, "code"); >+ }; >+ >+ subtest '2 isrc' => sub { >+ plan tests => 3; >+ >+ my $ida = 'FRAB50712345'; >+ my $idb = 'FRR091240970'; >+ my $record = MARC::Record->new(); >+ my $fielda = MARC::Field->new('024','0','','a' => $ida); >+ my $fieldb = MARC::Field->new('024','0','','a' => $idb); >+ $record->append_fields( $fielda ); >+ $record->append_fields( $fieldb ); >+ my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); >+ $biblionumbers{isrc2} = $biblionumber; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblionumber); >+ is($result->{idtype}, "isrc", "idtype"); >+ is($result->{documentids}, "$ida $idb", "documentids"); >+ is($result->{code}, 200, "code"); >+ }; >+ >+ subtest '2 upc' => sub { >+ plan tests => 3; >+ >+ my $ida = '036000291452'; >+ my $idb = '123601057072'; >+ my $record = MARC::Record->new(); >+ my $fielda = MARC::Field->new('024','1','','a' => $ida); >+ my $fieldb = MARC::Field->new('024','1','','a' => $idb); >+ $record->append_fields( $fielda ); >+ $record->append_fields( $fieldb ); >+ my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); >+ $biblionumbers{upc2} = $biblionumber; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblionumber); >+ is($result->{idtype}, "upc", "idtype"); >+ is($result->{documentids}, "$ida $idb", "documentids"); >+ is($result->{code}, 200, "code"); >+ }; >+ >+ subtest 'invalid isbn' => sub { >+ plan tests => 2; >+ >+ my $ida = '=af~faf5efg thg'; >+ my $record = MARC::Record->new(); >+ my $fielda = MARC::Field->new('020','','','a' => $ida); >+ $record->append_fields( $fielda ); >+ my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); >+ $biblionumbers{isbn_invalid} = $biblionumber; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblionumber); >+ is($result->{code}, 404, "code"); >+ is($result->{message}, "No usable id found", "message"); >+ }; >+ >+ subtest 'no id' => sub { >+ plan tests => 2; >+ my $record = MARC::Record->new(); >+ my ($biblionumber) = C4::Biblio::AddBiblio($record, ''); >+ $biblionumbers{no_id} = $biblionumber; >+ >+ my $result = Koha::SharedContent::get_identifiers($biblionumber); >+ is($result->{code}, 404, "code"); >+ is($result->{message}, "No usable id found", "message"); >+ }; >+}; >+ >+my $record5 = MARC::Record->new(); >+my $record6 = MARC::Record->new(); >+ >+my $id5 = '9780596003067'; >+my $id6 = '9780596527211'; >+ >+my $field5 = MARC::Field->new('024','3','','a' => $id5); >+my $field6 = MARC::Field->new('020','','','a' => $id6); >+ >+$record5->append_fields( $field5 ); >+$record6->append_fields( $field6 ); >+ >+my ($biblionumber5) = C4::Biblio::AddBiblio($record5, ''); >+$biblionumbers{biblio5} = $biblionumber5; >+my ($biblionumber6) = C4::Biblio::AddBiblio($record6, ''); >+$biblionumbers{biblio6} = $biblionumber6; >+ >+print "bib5 = $biblionumber5, bib6=$biblionumber6\n"; >+my $item5_0 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblionumber5 >+ } >+}); >+my $item6_0 = $builder->build({source => 'Item', value => { >+ biblionumber => $biblionumber6 >+ } >+}); >+ >+sub mock_ask_mana_reading_suggestion { >+ my ($params) = @_; >+ my $start = $params->{start}; >+ my $end = $params->{end}; >+ my $code = $params->{code}; >+ my $msg = $params->{msg}; >+ >+ if (!$start || !$end){ >+ return {code => $code, msg => $msg} >+ }; >+ >+ my @docs = ( >+ {idtype => "isbn", documentid => "9783161484100"}, #biblio1 0 >+ {idtype => "ean", documentid => "9783161484100"}, #biblio1 1 >+ {idtype => "isbn", documentid => "9780321496942"}, #biblio2 2 >+ {idtype => "issn", documentid => "0335-4725"}, #issn2 3 >+ {idtype => "ismn", documentid => "9790260000438"}, #ismn2 4 >+ {idtype => "isbn", documentid => "9780914378266"}, #biblio3 5 >+ {idtype => "isbn", documentid => "9780491001304"}, #biblio4 6 >+ {idtype => "ean", documentid => "9782259025669"}, #not in database 7 >+ {idtype => "isrn", documentid => "METPRO-CB-TR--74-216"}, #isrn2 8 >+ {idtype => "isrc", documentid => "FRAB50712345"}, #isrc2 9 >+ {idtype => "upc", documentid => "036000291452"}, #upc2 10 >+ {idtype => "isbn", documentid => "9782379891113"}, #not in datbase 11 >+ {idtype => "ean", documentid => "9782266247306"}, #ean2 12 >+ {idtype => "ean", documentid => "9780596003067"}, #biblio5 13 >+ {idtype => "isbn", documentid => "9780596527211"}, #biblio6 14 >+ ); >+ my @slice = @docs[$start..$end]; >+ my $ref = \@slice; >+ >+ return {code => $code, data => $ref}; >+}; >+ >+subtest 'get reading pair' => sub { >+ plan tests => 7; >+ >+ subtest 'biblio1' => sub { >+ plan tests => 12; >+ >+ my $module = Test::MockModule->new('Koha::SharedContent'); >+ $module->mock('ask_mana_reading_suggestion', sub {return mock_ask_mana_reading_suggestion{code => 200, start => 2, end => 14}}); >+ my $biblionumber = $biblionumbers{biblio1}; >+ my $local_suggestions; >+ eval{ >+ $local_suggestions = Koha::Reading_suggestions->find( $biblionumber )->unblessed(); >+ }; >+ >+ my $result = Koha::SharedContent::get_reading_suggestion($biblionumber, $local_suggestions); >+ is($result->{code}, 200, "code ok"); >+ is($result->{data}[0]->{biblionumber}, $biblionumbers{biblio2}, "1st suggestion"); >+ is($result->{data}[1]->{biblionumber}, $biblionumbers{issn2}, "2nd suggestion"); >+ is($result->{data}[2]->{biblionumber}, $biblionumbers{ismn2}, "3rd suggestion"); >+ is($result->{data}[3]->{biblionumber}, $biblionumbers{biblio3}, "4th suggestion"); >+ is($result->{data}[4]->{biblionumber}, $biblionumbers{biblio4}, "5th suggestion"); >+ is($result->{data}[5]->{biblionumber}, $biblionumbers{isrn2}, "6th suggestion"); >+ is($result->{data}[6]->{biblionumber}, $biblionumbers{isrc2}, "7th suggestion"); >+ is($result->{data}[7]->{biblionumber}, $biblionumbers{upc2}, "8th suggestion"); >+ is($result->{data}[8]->{biblionumber}, $biblionumbers{ean2}, "9th suggestion"); >+ is($result->{data}[9]->{biblionumber}, $biblionumbers{biblio5}, "10th suggestion"); >+ is(exists($result->{data}[10]), '', "no 11th suggestion"); >+ }; >+ >+ >+ subtest 'biblio2' => sub { >+ plan tests => 7; >+ >+ my $module = Test::MockModule->new('Koha::SharedContent'); >+ $module->mock('ask_mana_reading_suggestion', sub {return mock_ask_mana_reading_suggestion{code => 200, start => 5, end => 10}}); >+ my $biblionumber = $biblionumbers{biblio2}; >+ my $local_suggestions; >+ eval{ >+ $local_suggestions = Koha::Reading_suggestions->find( $biblionumber )->unblessed(); >+ }; >+ >+ my $result = Koha::SharedContent::get_reading_suggestion($biblionumber, $local_suggestions); >+ is($result->{code}, 200, "code ok"); >+ is($result->{data}[0]->{biblionumber}, $biblionumbers{biblio3}, "1st suggestion"); >+ is($result->{data}[1]->{biblionumber}, $biblionumbers{biblio4}, "2nd suggestion"); >+ is($result->{data}[2]->{biblionumber}, $biblionumbers{isrn2}, "3rd suggestion"); >+ is($result->{data}[3]->{biblionumber}, $biblionumbers{isrc2}, "4th suggestion"); >+ is($result->{data}[4]->{biblionumber}, $biblionumbers{upc2}, "5th suggestion"); >+ is(exists($result->{data}[5]), '', "no 6th suggestion"); >+ }; >+ >+ subtest 'biblio1 suggestion in koha db' => sub { >+ plan tests => 11; >+ >+ my $dbh = C4::Context->dbh; >+ my $db_query = q{ >+ SELECT >+ biblionumber, biblionumber1, biblionumber2, biblionumber3, biblionumber4, biblionumber5, biblionumber6, biblionumber6, biblionumber7, biblionumber8, biblionumber9, biblionumber10 >+ FROM reading_suggestion >+ WHERE >+ biblionumber = '}.$biblionumbers{biblio1}.q{' >+ }; >+ my $sth = $dbh->prepare( $db_query ); >+ $sth->execute; >+ my $row = $sth->fetchrow_hashref; >+ >+ is($row->{biblionumber}, $biblionumbers{biblio1}, "biblionumber"); >+ is($row->{biblionumber1}, $biblionumbers{biblio2}, "biblionumber1"); >+ is($row->{biblionumber2}, $biblionumbers{issn2}, "biblionumber2"); >+ is($row->{biblionumber3}, $biblionumbers{ismn2}, "biblionumber3"); >+ is($row->{biblionumber4}, $biblionumbers{biblio3}, "biblionumber4"); >+ is($row->{biblionumber5}, $biblionumbers{biblio4}, "biblionumber5"); >+ is($row->{biblionumber6}, $biblionumbers{isrn2}, "biblionumber6"); >+ is($row->{biblionumber7}, $biblionumbers{isrc2}, "biblionumber7"); >+ is($row->{biblionumber8}, $biblionumbers{upc2}, "biblionumber8"); >+ is($row->{biblionumber9}, $biblionumbers{ean2}, "biblionumber9"); >+ is($row->{biblionumber10}, $biblionumbers{biblio5}, "biblionumber10"); >+ }; >+ >+ subtest 'biblio2 suggestion in koha db' => sub { >+ plan tests => 11; >+ >+ my $dbh = C4::Context->dbh; >+ my $db_query = q{ >+ SELECT >+ biblionumber, biblionumber1, biblionumber2, biblionumber3, biblionumber4, biblionumber5, biblionumber6, biblionumber6, biblionumber7, biblionumber8, biblionumber9, biblionumber10 >+ FROM reading_suggestion >+ WHERE >+ biblionumber = '}.$biblionumbers{biblio2}.q{' >+ }; >+ my $sth = $dbh->prepare( $db_query ); >+ $sth->execute; >+ my $row = $sth->fetchrow_hashref; >+ >+ is($row->{biblionumber}, $biblionumbers{biblio2}, "biblionumber"); >+ is($row->{biblionumber1}, $biblionumbers{biblio3}, "biblionumber1"); >+ is($row->{biblionumber2}, $biblionumbers{biblio4}, "biblionumber2"); >+ is($row->{biblionumber3}, $biblionumbers{isrn2}, "biblionumber3"); >+ is($row->{biblionumber4}, $biblionumbers{isrc2}, "biblionumber4"); >+ is($row->{biblionumber5}, $biblionumbers{upc2}, "biblionumber5"); >+ is($row->{biblionumber6}, undef, "biblionumber6"); >+ is($row->{biblionumber7}, undef, "biblionumber7"); >+ is($row->{biblionumber8}, undef, "biblionumber8"); >+ is($row->{biblionumber9}, undef, "biblionumber9"); >+ is($row->{biblionumber10}, undef, "biblionumber10"); >+ }; >+ >+ >+ subtest 'error code from mana with message' => sub { >+ plan tests => 2; >+ >+ my $module = Test::MockModule->new('Koha::SharedContent'); >+ $module->mock('ask_mana_reading_suggestion', sub {return mock_ask_mana_reading_suggestion{code => 401, msg => "Error 401"}}); >+ >+ my $biblionumber = $biblionumbers{biblio2}; >+ my $local_suggestions; >+ eval{ >+ $local_suggestions = Koha::Reading_suggestions->find( $biblionumber )->unblessed(); >+ }; >+ >+ my $result = Koha::SharedContent::get_reading_suggestion($biblionumber, $local_suggestions); >+ >+ is($result->{code}, 401, "code"); >+ is($result->{message}, "Error 401", "message"); >+ }; >+ >+ subtest 'error code from mana' => sub { >+ plan tests => 2; >+ >+ my $module = Test::MockModule->new('Koha::SharedContent'); >+ $module->mock('ask_mana_reading_suggestion', sub {return mock_ask_mana_reading_suggestion{code => 401}}); >+ >+ my $biblionumber = $biblionumbers{biblio2}; >+ my $local_suggestions; >+ eval{ >+ $local_suggestions = Koha::Reading_suggestions->find( $biblionumber )->unblessed(); >+ }; >+ >+ my $result = Koha::SharedContent::get_reading_suggestion($biblionumber, $local_suggestions); >+ >+ is($result->{code}, 401, "code"); >+ is($result->{message}, undef, "message"); >+ }; >+ >+ subtest 'error without code or message from mana' => sub { >+ plan tests => 2; >+ >+ my $module = Test::MockModule->new('Koha::SharedContent'); >+ $module->mock('ask_mana_reading_suggestion', sub {return mock_ask_mana_reading_suggestion{}}); >+ >+ my $biblionumber = $biblionumbers{biblio2}; >+ my $local_suggestions; >+ eval{ >+ $local_suggestions = Koha::Reading_suggestions->find( $biblionumber )->unblessed(); >+ }; >+ >+ my $result = Koha::SharedContent::get_reading_suggestion($biblionumber, $local_suggestions); >+ >+ is($result->{code}, 400, "code"); >+ is($result->{message}, "Unknown error", "message"); >+ }; >+ >+}; >+ > $schema->storage->txn_rollback; >-- >2.7.4
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 18618
:
63496
|
63497
|
64531
|
64960
|
65066
|
65067
|
65068
|
65069
|
65070
|
130706
|
130707
|
130708
|
130709
|
130710
|
130711
|
130712
|
130713
|
130714
|
130715
|
130735
|
130736
|
130737
|
130738
|
130739
|
130740
|
130741
|
130742
|
130743
|
130744
| 132690 |
132691