From 861b179115674f1a1082f0101ea4fb795b24045b 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, update database, rebuild schema. 2) Apply this patch, update database, rebuild schema. 3) Restart koha-common and memcached 4) Turn on AllowIssueNotes 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 an issue 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 issue notes. 13) Go to main intranet page. There should be no message saying 'issue notes pending'. 14) Go to circulation home page. There should be no link to Issue notes. 15) Go back to user's permissions and tick circulate->manage issue notes. 16) Go back to main intranet page. There should now be a message at the bottom saying 'Issue notes pending: 2' 17) Go to circulation home page. There should be a link to Issue notes. Click Issue notes 18) Attempt to mark an issue note as seen. This should update the status of the issue 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) Try selecting both issues and using the buttons at the bottom to mark multiple issue notes at once. 22) Confirm the barcode link to the item works as expected. 23) Confirm the cardnumber link to the user works as expected. 24) Confirm all table details show correctly. Sponsored-by: Catalyst IT --- Koha/Schema/Result/Issue.pm | 11 +- .../bug-17698_add-noteseen-column-to-issues.sql | 1 + ...-17698_add-permission-to-manage-issue-notes.sql | 1 + installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/userpermissions.sql | 1 + issue_notes/issue-notes.pl | 93 +++++----------- .../prog/en/modules/circ/circulation-home.tt | 2 +- .../intranet-tmpl/prog/en/modules/intranet-main.tt | 2 +- .../prog/en/modules/issue_notes/issue-notes.tt | 122 +++++++++++++++++++-- opac/opac-issue-note.pl | 2 +- opac/svc/patron_notes | 2 +- svc/issue_notes | 73 ++++++++++++ 12 files changed, 227 insertions(+), 84 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug-17698_add-permission-to-manage-issue-notes.sql create mode 100755 svc/issue_notes diff --git a/Koha/Schema/Result/Issue.pm b/Koha/Schema/Result/Issue.pm index 43d5c75..eb8b80b 100644 --- a/Koha/Schema/Result/Issue.pm +++ b/Koha/Schema/Result/Issue.pm @@ -112,6 +112,11 @@ __PACKAGE__->table("issues"); datetime_undef_if_invalid: 1 is_nullable: 1 +=head2 noteseen + + data_type: 'integer' + is_nullable: 1 + =cut __PACKAGE__->add_columns( @@ -170,6 +175,8 @@ __PACKAGE__->add_columns( datetime_undef_if_invalid => 1, is_nullable => 1, }, + "noteseen", + { data_type => "integer", is_nullable => 1 }, ); =head1 PRIMARY KEY @@ -241,8 +248,8 @@ __PACKAGE__->belongs_to( ); -# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-12-01 02:20:55 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:a7FCuypwxtuE6oJjEnRJRg +# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-12-12 02:41:09 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZF/YAX9BT1WrgCLUsXSqXQ __PACKAGE__->belongs_to( "borrower", 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 index 004acd1..6c7ce70 100644 --- 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 @@ -1 +1,2 @@ ALTER IGNORE TABLE issues ADD `noteseen` int(1) default NULL; +ALTER IGNORE TABLE old_issues ADD `noteseen` int(1) default NULL; 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..8e7272a --- /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_issue_notes', 'Mark issue notes as seen/not seen'); diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 62c3237..084975f 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -1808,6 +1808,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 885fbd7..adbe1fc 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_issue_notes', 'Mark issue 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/issue_notes/issue-notes.pl b/issue_notes/issue-notes.pl index a0b6927..54ae705 100644 --- a/issue_notes/issue-notes.pl +++ b/issue_notes/issue-notes.pl @@ -19,41 +19,13 @@ use Modern::Perl; -use strict; -use warnings; - use CGI qw ( -utf8 ); -use CGI::Cookie; # need to check cookies before having CGI parse the POST request use C4::Koha; use C4::Context; -use C4::Biblio; -use C4::Output qw(:DEFAULT :ajax); +use C4::Output; use C4::Auth; - -sub ajax_auth_cgi { # returns CGI object - my $needed_flags = shift; - my %cookies = fetch CGI::Cookie; - my $input = CGI->new; - my $sessid = $cookies{'CGISESSID'}->value; - my ($auth_status, $auth_sessid) = check_cookie_auth($sessid, $needed_flags); - if ($auth_status ne "ok") { - output_with_http_headers $input, undef, - "window.alert('Your CGI session cookie ($sessid) is not current. " . - "Please refresh the page and try again.');\n", 'js'; - exit 0; - } - return $input; -} - -if (is_ajax()) { - my $input = &ajax_auth_cgi({}) || CGI->new(); - my ($note, $js_reply); - if ($note = $input->param('seen')) { - $js_reply = ( markseen($note) ? 'success' : 'failure') . "_seen('$note');\n"; - } - output_with_http_headers $input, undef, $js_reply, 'js'; - exit; -} +use C4::Biblio; +use Koha::Issues; my $query = new CGI; @@ -68,46 +40,35 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); -my @notes = get_notes(); -my $pending_notes = Koha::Issues->search({ noteseen => 0 }); -#my $borrower = C4::Members::GetMember( borrowernumber => $notes->{'borrowernumber'} ); -#my $itemnumber = $notes->{'itemnumber'}; -#my $biblio = GetBiblioFromItemNumber($itemnumber); +my $schema = Koha::Database->new()->schema(); +my @notes = $schema->resultset('Issue')->search({ 'me.note' => { '!=', undef } }, { prefetch => [ 'borrower', { item => 'biblionumber' } ] }); $template->param( - notes => @notes, - pending => $pending_notes, -# title => $biblio->{'title'}, -# issuenote => $notes->{'note'}, -# barcode => $biblio->{'barcode'}, -# borrower => $borrower, -# date => $notes->{'notedate'}, + notes => \@notes, ); +my $action; +foreach (qw( seen notseen )) { + $action = $_ if ( $query->param("mark_selected-$_") ); +} +$action ||= 'none'; + +my @issue_ids = $query->multi_param('issue_ids'); -sub get_notes { - my $dbh = C4::Context->dbh; - my $q = "SELECT issues.borrowernumber AS borrowernumber, - issues.itemnumber AS itemnumber, - issues.note AS note, - issues.notedate AS notedate, - issues.noteseen AS noteseen, - borrowers.firstname AS firstname, - borrowers.surname AS surname, - items.barcode AS barcode, - biblio.title AS title, - biblio.author AS author - FROM issues - JOIN borrowers - ON issues.borrowernumber = borrowers.borrowernumber - JOIN items - ON issues.itemnumber = items.itemnumber - JOIN biblio - ON items.biblionumber = biblio.biblionumber - WHERE issues.note IS NOT NULL"; - my $sth = $dbh->prepare($q); - $sth->execute(); - return $sth->fetchall_arrayref({}); +if ( $action eq 'seen' ) { + foreach my $issue_id ( @issue_ids ) { + my $issue = Koha::Issues->find($issue_id); + $issue->set({ noteseen => 1 })->store; + } +} elsif ( $action eq 'notseen' ) { + foreach my $issue_id ( @issue_ids ) { + my $issue = Koha::Issues->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, undef, { force_no_caching => 1 }; 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 d700ba0..ba26480 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 @@ -30,7 +30,7 @@
  • Fast cataloging
  • [% END %] [% END %] -
  • Issue notes
  • + [% IF ( CAN_user_circulate_manage_issue_notes ) %]
  • Issue notes
  • [% 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 f09c9c1..74f6460 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt @@ -162,7 +162,7 @@ [% END %] - [% IF Koha.Preference('AllowIssueNotes') && pending_issue_notes %] + [% IF Koha.Preference('AllowIssueNotes') && CAN_user_circulate_manage_issue_notes && pending_issue_notes %]
    Issue notes pending: [% pending_issue_notes %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/issue_notes/issue-notes.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/issue_notes/issue-notes.tt index 54053f0..f068e77 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/issue_notes/issue-notes.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/issue_notes/issue-notes.tt @@ -2,10 +2,66 @@ [% USE KohaDates %] [% USE Branches %] [% INCLUDE 'doc-head-open.inc' %] -Home › Circulation › Issue Notes › Review Issue Notes +Home › Circulation › Issue Notes [% INCLUDE 'doc-head-close.inc' %] [% INCLUDE 'datatables.inc' %] + [% INCLUDE 'calendar.inc' %] @@ -14,41 +70,83 @@ -
    +

    Issue 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 %] +
    + Back to issue notes + [% ELSE %] + [% IF ( notes ) %] + +
    + Select all | Clear all +
    + +
    + + + - - + - [% FOREACH note in notes %] + [% FOREACH note IN notes %] + - - - - - + + + + + [% END %]
      NoteStatus TitleBarcode Date Set bySeenActions
    [% note.note %][% note.title %][% note.barcode %][% note.date %][% note.firstname %] [% note.surname %] ([% note.borrowernumber %])[% IF ( pending ) %][% ELSE %][% END %][% IF ( note.noteseen == 0 ) %] + Not seen + [% ELSIF ( note.noteseen == 1 ) %] + Seen + [% END %][% note.item.biblionumber.title %] - [% note.item.biblionumber.author %] ([% note.item.barcode %])[% note.notedate | $KohaDates %][% note.borrower.firstname %] [% note.borrower.surname %] ([% note.borrower.cardnumber %])[% IF ( note.noteseen == 1 ) %] + + [% ELSIF ( note.noteseen == 0 ) %] + + [% END %]
    - [% END %] + +
    + + +
    + +
    + + [% END %] + + [% END %]
    diff --git a/opac/opac-issue-note.pl b/opac/opac-issue-note.pl index 3568a8c..909a562 100755 --- a/opac/opac-issue-note.pl +++ b/opac/opac-issue-note.pl @@ -67,7 +67,7 @@ if ( $action eq 'issuenote' && C4::Context->preference('AllowIssueNotes') ) { 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 6a8981a..a322a74 100755 --- a/opac/svc/patron_notes +++ b/opac/svc/patron_notes @@ -79,7 +79,7 @@ if ($is_ajax) { $error = "Invalid issue id!"; } - if ( (not $error) && $issue->set({ notedate => dt_from_string(), note => $clean_note })->store ) { + if ( (not $error) && $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/issue_notes b/svc/issue_notes new file mode 100755 index 0000000..1c12a60 --- /dev/null +++ b/svc/issue_notes @@ -0,0 +1,73 @@ +#!/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 C4::Service; +use C4::Auth qw /check_cookie_auth/; +use CGI; +use C4::Output qw(:DEFAULT :ajax); +use Koha::Issues; + +=head1 NAME + +svc/issue_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'), {} ); +if ( $auth_status ne "ok" ) { + exit 0; +} +if ($is_ajax) { + my $issue_id = $query->param('issue_id'); + my $issue = Koha::Issues->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 $response = "{\"status\": \"$status\"}"; + output_with_http_headers $query, undef, $response, 'js'; + exit; +} + +my ( $template, $borrowernumber, $cookie ) = get_template_and_user({ + template_name => "issue_notes/issue-notes.tt", + query => $query, + type => "intranet", + debug => 1, + authnotrequired => 0, + flagsrequired => { circulation => 'manage_issue_notes' }, +}); + + -- 2.1.4