From 350081713c8915b52182ecd9b90712915f59ae52 Mon Sep 17 00:00:00 2001 From: Aleisha Amohia Date: Thu, 1 Dec 2016 00:54:07 +0000 Subject: [PATCH] Bug 17698: Make patron notes show up on staff dashboard This patch adds a user permission for managing issue notes, and a 'noteseen' column to the issues table. To test: 1) Apply Bug 14224 first 2) Apply this patch, update database, rebuild schema. 3) Restart koha-common and memcached 4) Turn on AllowCheckoutNotes syspref if haven't already 5) Issue two items to two different users (one item each) 6) Log into the OPAC as one of the users and add an issue note to their issue 7) Log out and log back into the OPAC as the other user 8) Disable Javascript 9) Refresh opac-user.pl 10) Leave a checkout note on their issue 11) Enable javascript and log into the Staff Client as a superlibrarian user 12) Go to your user's account and edit their permissions to have everything ticked EXCEPT circulate->manage checkout notes. 13) Go to main intranet page. There should be no message saying 'checkout notes pending'. 14) Go to circulation home page. There should be no link to Checkout notes. 15) Go back to user's permissions and tick circulate->manage checkout notes. 16) Go back to main intranet page. There should now be a message at the bottom saying 'Checkout notes pending: 2' 17) Go to circulation home page. There should be a link to Checkout notes with a 2 next to it. Click this link 18) Attempt to mark an checkout note as seen. This should update the status of the checkout note to 'seen' and disable to 'mark as seen' button while enabling the 'mark as not seen' button. 19) Test both buttons with both issues. 20) Test select all and clear all buttons 21) Confirm that buttons at the bottom are only enabled if a checkbox is checked 22) Try selecting both issues and using the buttons at the bottom to mark multiple issue notes at once. 23) Confirm the barcode link to the item works as expected. 24) Confirm the cardnumber link to the user works as expected. 25) Confirm all table details show correctly. Sponsored-by: Catalyst IT Signed-off-by: Josef Moravec --- Koha/Schema/Result/Issue.pm | 7 + circ/checkout-notes.pl | 71 +++++++++ circ/circulation-home.pl | 3 + .../bug-17698_add-noteseen-column-to-issues.sql | 13 ++ ...-17698_add-permission-to-manage-issue-notes.sql | 1 + installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/userpermissions.sql | 1 + .../intranet-tmpl/prog/en/includes/permissions.inc | 1 + .../prog/en/modules/circ/checkout-notes.tt | 165 +++++++++++++++++++++ .../prog/en/modules/circ/circulation-home.tt | 1 + .../intranet-tmpl/prog/en/modules/intranet-main.tt | 7 + mainpage.pl | 3 + opac/opac-issue-note.pl | 2 +- opac/svc/patron_notes | 2 +- svc/checkout_notes | 63 ++++++++ 15 files changed, 339 insertions(+), 2 deletions(-) create mode 100755 circ/checkout-notes.pl create mode 100644 installer/data/mysql/atomicupdate/bug-17698_add-noteseen-column-to-issues.sql create mode 100644 installer/data/mysql/atomicupdate/bug-17698_add-permission-to-manage-issue-notes.sql create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/checkout-notes.tt create mode 100755 svc/checkout_notes diff --git a/Koha/Schema/Result/Issue.pm b/Koha/Schema/Result/Issue.pm index 326eb95..f521bf7 100644 --- a/Koha/Schema/Result/Issue.pm +++ b/Koha/Schema/Result/Issue.pm @@ -106,6 +106,11 @@ __PACKAGE__->table("issues"); datetime_undef_if_invalid: 1 is_nullable: 1 +=head2 noteseen + + data_type: 'integer' + is_nullable: 1 + =cut __PACKAGE__->add_columns( @@ -162,6 +167,8 @@ __PACKAGE__->add_columns( datetime_undef_if_invalid => 1, is_nullable => 1, }, + "noteseen", + { data_type => "integer", is_nullable => 1 }, ); =head1 PRIMARY KEY diff --git a/circ/checkout-notes.pl b/circ/checkout-notes.pl new file mode 100755 index 0000000..998cabe --- /dev/null +++ b/circ/checkout-notes.pl @@ -0,0 +1,71 @@ +#!/usr/bin/perl + +# Copyright 2016 Aleisha Amohia +# +# 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 . + +use Modern::Perl; + +use CGI qw ( -utf8 ); +use C4::Context; +use C4::Output; +use C4::Auth; +use Koha::Checkouts; + +my $query = new CGI; + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "circ/checkout-notes.tt", + query => $query, + type => "intranet", + authnotrequired => 0, + flagsrequired => { circulation => "manage_checkout_notes" }, + } +); + +my $schema = Koha::Database->new()->schema(); +my @notes = $schema->resultset('Issue')->search({ 'me.note' => { '!=', undef } }, { prefetch => [ 'borrower', { item => 'biblionumber' } ] }); +$template->param( + notes => \@notes, +); + +my $action; +foreach (qw( seen notseen )) { + $action = $_ if ( $query->param("mark_selected-$_") ); +} +$action ||= 'none'; + +my @issue_ids = $query->multi_param('issue_ids'); + +if ( $action eq 'seen' ) { + foreach my $issue_id ( @issue_ids ) { + my $issue = Koha::Checkouts->find($issue_id); + $issue->set({ noteseen => 1 })->store; + } +} elsif ( $action eq 'notseen' ) { + foreach my $issue_id ( @issue_ids ) { + my $issue = Koha::Checkouts->find($issue_id); + $issue->set({ noteseen => 0 })->store; + } +} + +$template->param( + selected_count => scalar(@issue_ids), + action => $action, +); + +output_html_with_http_headers $query, $cookie, $template->output; diff --git a/circ/circulation-home.pl b/circ/circulation-home.pl index 7d24d79..f101f6d 100755 --- a/circ/circulation-home.pl +++ b/circ/circulation-home.pl @@ -22,6 +22,7 @@ use C4::Auth; use C4::Output; use C4::Context; use Koha::BiblioFrameworks; +use Koha::Checkouts; my $query = new CGI; my ($template, $loggedinuser, $cookie, $flags) = get_template_and_user( @@ -39,5 +40,7 @@ $template->param( fast_cataloging => 1 ) if Koha::BiblioFrameworks->find( 'FA' ) $template->{'VARS'}->{'AllowOfflineCirculation'} = C4::Context->preference('AllowOfflineCirculation'); +my $pending_checkout_notes = Koha::Checkouts->search({ noteseen => 0 })->count; +$template->param( pending_checkout_notes => $pending_checkout_notes ); output_html_with_http_headers $query, $cookie, $template->output; diff --git a/installer/data/mysql/atomicupdate/bug-17698_add-noteseen-column-to-issues.sql b/installer/data/mysql/atomicupdate/bug-17698_add-noteseen-column-to-issues.sql new file mode 100644 index 0000000..f57d930 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug-17698_add-noteseen-column-to-issues.sql @@ -0,0 +1,13 @@ +$DBversion = 'XXX'; +if( CheckVersion( $DBversion ) ) { + unless( column_exists( 'issues', 'noteseen' ) ) { + $dbh->do(q|ALTER TABLE issues ADD noteseen int(1) default NULL AFTER notedate|); + } + + unless( column_exists( 'old_issues', 'noteseen' ) ) { + $dbh->do(q|ALTER TABLE old_issues ADD noteseen int(1) default NULL AFTER notedate|); + } + + SetVersion( $DBversion ); + print "Upgrade to $DBversion done (Bug 17698: Add column issues.noteseen and old_issues.noteseen)\n"; +} diff --git a/installer/data/mysql/atomicupdate/bug-17698_add-permission-to-manage-issue-notes.sql b/installer/data/mysql/atomicupdate/bug-17698_add-permission-to-manage-issue-notes.sql new file mode 100644 index 0000000..86d4351 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug-17698_add-permission-to-manage-issue-notes.sql @@ -0,0 +1 @@ +INSERT INTO permissions (module_bit, code, description) VALUES ( 1, 'manage_checkout_notes', 'Mark checkout notes as seen/not seen'); diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 751ce65..b457bc3 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1780,6 +1780,7 @@ CREATE TABLE `old_issues` ( -- lists items that were checked out and have been r `onsite_checkout` int(1) NOT NULL default 0, -- in house use flag `note` mediumtext default NULL, -- issue note text `notedate` datetime default NULL, -- datetime of issue note (yyyy-mm-dd hh:mm::ss) + `noteseen` int(1) default NULL, -- describes whether issue note has been seen 1, not been seen 0 or doesn't exist null PRIMARY KEY (`issue_id`), KEY `old_issuesborridx` (`borrowernumber`), KEY `old_issuesitemidx` (`itemnumber`), diff --git a/installer/data/mysql/userpermissions.sql b/installer/data/mysql/userpermissions.sql index 6b72278..532f74e 100644 --- a/installer/data/mysql/userpermissions.sql +++ b/installer/data/mysql/userpermissions.sql @@ -5,6 +5,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES ( 1, 'force_checkout', 'Force checkout if a limitation exists'), ( 1, 'manage_restrictions', 'Manage restrictions for accounts'), ( 1, 'self_checkout', 'Perform self checkout at the OPAC. It should be used for the patron matching the AutoSelfCheckID'), + ( 1, 'manage_checkout_notes', 'Mark checkout notes as seen/not seen'), ( 3, 'parameters_remaining_permissions', 'Remaining system parameters permissions'), ( 3, 'manage_circ_rules', 'Manage circulation rules'), ( 6, 'place_holds', 'Place holds for patrons'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc index bcff76b..18d2054 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc @@ -30,6 +30,7 @@ [%- CASE 'overdues_report' -%]Execute overdue items report [%- CASE 'override_renewals' -%]Override blocked renewals [%- CASE 'self_checkout' -%]Perform self checkout at the OPAC. It should be used for the patron matching the AutoSelfCheckID + [%- CASE 'manage_checkout_notes' -%]Mark checkout notes as seen/notseen [%- CASE 'manage_circ_rules' -%]manage circulation rules [%- CASE 'parameters_remaining_permissions' -%]Remaining system parameters permissions [%- CASE 'modify_holds_priority' -%]Modify holds priority diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/checkout-notes.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/checkout-notes.tt new file mode 100644 index 0000000..09fb63a --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/checkout-notes.tt @@ -0,0 +1,165 @@ +[% USE Koha %] +[% USE KohaDates %] +[% USE Branches %] +[% INCLUDE 'doc-head-open.inc' %] +Home › Circulation › Checkout Notes +[% INCLUDE 'doc-head-close.inc' %] + +[% INCLUDE 'datatables.inc' %] + +[% INCLUDE 'calendar.inc' %] + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'circ-search.inc' %] + + +
+
+
+ +

Checkout notes

+ +
+ + [% IF ( selected_count ) %] +
+ [% IF ( action == 'seen' ) %] + [% selected_count %] note(s) marked as seen. + [% ELSIF ( action == 'notseen' ) %] + [% selected_count %] note(s) marked as not seen. + [% ELSE %] + Failed to change the status of [% selected_count %] item(s). + [% END %] +
+ Return to checkout notes + [% ELSE %] + + [% IF ( notes ) %] + +
+ Select all | Clear all +
+ +
+ + + + + + + + + + + + + + + [% FOREACH note IN notes %] + + + + + + + + + + [% END %] + +
 TitleNoteDateSet byStatusActions
[% note.item.biblionumber.title %] - [% note.item.biblionumber.author %] ([% note.item.barcode %])[% note.note %][% note.notedate | $KohaDates %][% note.borrower.firstname %] [% note.borrower.surname %] ([% note.borrower.cardnumber %])[% IF ( note.noteseen == 0 ) %] + Not seen + [% ELSIF ( note.noteseen == 1 ) %] + Seen + [% END %][% IF ( note.noteseen == 1 ) %] + + [% ELSIF ( note.noteseen == 0 ) %] + + [% END %]
+ +
+ + +
+ +
+ + [% END %] + + [% END %] + +
+
+
+ +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt index fa49df9..1f2381f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt @@ -31,6 +31,7 @@
  • Fast cataloging
  • [% END %] [% END %] + [% IF ( Koha.Preference('AllowCheckoutNotes') && CAN_user_circulate_manage_checkout_notes ) %]
  • Checkout notes [% IF ( pending_checkout_notes ) %][% pending_checkout_notes %][% END %]
  • [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt index fa5cde8..2f2d7e4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt @@ -162,6 +162,13 @@ [% END %] + [% IF Koha.Preference('AllowCheckoutNotes') && CAN_user_circulate_manage_checkout_notes && pending_checkout_notes %] +
    + Checkout notes pending: + [% pending_checkout_notes %] +
    + [% END %] + [% END %] diff --git a/mainpage.pl b/mainpage.pl index 7410247..12d5f39 100755 --- a/mainpage.pl +++ b/mainpage.pl @@ -31,6 +31,7 @@ use Koha::Patron::Modifications; use Koha::Patron::Discharge; use Koha::Reviews; use Koha::ArticleRequests; +use Koha::Checkouts; my $query = new CGI; @@ -74,6 +75,7 @@ my $pending_article_requests = Koha::ArticleRequests->count( $branch ? ( branchcode => $branch ) : (), } ); +my $pending_checkout_notes = Koha::Checkouts->search({ noteseen => 0 })->count; $template->param( pendingcomments => $pendingcomments, @@ -82,6 +84,7 @@ $template->param( pending_borrower_modifications => $pending_borrower_modifications, pending_discharge_requests => $pending_discharge_requests, pending_article_requests => $pending_article_requests, + pending_checkout_notes => $pending_checkout_notes, ); # diff --git a/opac/opac-issue-note.pl b/opac/opac-issue-note.pl index becd708..fa2def0 100755 --- a/opac/opac-issue-note.pl +++ b/opac/opac-issue-note.pl @@ -67,7 +67,7 @@ if ( $action eq 'issuenote' && C4::Context->preference('AllowCheckoutNotes') ) { my $note = $query->param('note'); my $scrubber = C4::Scrubber->new(); my $clean_note = $scrubber->scrub($note); - if ( $issue->set({ notedate => dt_from_string(), note => $clean_note })->store ) { + if ( $issue->set({ notedate => dt_from_string(), note => $clean_note, noteseen => 0 })->store ) { if ($clean_note) { # only send email if note not empty my $branch = Koha::Libraries->find( $issue->branchcode ); my $letter = C4::Letters::GetPreparedLetter ( diff --git a/opac/svc/patron_notes b/opac/svc/patron_notes index e26c266..26765e5 100755 --- a/opac/svc/patron_notes +++ b/opac/svc/patron_notes @@ -76,7 +76,7 @@ if ($is_ajax) { } if ( $issue ) { - $issue->set({ notedate => dt_from_string(), note => $clean_note })->store; + $issue->set({ notedate => dt_from_string(), note => $clean_note, noteseen => 0 })->store; if($clean_note) { # only send email if note not empty my $branch = Koha::Libraries->find( $issue->branchcode ); my $biblio = GetBiblioFromItemNumber($issue->itemnumber); diff --git a/svc/checkout_notes b/svc/checkout_notes new file mode 100755 index 0000000..5ad972c --- /dev/null +++ b/svc/checkout_notes @@ -0,0 +1,63 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Copyright 2017 Aleisha Amohia +# +# 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 . + +use Modern::Perl; + +use JSON qw( to_json ); +use CGI; +use C4::Service; +use C4::Auth qw /check_cookie_auth/; +use C4::Output qw(:DEFAULT :ajax); +use Koha::Checkouts; + +=head1 NAME + +svc/checkout_notes - Web service for managing patron notes set on issues + +=head1 DESCRIPTION + +=cut + +# AJAX requests +my $is_ajax = is_ajax(); +my $query = new CGI; +my ( $auth_status, $sessionID ) = check_cookie_auth( $query->cookie('CGISESSID'), { circulate => 'manage_checkout_notes' } ); +if ( $auth_status ne "ok" ) { + exit 0; +} +if ($is_ajax) { + my $issue_id = $query->param('issue_id'); + my $issue = Koha::Checkouts->find($issue_id); + my $action = $query->param('action'); + my $status = 'success'; + if ($action eq 'seen'){ + $issue->set({ noteseen => 1 })->store; + if ( $issue->noteseen != 1 ) { + $status = 'failure'; + } + } elsif ($action eq 'notseen'){ + $issue->set({ noteseen => 0 })->store; + if ( $issue->noteseen != 0 ) { + $status = 'failure'; + } + } + my $json = to_json ( { status => $status } ); + output_with_http_headers $query, undef, $json, 'js'; + exit; +} -- 2.1.4