View | Details | Raw Unified | Return to bug 17698
Collapse All | Expand All

(-)a/Koha/Schema/Result/Issue.pm (-2 / +9 lines)
Lines 112-117 __PACKAGE__->table("issues"); Link Here
112
  datetime_undef_if_invalid: 1
112
  datetime_undef_if_invalid: 1
113
  is_nullable: 1
113
  is_nullable: 1
114
114
115
=head2 noteseen
116
117
  data_type: 'integer'
118
  is_nullable: 1
119
115
=cut
120
=cut
116
121
117
__PACKAGE__->add_columns(
122
__PACKAGE__->add_columns(
Lines 170-175 __PACKAGE__->add_columns( Link Here
170
    datetime_undef_if_invalid => 1,
175
    datetime_undef_if_invalid => 1,
171
    is_nullable => 1,
176
    is_nullable => 1,
172
  },
177
  },
178
  "noteseen",
179
  { data_type => "integer", is_nullable => 1 },
173
);
180
);
174
181
175
=head1 PRIMARY KEY
182
=head1 PRIMARY KEY
Lines 241-248 __PACKAGE__->belongs_to( Link Here
241
);
248
);
242
249
243
250
244
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-12-01 02:20:55
251
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-12-12 02:41:09
245
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:a7FCuypwxtuE6oJjEnRJRg
252
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZF/YAX9BT1WrgCLUsXSqXQ
246
253
247
__PACKAGE__->belongs_to(
254
__PACKAGE__->belongs_to(
248
    "borrower",
255
    "borrower",
(-)a/circ/circulation-home.pl (+3 lines)
Lines 22-27 use C4::Auth; Link Here
22
use C4::Output;
22
use C4::Output;
23
use C4::Context;
23
use C4::Context;
24
use Koha::BiblioFrameworks;
24
use Koha::BiblioFrameworks;
25
use Koha::Issues;
25
26
26
my $query = new CGI;
27
my $query = new CGI;
27
my ($template, $loggedinuser, $cookie, $flags) = get_template_and_user(
28
my ($template, $loggedinuser, $cookie, $flags) = get_template_and_user(
Lines 41-45 $template->param( fast_cataloging => 1 ) if Koha::BiblioFrameworks->find( 'FA' ) Link Here
41
$template->param( display_transfer => 1 ) if ( ($flags->{'superlibrarian'} == 1) || (C4::Context->preference("IndependentBranches") == 0) );
42
$template->param( display_transfer => 1 ) if ( ($flags->{'superlibrarian'} == 1) || (C4::Context->preference("IndependentBranches") == 0) );
42
$template->{'VARS'}->{'AllowOfflineCirculation'} = C4::Context->preference('AllowOfflineCirculation');
43
$template->{'VARS'}->{'AllowOfflineCirculation'} = C4::Context->preference('AllowOfflineCirculation');
43
44
45
my $pendingissuenotes = Koha::Issues->search({ noteseen => 0 })->count;
46
$template->param( pendingissuenotes => $pendingissuenotes );
44
47
45
output_html_with_http_headers $query, $cookie, $template->output;
48
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/installer/data/mysql/atomicupdate/bug-17698_add-noteseen-column-to-issues.sql (+2 lines)
Line 0 Link Here
1
ALTER IGNORE TABLE issues ADD `noteseen` int(1) default NULL;
2
ALTER IGNORE TABLE old_issues ADD `noteseen` int(1) default NULL;
(-)a/installer/data/mysql/atomicupdate/bug-17698_add-permission-to-manage-issue-notes.sql (+1 lines)
Line 0 Link Here
1
INSERT INTO permissions (module_bit, code, description) VALUES ( 1, 'manage_issue_notes', 'Mark issue notes as seen/not seen');
(-)a/installer/data/mysql/kohastructure.sql (+1 lines)
Lines 1777-1782 CREATE TABLE `old_issues` ( -- lists items that were checked out and have been r Link Here
1777
  `onsite_checkout` int(1) NOT NULL default 0, -- in house use flag
1777
  `onsite_checkout` int(1) NOT NULL default 0, -- in house use flag
1778
  `note` mediumtext default NULL, -- issue note text
1778
  `note` mediumtext default NULL, -- issue note text
1779
  `notedate` datetime default NULL, -- datetime of issue note (yyyy-mm-dd hh:mm::ss)
1779
  `notedate` datetime default NULL, -- datetime of issue note (yyyy-mm-dd hh:mm::ss)
1780
  `noteseen` int(1) default NULL, -- describes whether issue note has been seen 1, not been seen 0 or doesn't exist null
1780
  PRIMARY KEY (`issue_id`),
1781
  PRIMARY KEY (`issue_id`),
1781
  KEY `old_issuesborridx` (`borrowernumber`),
1782
  KEY `old_issuesborridx` (`borrowernumber`),
1782
  KEY `old_issuesitemidx` (`itemnumber`),
1783
  KEY `old_issuesitemidx` (`itemnumber`),
(-)a/installer/data/mysql/userpermissions.sql (+1 lines)
Lines 5-10 INSERT INTO permissions (module_bit, code, description) VALUES Link Here
5
   ( 1, 'force_checkout', 'Force checkout if a limitation exists'),
5
   ( 1, 'force_checkout', 'Force checkout if a limitation exists'),
6
   ( 1, 'manage_restrictions', 'Manage restrictions for accounts'),
6
   ( 1, 'manage_restrictions', 'Manage restrictions for accounts'),
7
   ( 1, 'self_checkout', 'Perform self checkout at the OPAC. It should be used for the patron matching the AutoSelfCheckID'),
7
   ( 1, 'self_checkout', 'Perform self checkout at the OPAC. It should be used for the patron matching the AutoSelfCheckID'),
8
   ( 1, 'manage_issue_notes', 'Mark issue notes as seen/not seen'),
8
   ( 3, 'parameters_remaining_permissions', 'Remaining system parameters permissions'),
9
   ( 3, 'parameters_remaining_permissions', 'Remaining system parameters permissions'),
9
   ( 3, 'manage_circ_rules', 'Manage circulation rules'),
10
   ( 3, 'manage_circ_rules', 'Manage circulation rules'),
10
   ( 6, 'place_holds', 'Place holds for patrons'),
11
   ( 6, 'place_holds', 'Place holds for patrons'),
(-)a/issue_notes/issue-notes.pl (+74 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2016 Aleisha Amohia <aleisha@catalyst.net.nz>
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use CGI qw ( -utf8 );
23
use C4::Koha;
24
use C4::Context;
25
use C4::Output;
26
use C4::Auth;
27
use C4::Biblio;
28
use Koha::Issues;
29
30
my $query = new CGI;
31
32
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
33
    {
34
        template_name   => "issue_notes/issue-notes.tt",
35
        query           => $query,
36
        type            => "intranet",
37
        authnotrequired => 0,
38
        flagsrequired   => { circulation => 1 },
39
        debug           => 1,
40
    }
41
);
42
43
my $schema = Koha::Database->new()->schema();
44
my @notes = $schema->resultset('Issue')->search({ 'me.note' => { '!=', undef } }, { prefetch => [ 'borrower', { item => 'biblionumber' } ] });
45
$template->param(
46
    notes     => \@notes,
47
);
48
49
my $action;
50
foreach (qw( seen notseen )) {
51
    $action = $_ if ( $query->param("mark_selected-$_") );
52
}
53
$action ||= 'none';
54
55
my @issue_ids = $query->multi_param('issue_ids');
56
57
if ( $action eq 'seen' ) {
58
    foreach my $issue_id ( @issue_ids ) {
59
        my $issue = Koha::Issues->find($issue_id);
60
        $issue->set({ noteseen => 1 })->store;
61
    }
62
} elsif ( $action eq 'notseen' ) {
63
    foreach my $issue_id ( @issue_ids ) {
64
        my $issue = Koha::Issues->find($issue_id);
65
        $issue->set({ noteseen => 0 })->store;
66
    }
67
}
68
69
$template->param(
70
    selected_count => scalar(@issue_ids),
71
    action         => $action,
72
);
73
74
output_html_with_http_headers $query, $cookie, $template->output, undef, { force_no_caching => 1 };
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc (+1 lines)
Lines 30-35 Link Here
30
    [%- CASE 'overdues_report' -%]<span>Execute overdue items report</span>
30
    [%- CASE 'overdues_report' -%]<span>Execute overdue items report</span>
31
    [%- CASE 'override_renewals' -%]<span>Override blocked renewals</span>
31
    [%- CASE 'override_renewals' -%]<span>Override blocked renewals</span>
32
    [%- CASE 'self_checkout' -%]<span>Perform self checkout at the OPAC. It should be used for the patron matching the AutoSelfCheckID</span>
32
    [%- CASE 'self_checkout' -%]<span>Perform self checkout at the OPAC. It should be used for the patron matching the AutoSelfCheckID</span>
33
    [%- CASE 'manage_issue_notes' -%]<span>Mark issue notes as seen/notseen</span>
33
    [%- CASE 'manage_circ_rules' -%]<span>manage circulation rules</span>
34
    [%- CASE 'manage_circ_rules' -%]<span>manage circulation rules</span>
34
    [%- CASE 'parameters_remaining_permissions' -%]<span>Remaining system parameters permissions</span>
35
    [%- CASE 'parameters_remaining_permissions' -%]<span>Remaining system parameters permissions</span>
35
    [%- CASE 'modify_holds_priority' -%]<span>Modify holds priority</span>
36
    [%- CASE 'modify_holds_priority' -%]<span>Modify holds priority</span>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt (+1 lines)
Lines 30-35 Link Here
30
		<li><a href="/cgi-bin/koha/cataloguing/addbiblio.pl?frameworkcode=FA">Fast cataloging</a></li>
30
		<li><a href="/cgi-bin/koha/cataloguing/addbiblio.pl?frameworkcode=FA">Fast cataloging</a></li>
31
	    [% END %]
31
	    [% END %]
32
	[% END %]
32
	[% END %]
33
        [% IF ( CAN_user_circulate_manage_issue_notes ) %]<li><a href="/cgi-bin/koha/issue_notes/issue-notes.pl">Issue notes</a> [% IF ( pendingissuenotes ) %]<span class="number_box"><a href="/cgi-bin/koha/reviews/reviewswaiting.pl">[% pendingissuenotes %]</a></span>[% END %]</li>[% END %]
33
	</ul>
34
	</ul>
34
	</div>
35
	</div>
35
36
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt (+7 lines)
Lines 162-167 Link Here
162
                    </div>
162
                    </div>
163
                    [% END %]
163
                    [% END %]
164
164
165
                    [% IF Koha.Preference('AllowIssueNotes') && CAN_user_circulate_manage_issue_notes && pending_issue_notes %]
166
                    <div class="pending-info" id="issue_notes_pending">
167
                        <a href="/cgi-bin/koha/issue_notes/issue-notes.pl">Issue notes pending</a>:
168
                        <span class="pending-number-link">[% pending_issue_notes %]</span>
169
                    </div>
170
                    [% END %]
171
165
                </div>
172
                </div>
166
173
167
            [% END %]
174
            [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/issue_notes/issue-notes.tt (+155 lines)
Line 0 Link Here
1
[% USE Koha %]
2
[% USE KohaDates %]
3
[% USE Branches %]
4
[% INCLUDE 'doc-head-open.inc' %]
5
<title>Home &rsaquo; Circulation &rsaquo; Issue Notes</title>
6
[% INCLUDE 'doc-head-close.inc' %]
7
<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/css/datatables.css" />
8
[% INCLUDE 'datatables.inc' %]
9
<script type="text/javascript">
10
//<![CDATA[
11
    $(document).ready(function(){
12
        $("#notestable").dataTable($.extend(true, {}, dataTablesDefaults, {
13
            "aoColumnDefs": [
14
                { "aTargets": [ 0, -1 ], "bSearchable": false, "bSortable": false },
15
            ],
16
            "sPaginationType": "four_button"
17
        }));
18
19
        $(".SelectAll").on("click", function(){
20
            $("input[name='issue_ids'][type='checkbox']").prop("checked", true);
21
        });
22
23
        $(".ClearAll").on("click", function(){
24
            $("input[name='issue_ids'][type='checkbox']").prop("checked", false);
25
        });
26
27
        $("#error").hide();
28
29
        $(".btn-mini").click(function(event){
30
            event.preventDefault(); // prevent form submission
31
            var $action = $(this).attr("name");
32
            var $issue_id = $(this).data('issue_id');
33
            var ajaxData = {
34
                'action': $action,
35
                'issue_id': $issue_id,
36
            };
37
38
            $.ajax({
39
                url: '/cgi-bin/koha/svc/issue_notes/',
40
                type: 'POST',
41
                dataType: 'json',
42
                data: ajaxData,
43
            })
44
45
            .done(function(data){
46
                if (data.status == 'success'){
47
                    if ( $action == 'notseen' ){
48
                        $("#status_" + $issue_id).text("Not seen");
49
                        $(event.target).siblings(".seen").prop("disabled", false);
50
                        $(event.target).prop("disabled", true);
51
                    } else {
52
                        $("#status_" + $issue_id).text("Seen");
53
                        $(event.target).siblings(".notseen").prop("disabled", false);
54
                        $(event.target).prop("disabled", true);
55
                    }
56
                } else {
57
                    $("#error").text("Unable to change status of note.");
58
                    $("#error").show();
59
                }
60
            });
61
        });
62
    });
63
//]]>
64
</script>
65
[% INCLUDE 'calendar.inc' %]
66
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
67
</head>
68
[% INCLUDE 'header.inc' %]
69
[% INCLUDE 'circ-search.inc' %]
70
<div id="breadcrumbs">
71
    <a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo;
72
    <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a> &rsaquo;
73
    Issue notes
74
</div>
75
76
<div id="doc" class="yui-t7"> <!-- <div id="doc3" class="yui-t2" -->
77
    <div id="bd">
78
        <div id="yui-main">
79
80
            <h1>Issue notes</h1>
81
82
            <div class="dialog alert" id="error"></div>
83
84
            [% IF ( selected_count ) %]
85
                <div class="dialog message">
86
                    [% IF ( action == 'seen' ) %]
87
                        [% selected_count %] note(s) marked as seen.
88
                    [% ELSIF ( action == 'notseen' ) %]
89
                        [% selected_count %] note(s) marked as not seen.
90
                    [% ELSE %]
91
                        Failed to change the status of [% selected_count %] item(s).
92
                    [% END %]
93
                </div>
94
                <a href="/cgi-bin/koha/issue_notes/issue-notes.pl" class="btn btn-small"><i class="fa fa-left"></i> Back to issue notes</a>
95
            [% ELSE %]
96
97
            [% IF ( notes ) %]
98
99
            <fieldset class="action">
100
                <a class="SelectAll"><i class="fa fa-check"></i> Select all</a> | <a class="ClearAll"><i class="fa fa-remove"></i> Clear all</a>
101
            </fieldset>
102
103
            <form id="mark_selected" method="post" action="/cgi-bin/koha/issue_notes/issue-notes.pl">
104
105
            <table id="notestable">
106
                <thead>
107
                    <tr>
108
                        <th>&nbsp;</th>
109
                        <th>Note</th>
110
                        <th>Status</th>
111
                        <th>Title</th>
112
                        <th>Date</th>
113
                        <th>Set by</th>
114
                        <th>Actions</th>
115
                    </tr>
116
                </thead>
117
                <tbody>
118
                [% FOREACH note IN notes %]
119
                    <tr>
120
                        <td><input type="checkbox" name="issue_ids" value="[% note.issue_id %]"></td>
121
                        <td>[% note.note %]</td>
122
                        <td>[% IF ( note.noteseen == 0 ) %]
123
                            <span id="status_[% note.issue_id %]">Not seen</span>
124
                        [% ELSIF ( note.noteseen == 1 ) %]
125
                            <span id="status_[% note.issue_id %]">Seen</span>
126
                        [% END %]</td>
127
                        <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>
128
                        <td>[% note.notedate | $KohaDates %]</td>
129
                        <td>[% note.borrower.firstname %] [% note.borrower.surname %] (<a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% note.borrower.borrowernumber %]">[% note.borrower.cardnumber %]</a>)</td>
130
                        <td class="actions">[% IF ( note.noteseen == 1 ) %]
131
                            <button name="seen" data-issue_id="[% note.issue_id %]" class="seen btn btn-mini" disabled="disabled"><i class="fa fa-eye"></i> Mark seen</button> <button name="notseen" data-issue_id="[% note.issue_id %]" class="notseen btn btn-mini"><i class="fa fa-eye-slash"></i> Mark not seen</button>
132
                        [% ELSIF ( note.noteseen == 0 ) %]
133
                            <button name="seen" data-issue_id="[% note.issue_id %]" class="seen btn btn-mini"><i class="fa fa-eye"></i> Mark seen</button> <button name="notseen" data-issue_id="[% note.issue_id %]" class="notseen btn btn-mini" disabled="disabled"><i class="fa fa-eye-slash"></i> Mark not seen</button>
134
                        [% END %]</td>
135
                    </tr>
136
                [% END %]
137
                </tbody>
138
            </table>
139
140
            <fieldset class="action">
141
                <button type="submit" class="btn btn-small" name="mark_selected-seen" value="seen"><i class="fa fa-eye"></i> Mark seen</button>
142
                <button type="submit" class="btn btn-small" name="mark_selected-notseen" value="notseen"><i class="fa fa-eye-slash"></i> Mark not seen</button>
143
            </fieldset>
144
145
            </form>
146
147
            [% END %] <!-- notes -->
148
149
            [% END %] <!-- selected_count -->
150
151
        </div> <!-- yui-main -->
152
    </div> <!-- bd -->
153
</div> <!-- doc3 -->
154
155
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/opac/opac-issue-note.pl (-1 / +1 lines)
Lines 67-73 if ( $action eq 'issuenote' && C4::Context->preference('AllowIssueNotes') ) { Link Here
67
    my $note = $query->param('note');
67
    my $note = $query->param('note');
68
    my $scrubber = C4::Scrubber->new();
68
    my $scrubber = C4::Scrubber->new();
69
    my $clean_note = $scrubber->scrub($note);
69
    my $clean_note = $scrubber->scrub($note);
70
    if ( $issue->set({ notedate => dt_from_string(), note => $clean_note })->store ) {
70
    if ( $issue->set({ notedate => dt_from_string(), note => $clean_note, noteseen => 0 })->store ) {
71
        if ($clean_note) { # only send email if note not empty
71
        if ($clean_note) { # only send email if note not empty
72
            my $branch = Koha::Libraries->find( $issue->branchcode );
72
            my $branch = Koha::Libraries->find( $issue->branchcode );
73
            my $letter = C4::Letters::GetPreparedLetter (
73
            my $letter = C4::Letters::GetPreparedLetter (
(-)a/opac/svc/patron_notes (-1 / +1 lines)
Lines 79-85 if ($is_ajax) { Link Here
79
            $error = "Invalid issue id!";
79
            $error = "Invalid issue id!";
80
        }
80
        }
81
81
82
        if ( (not $error) && $issue->set({ notedate => dt_from_string(), note => $clean_note })->store ) {
82
        if ( (not $error) && $issue->set({ notedate => dt_from_string(), note => $clean_note, noteseen => 0 })->store ) {
83
            if($clean_note) { # only send email if note not empty
83
            if($clean_note) { # only send email if note not empty
84
                my $branch = Koha::Libraries->find( $issue->branchcode );
84
                my $branch = Koha::Libraries->find( $issue->branchcode );
85
                my $biblio = GetBiblioFromItemNumber($issue->itemnumber);
85
                my $biblio = GetBiblioFromItemNumber($issue->itemnumber);
(-)a/svc/issue_notes (-1 / +71 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Copyright 2017 Aleisha Amohia <aleisha@catalyst.net.nz>
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use C4::Service;
23
use C4::Auth qw /check_cookie_auth/;
24
use CGI;
25
use C4::Output qw(:DEFAULT :ajax);
26
use Koha::Issues;
27
28
=head1 NAME
29
30
svc/issue_notes - Web service for managing patron notes set on issues
31
32
=head1 DESCRIPTION
33
34
=cut
35
36
# AJAX requests
37
my $is_ajax = is_ajax();
38
my $query = new CGI;
39
my ( $auth_status, $sessionID ) = check_cookie_auth( $query->cookie('CGISESSID'), {} );
40
if ( $auth_status ne "ok" ) {
41
    exit 0;
42
}
43
if ($is_ajax) {
44
    my $issue_id = $query->param('issue_id');
45
    my $issue = Koha::Issues->find($issue_id);
46
    my $action = $query->param('action');
47
    my $status = 'success';
48
    if ($action eq 'seen'){
49
        $issue->set({ noteseen => 1 })->store;
50
        if ( $issue->noteseen != 1 ) {
51
            $status = 'failure';
52
        }
53
    } elsif ($action eq 'notseen'){
54
        $issue->set({ noteseen => 0 })->store;
55
        if ( $issue->noteseen != 0 ) {
56
            $status = 'failure';
57
        }
58
    }
59
    my $response = "{\"status\": \"$status\"}";
60
    output_with_http_headers $query, undef, $response, 'js';
61
    exit;
62
}
63
64
my ( $template, $borrowernumber, $cookie ) = get_template_and_user({
65
    template_name   => "issue_notes/issue-notes.tt",
66
    query           => $query,
67
    type            => "intranet",
68
    debug           => 1,
69
    authnotrequired => 0,
70
    flagsrequired   => { circulation => 'manage_issue_notes' },
71
});

Return to bug 17698