@@ -, +, @@
---
C4/Circulation.pm | 61 ++++++++++++++
Koha/REST/V1/TopIssues.pm | 27 +++++++
api/v1/swagger.json | 93 ++++++++++++++++++++++
.../bootstrap/en/modules/opac-topissues.tt | 53 ++++++------
opac/opac-topissues.pl | 71 +++--------------
5 files changed, 220 insertions(+), 85 deletions(-)
create mode 100644 Koha/REST/V1/TopIssues.pm
--- a/C4/Circulation.pm
+++ a/C4/Circulation.pm
@@ -95,6 +95,7 @@ BEGIN {
&AnonymiseIssueHistory
&CheckIfIssuedToPatron
&IsItemIssued
+ GetTopIssues
);
# subs to deal with returns
@@ -3968,6 +3969,66 @@ sub GetPendingOnSiteCheckouts {
|, { Slice => {} } );
}
+sub GetTopIssues {
+ my ($params) = @_;
+
+ my ($count, $branch, $itemtype, $ccode, $newness)
+ = @$params{qw(count branch itemtype ccode newness)};
+
+ my $dbh = C4::Context->dbh;
+ my $query = q{
+ SELECT b.biblionumber, b.title, b.author, bi.itemtype, bi.publishercode,
+ bi.place, bi.publicationyear, b.copyrightdate, bi.pages, bi.size,
+ i.ccode, SUM(i.issues) AS count
+ FROM biblio b
+ LEFT JOIN items i ON (i.biblionumber = b.biblionumber)
+ LEFT JOIN biblioitems bi ON (bi.biblionumber = b.biblionumber)
+ };
+
+ my (@where_strs, @where_args);
+
+ if ($branch) {
+ push @where_strs, 'i.homebranch = ?';
+ push @where_args, $branch;
+ }
+ if ($itemtype) {
+ if (C4::Context->preference('item-level_itypes')){
+ push @where_strs, 'i.itype = ?';
+ push @where_args, $itemtype;
+ } else {
+ push @where_strs, 'bi.itemtype = ?';
+ push @where_args, $itemtype;
+ }
+ }
+ if ($ccode) {
+ push @where_strs, 'i.ccode = ?';
+ push @where_args, $ccode;
+ }
+ if ($newness) {
+ push @where_strs, 'TO_DAYS(NOW()) - TO_DAYS(b.datecreated) <= ?';
+ push @where_args, $newness;
+ }
+
+ if (@where_strs) {
+ $query .= 'WHERE ' . join(' AND ', @where_strs);
+ }
+
+ $query .= q{
+ GROUP BY b.biblionumber
+ HAVING count > 0
+ ORDER BY count DESC
+ };
+
+ $count = int($count);
+ if ($count > 0) {
+ $query .= "LIMIT $count";
+ }
+
+ my $rows = $dbh->selectall_arrayref($query, { Slice => {} }, @where_args);
+
+ return @$rows;
+}
+
__END__
=head1 AUTHOR
--- a/Koha/REST/V1/TopIssues.pm
+++ a/Koha/REST/V1/TopIssues.pm
@@ -0,0 +1,27 @@
+package Koha::REST::V1::TopIssues;
+
+use Modern::Perl;
+
+use Mojo::Base 'Mojolicious::Controller';
+
+use C4::Context;
+use C4::Circulation;
+
+sub get_top_issues {
+ my ($c, $args, $cb) = @_;
+
+ my $req = $c->req;
+ my %params = (
+ count => $req->param('count'),
+ branch => $req->param('branch'),
+ itemtype => $req->param('itemtype'),
+ ccode => $req->param('ccode'),
+ newness => $req->param('newness'),
+ );
+
+ my @results = GetTopIssues(\%params);
+
+ $c->$cb(\@results, 200);
+}
+
+1;
--- a/api/v1/swagger.json
+++ a/api/v1/swagger.json
@@ -63,6 +63,99 @@
}
}
}
+ },
+ "/topissues": {
+ "get": {
+ "x-mojo-controller": "Koha::REST::V1::TopIssues",
+ "operationId": "get_top_issues",
+ "tags": ["issues"],
+ "parameters": [
+ {
+ "name": "count",
+ "in": "query",
+ "type": "integer",
+ "minimum": 1,
+ "description": "Number of titles to retrieve"
+ },
+ {
+ "name": "branch",
+ "in": "query",
+ "type": "string",
+ "description": "Filter by branch code"
+ },
+ {
+ "name": "itemtype",
+ "in": "query",
+ "type": "string",
+ "description": "Filter by item type"
+ },
+ {
+ "name": "ccode",
+ "in": "query",
+ "type": "string",
+ "description": "Filter by collection code"
+ },
+ {
+ "name": "newness",
+ "in": "query",
+ "type": "integer",
+ "minimum": 1,
+ "description": "Filter by newness (in days)"
+ }
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "200": {
+ "description": "A borrower",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "count": {
+ "description": "Number of issues for this title"
+ },
+ "copyrightdate": {
+ "description": "Copyright date"
+ },
+ "ccode": {
+ "description": "Collection code"
+ },
+ "itemtype": {
+ "description": "Item type"
+ },
+ "place": {
+ "description": "Publication place"
+ },
+ "author": {
+ "description": "Author"
+ },
+ "size": {
+ "description": "Material size"
+ },
+ "biblionumber": {
+ "description": "Biblio internal identifier"
+ },
+ "title": {
+ "description": "Title"
+ },
+ "publicationyear": {
+ "description": "Publication year"
+ },
+ "publishercode": {
+ "description": "Publisher code"
+ },
+ "pages": {
+ "description": "Number of pages"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
},
"definitions": {
--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-topissues.tt
+++ a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-topissues.tt
@@ -1,4 +1,6 @@
[% USE Koha %]
+[% USE AuthorisedValues %]
+[% USE ItemTypes %]
[% INCLUDE 'doc-head-open.inc' %]
[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › Most popular titles
[% INCLUDE 'doc-head-close.inc' %]
@@ -20,7 +22,7 @@
- [% IF ( results_loop ) %]
+ [% IF ( results ) %]
[% INCLUDE 'opac-topissues.inc' %]
[% IF ( OpacNav || OpacNavBottom ) %]
@@ -38,7 +40,7 @@
- [% IF ( results_loop ) %]
+ [% IF ( results ) %]
The [% limit %] most checked-out
@@ -49,8 +51,8 @@
at
[% branch %]
[% END %]
- [% IF ( timeLimitFinite ) %]
- in the past [% timeLimitFinite |html %] months
+ [% IF ( timeLimit != 999 ) %]
+ in the past [% timeLimit |html %] months
[% ELSE %] of all time[% END %]
@@ -62,33 +64,30 @@
- [% FOREACH results_loo IN results_loop %]
+ [% FOREACH result IN results %]
- [% results_loo.title |html %] [% results_loo.author %]
- [% IF ( results_loo.publishercode ) %]- [% results_loo.publishercode %][% END %] [% IF ( results_loo.seriestitle ) %]([% results_loo.seriestitle %])[% END %]
- [% IF ( results_loo.place ) %][% results_loo.place %][% END %]
- [% IF ( results_loo.publicationyear ) %]
- [% results_loo.publicationyear %]
- [% ELSIF ( results_loo.copyrightdate ) %]
- [% results_loo.copyrightdate %]
+
[% result.title |html %] [% result.author %]
+ [% IF ( result.publishercode ) %]- [% result.publishercode %][% END %]
+ [% IF ( result.place ) %][% result.place %][% END %]
+ [% IF ( result.publicationyear ) %]
+ [% result.publicationyear %]
+ [% ELSIF ( result.copyrightdate ) %]
+ [% result.copyrightdate %]
[% END %]
- [% IF ( results_loo.pages ) %] - [% results_loo.pages %][% END %]
- [% IF ( results_loo.item('size') ) %][% results_loo.item('size') %][% END %]
+ [% IF ( result.pages ) %] - [% result.pages %][% END %]
+ [% IF ( result.item('size') ) %][% result.item('size') %][% END %]
- [% IF ( results_loo.description ) %]
-
- [% IF ( ccodesearch ) %]
- Collection
- [% ELSE %]
- Item type
- [% END %]:
-
- [% results_loo.description %]
- [% END %]
+ [% IF Koha.Preference('AdvancedSearchTypes') == 'ccode' %]
+ Collection
+ [% AuthorisedValues.GetByCode('ccode', result.ccode, 1) %]
+ [% ELSE %]
+ Item type
+ [% ItemTypes.GetDescription(result.itemtype) %]
+ [% END %]
- Checkouts: [% results_loo.tot %]
- [% IF Koha.Preference( 'opacuserlogin' ) == 1 %][% IF Koha.Preference( 'RequestOnOpac' ) == 1 %][% UNLESS ( results_loo.norequests ) %]Place hold [% END %][% END %] [% END %]
+ Checkouts: [% result.count %]
+ [% IF Koha.Preference( 'opacuserlogin' ) == 1 %][% IF Koha.Preference( 'RequestOnOpac' ) == 1 %][% UNLESS ( result.norequests ) %]Place hold [% END %][% END %] [% END %]
[% END %]
@@ -152,7 +151,7 @@
- [% END # / IF results_loop %]
+ [% END # / IF results %]
--- a/opac/opac-topissues.pl
+++ a/opac/opac-topissues.pl
@@ -29,6 +29,7 @@ use C4::Search;
use C4::Output;
use C4::Koha;
use C4::Branch;
+use C4::Circulation;
use Date::Manip;
=head1 NAME
@@ -73,75 +74,29 @@ my $itemtype = $input->param('itemtype') || '';
my $timeLimit = $input->param('timeLimit') || 3;
my $advanced_search_types = C4::Context->preference('AdvancedSearchTypes');
-my $whereclause = '';
-$whereclause .= ' AND items.homebranch='.$dbh->quote($branch) if ($branch);
-$whereclause .= ' AND TO_DAYS(NOW()) - TO_DAYS(biblio.datecreated) <= '.($timeLimit*30) if $timeLimit < 999;
-$whereclause =~ s/ AND $// if $whereclause;
-my $query;
+
+my $params = {
+ count => $limit,
+ branch => $branch,
+ newness => $timeLimit < 999 ? $timeLimit * 30 : undef,
+};
if($advanced_search_types eq 'ccode'){
- $whereclause .= ' AND authorised_values.authorised_value='.$dbh->quote($itemtype) if $itemtype;
- $query = "SELECT datecreated, biblio.biblionumber, title,
- author, sum( items.issues ) AS tot, biblioitems.itemtype,
- biblioitems.publishercode, biblioitems.place, biblioitems.publicationyear, biblio.copyrightdate,
- authorised_values.lib as description, biblioitems.pages, biblioitems.size
- FROM biblio
- LEFT JOIN items USING (biblionumber)
- LEFT JOIN biblioitems USING (biblionumber)
- LEFT JOIN authorised_values ON items.ccode = authorised_values.authorised_value
- WHERE 1
- $whereclause
- AND authorised_values.category = 'ccode'
- GROUP BY biblio.biblionumber
- HAVING tot >0
- ORDER BY tot DESC
- LIMIT ?
- ";
+ $params->{ccode} = $itemtype;
$template->param(ccodesearch => 1);
-}else{
- if ($itemtype){
- if (C4::Context->preference('item-level_itypes')){
- $whereclause .= ' AND items.itype = ' . $dbh->quote($itemtype);
- }
- else {
- $whereclause .= ' AND biblioitems.itemtype='.$dbh->quote($itemtype);
- }
- }
- $query = "SELECT datecreated, biblio.biblionumber, title,
- author, sum( items.issues ) AS tot, biblioitems.itemtype,
- biblioitems.publishercode, biblioitems.place, biblioitems.publicationyear, biblio.copyrightdate,
- itemtypes.description, biblioitems.pages, biblioitems.size
- FROM biblio
- LEFT JOIN items USING (biblionumber)
- LEFT JOIN biblioitems USING (biblionumber)
- LEFT JOIN itemtypes ON itemtypes.itemtype = biblioitems.itemtype
- WHERE 1
- $whereclause
- GROUP BY biblio.biblionumber
- HAVING tot >0
- ORDER BY tot DESC
- LIMIT ?
- ";
- $template->param(itemtypesearch => 1);
-}
-
-my $sth = $dbh->prepare($query);
-$sth->execute($limit);
-my @results;
-while (my $line= $sth->fetchrow_hashref) {
- push @results, $line;
+} else {
+ $params->{itemtype} = $itemtype;
+ $template->param(itemtypesearch => 1);
}
-my $timeLimitFinite = $timeLimit;
-if($timeLimit eq 999){ $timeLimitFinite = 0 };
+my @results = GetTopIssues($params);
$template->param(do_it => 1,
limit => $limit,
branch => $branches->{$branch}->{branchname},
itemtype => $itemtypes->{$itemtype}->{description},
timeLimit => $timeLimit,
- timeLimitFinite => $timeLimitFinite,
- results_loop => \@results,
+ results => \@results,
);
$template->param( branchloop => GetBranchesLoop($branch));
--