--- /dev/null
+#!/usr/bin/perl
+
+# Copyright 2016 Aleisha Amohia <aleisha@catalyst.net.nz>
+#
+# 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 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;
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(
$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;
--- /dev/null
+$DBversion = 'XXX';
+if( CheckVersion( $DBversion ) ) {
+ unless( column_exists( 'issues', 'noteseen' ) ) {
+ $dbh->do(q|ALTER TABLE issues ADD COLUMN noteseen int(1) default NULL AFTER notedate|);
+ }
+
+ unless( column_exists( 'old_issues', 'noteseen' ) ) {
+ $dbh->do(q|ALTER TABLE old_issues ADD COLUMN 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";
+}
--- /dev/null
+INSERT INTO permissions (module_bit, code, description) VALUES ( 1, 'manage_checkout_nots', 'Mark checkout notes as seen/not seen');
`onsite_checkout` int(1) NOT NULL default 0, -- in house use flag
`note` LONGTEXT 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 checkout note has been seen 1, not been seen 0 or doesn't exist null
PRIMARY KEY (`issue_id`),
UNIQUE KEY `itemnumber` (`itemnumber`),
KEY `issuesborridx` (`borrowernumber`),
`onsite_checkout` int(1) NOT NULL default 0, -- in house use flag
`note` LONGTEXT 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 checkout 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`),
( 1, 'overdues_report', 'Execute overdue items report'),
( 1, 'force_checkout', 'Force checkout if a limitation exists'),
( 1, 'manage_restrictions', 'Manage restrictions for accounts'),
+ ( 1, 'manage_checkout_nots', 'Mark checkout notes as seen/not seen'),
( 3, 'parameters_remaining_permissions', 'Remaining system parameters permissions'),
( 3, 'manage_circ_rules', 'Manage circulation rules'),
( 4, 'edit_borrowers', 'Add, modify and view patron information'),
[%- CASE 'manage_restrictions' -%]<span>Manage restrictions for accounts</span>
[%- CASE 'overdues_report' -%]<span>Execute overdue items report</span>
[%- CASE 'override_renewals' -%]<span>Override blocked renewals</span>
+ [%- CASE 'manage_checkout_notes' %]<span>Mark checkout notes as seen/not seen</span>
[%- CASE 'manage_circ_rules' -%]<span>manage circulation rules</span>
[%- CASE 'parameters_remaining_permissions' -%]<span>Remaining system parameters permissions</span>
[%- CASE 'edit_borrowers' -%]<span>Add, modify and view patron information</span>
--- /dev/null
+[% USE Koha %]
+[% USE KohaDates %]
+[% USE Branches %]
+[% INCLUDE 'doc-head-open.inc' %]
+<title>Home › Circulation › Checkout Notes</title>
+[% INCLUDE 'doc-head-close.inc' %]
+<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/css/datatables.css" />
+[% INCLUDE 'datatables.inc' %]
+<script type="text/javascript">
+//<![CDATA[
+ $(document).ready(function(){
+ $("#notestable").dataTable($.extend(true, {}, dataTablesDefaults, {
+ "aoColumnDefs": [
+ { "aTargets": [ 0, -1 ], "bSearchable": false, "bSortable": false },
+ ],
+ "sPaginationType": "four_button"
+ }));
+
+ $(".SelectAll").on("click", function(){
+ $("input[name='issue_ids'][type='checkbox']").prop("checked", true);
+ $(".btn-sm").prop("disabled", false);
+ });
+
+ $(".ClearAll").on("click", function(){
+ $("input[name='issue_ids'][type='checkbox']").prop("checked", false);
+ $(".btn-sm").prop("disabled", true);
+ });
+
+ $("#error").hide();
+
+ $("input[type='checkbox']").click(function(event){
+ if ( $("input[type='checkbox']").is(":checked") ) {
+ $(".btn-sm").prop("disabled", false);
+ } else {
+ $(".btn-sm").prop("disabled", true);
+ }
+ });
+
+ $(".btn-xs").click(function(event){
+ event.preventDefault(); // prevent form submission
+ var $action = $(this).attr("name");
+ var $issue_id = $(this).data('issue_id');
+ var ajaxData = {
+ 'action': $action,
+ 'issue_id': $issue_id,
+ };
+
+ $.ajax({
+ url: '/cgi-bin/koha/svc/checkout_notes/',
+ type: 'POST',
+ dataType: 'json',
+ data: ajaxData,
+ })
+
+ .done(function(data){
+ if (data.status == 'success'){
+ if ( $action == 'notseen' ){
+ $("#status_" + $issue_id).text("Not seen");
+ $(event.target).siblings(".seen").prop("disabled", false);
+ $(event.target).prop("disabled", true);
+ } else {
+ $("#status_" + $issue_id).text("Seen");
+ $(event.target).siblings(".notseen").prop("disabled", false);
+ $(event.target).prop("disabled", true);
+ }
+ } else {
+ $("#error").text(_("Unable to change status of note."));
+ $("#error").show();
+ }
+ });
+ });
+ });
+//]]>
+</script>
+[% INCLUDE 'calendar.inc' %]
+<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
+</head>
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'circ-search.inc' %]
+<div id="breadcrumbs">
+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> ›
+ <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a> ›
+ Checkout notes
+</div>
+
+<div id="doc" class="yui-t7"> <!-- <div id="doc3" class="yui-t2" -->
+ <div id="bd">
+ <div id="yui-main">
+
+ <h1>Checkout notes</h1>
+
+ <div class="dialog alert" id="error"></div>
+
+ [% IF ( selected_count ) %]
+ <div class="dialog message">
+ [% 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 %]
+ </div>
+ <a href="/cgi-bin/koha/circ/checkout-notes.pl" class="btn btn-default btn-sm"><i class="fa fa-left"></i> Return to checkout notes</a>
+ [% ELSE %]
+
+ [% IF ( notes ) %]
+ <fieldset class="action">
+ <a class="SelectAll"><i class="fa fa-check"></i> Select all</a> | <a class="ClearAll"><i class="fa fa-remove"></i> Clear all</a>
+ </fieldset>
+
+ <form id="mark_selected" method="post" action="/cgi-bin/koha/circ/checkout-notes.pl">
+
+ <table id="notestable">
+ <thead>
+ <tr>
+ <th> </th>
+ <th>Title</th>
+ <th>Note</th>
+ <th>Date</th>
+ <th>Set by</th>
+ <th>Status</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ [% FOREACH note IN notes %]
+ <tr>
+ <td><input type="checkbox" name="issue_ids" value="[% note.issue_id %]"></td>
+ <td>[% note.item.biblionumber.title %] - [% note.item.biblionumber.author %] (<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% note.item.biblionumber.biblionumber %]">[% note.item.barcode %]</a>)</td>
+ <td>[% note.note %]</td>
+ <td>[% note.notedate | $KohaDates %]</td>
+ <td>[% note.borrower.firstname %] [% note.borrower.surname %] (<a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% note.borrower.borrowernumber %]">[% note.borrower.cardnumber %]</a>)</td>
+ <td>[% IF ( note.noteseen == 0 ) %]
+ <span id="status_[% note.issue_id %]">Not seen</span>
+ [% ELSIF ( note.noteseen == 1 ) %]
+ <span id="status_[% note.issue_id %]">Seen</span>
+ [% END %]</td>
+ <td class="actions">[% IF ( note.noteseen == 1 ) %]
+ <button name="seen" data-issue_id="[% note.issue_id %]" class="seen btn btn-default btn-xs" disabled="disabled"><i class="fa fa-eye"></i> Mark seen</button> <button name="notseen" data-issue_id="[% note.issue_id %]" class="notseen btn btn-default btn-xs"><i class="fa fa-eye-slash"></i> Mark not seen</button>
+ [% ELSIF ( note.noteseen == 0 ) %]
+ <button name="seen" data-issue_id="[% note.issue_id %]" class="seen btn btn-default btn-xs"><i class="fa fa-eye"></i> Mark seen</button> <button name="notseen" data-issue_id="[% note.issue_id %]" class="notseen btn btn-default btn-xs" disabled="disabled"><i class="fa fa-eye-slash"></i> Mark not seen</button>
+ [% END %]</td>
+ </tr>
+ [% END %]
+ </tbody>
+ </table>
+
+ <fieldset class="action">
+ <button type="submit" class="btn btn-default btn-sm" name="mark_selected-seen" value="seen" disabled="disabled"><i class="fa fa-eye"></i> Mark seen</button>
+ <button type="submit" class="btn btn-default btn-sm" name="mark_selected-notseen" value="notseen" disabled="disabled"><i class="fa fa-eye-slash"></i> Mark not seen</button>
+ </fieldset>
+
+ </form>
+
+ [% END %] <!-- notes -->
+
+ [% END %] <!-- selected_count -->
+
+ </div> <!-- yui-main -->
+ </div> <!-- bd -->
+</div> <!-- doc3 -->
+
+[% INCLUDE 'intranet-bottom.inc' %]
</li>
[% END %]
[% END %]
+ [% IF ( Koha.Preference('AllowCheckoutNotes') && CAN_user_circulate_manage_checkout_notes ) %]
+ <li>
+ <a href="/cgi-bin/koha/circ/checkout-notes.pl">Checkout notes</a> [% IF ( pending_checkout_notes ) %]<span class="number_box"><a href="/cgi-bin/koha/circ/checkout-notes.pl">[% pending_checkout_notes %]</a></span>[% END %]
+ </li>
+ [% END %]
</ul>
</div>
</div>
[% END %]
+ [% IF Koha.Preference('AllowCheckoutNotes') && CAN_user_circulate_manage_checkout_notes && pending_checkout_notes %]
+ <div class="pending-info" id="checkout_notes_pending">
+ <a href="/cgi-bin/koha/circ/checkout-notes.pl">Checkout notes pending</a>:
+ <span class="pending-number-link">[% pending_checkout_notes %]</span>
+ </div>
+ [% END %]
+
</div>
[% END %]
use Koha::Patron::Discharge;
use Koha::Reviews;
use Koha::ArticleRequests;
+use Koha::Checkouts;
my $query = new CGI;
$branch ? ( branchcode => $branch ) : (),
}
)->count;
+my $pending_checkout_notes = Koha::Checkouts->search({ noteseen => 0 })->count;
$template->param(
pendingcomments => $pendingcomments,
pending_borrower_modifications => $pending_borrower_modifications,
pending_discharge_requests => $pending_discharge_requests,
pending_article_requests => $pending_article_requests,
+ pending_checkout_notes => $pending_checkout_notes,
);
output_html_with_http_headers $query, $cookie, $template->output;
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 (
}
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 $biblionumber = $issue->item->biblionumber;
--- /dev/null
+#!/usr/bin/perl
+
+# This file is part of Koha.
+#
+# Copyright 2017 Aleisha Amohia <aleisha@catalyst.net.nz>
+#
+# 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 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;
+}