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

(-)a/C4/Circulation.pm (-1 lines)
Lines 2509-2515 sub GetOpenIssue { Link Here
2509
=head2 GetIssues
2509
=head2 GetIssues
2510
2510
2511
    $issues = GetIssues({});    # return all issues!
2511
    $issues = GetIssues({});    # return all issues!
2512
    $issues = GetIssues({ borrowernumber => $borrowernumber, biblionumber => $biblionumber });
2513
2512
2514
Returns all pending issues that match given criteria.
2513
Returns all pending issues that match given criteria.
2515
Returns a arrayref or undef if an error occurs.
2514
Returns a arrayref or undef if an error occurs.
(-)a/Koha/Schema/Result/Issue.pm (-2 / +21 lines)
Lines 101-106 __PACKAGE__->table("issues"); Link Here
101
  default_value: 0
101
  default_value: 0
102
  is_nullable: 0
102
  is_nullable: 0
103
103
104
=head2 note
105
106
  data_type: 'mediumtext'
107
  is_nullable: 1
108
109
=head2 notedate
110
111
  data_type: 'datetime'
112
  datetime_undef_if_invalid: 1
113
  is_nullable: 1
114
104
=cut
115
=cut
105
116
106
__PACKAGE__->add_columns(
117
__PACKAGE__->add_columns(
Lines 151-156 __PACKAGE__->add_columns( Link Here
151
  },
162
  },
152
  "onsite_checkout",
163
  "onsite_checkout",
153
  { data_type => "integer", default_value => 0, is_nullable => 0 },
164
  { data_type => "integer", default_value => 0, is_nullable => 0 },
165
  "note",
166
  { data_type => "mediumtext", is_nullable => 1 },
167
  "notedate",
168
  {
169
    data_type => "datetime",
170
    datetime_undef_if_invalid => 1,
171
    is_nullable => 1,
172
  },
154
);
173
);
155
174
156
=head1 PRIMARY KEY
175
=head1 PRIMARY KEY
Lines 222-229 __PACKAGE__->belongs_to( Link Here
222
);
241
);
223
242
224
243
225
# Created by DBIx::Class::Schema::Loader v0.07039 @ 2015-11-04 12:00:58
244
# Created by DBIx::Class::Schema::Loader v0.07042 @ 2016-12-01 02:20:55
226
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:kREecsHr6wZPiokS946BHw
245
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:a7FCuypwxtuE6oJjEnRJRg
227
246
228
__PACKAGE__->belongs_to(
247
__PACKAGE__->belongs_to(
229
    "borrower",
248
    "borrower",
(-)a/circ/returns.pl (+3 lines)
Lines 282-287 if ($barcode) { Link Here
282
    my $descriptions = Koha::AuthorisedValues->get_description_by_koha_field({frameworkcode => '', kohafield =>'items.materials', authorised_value => $materials });
282
    my $descriptions = Koha::AuthorisedValues->get_description_by_koha_field({frameworkcode => '', kohafield =>'items.materials', authorised_value => $materials });
283
    $materials = $descriptions->{lib} // '';
283
    $materials = $descriptions->{lib} // '';
284
284
285
    my $issue = GetItemIssue($itemnumber);
286
285
    $template->param(
287
    $template->param(
286
        title            => $biblio->{'title'},
288
        title            => $biblio->{'title'},
287
        homebranch       => $biblio->{'homebranch'},
289
        homebranch       => $biblio->{'homebranch'},
Lines 295-300 if ($barcode) { Link Here
295
        biblionumber     => $biblio->{'biblionumber'},
297
        biblionumber     => $biblio->{'biblionumber'},
296
        borrower         => $borrower,
298
        borrower         => $borrower,
297
        additional_materials => $materials,
299
        additional_materials => $materials,
300
        issue            => $issue,
298
    );
301
    );
299
302
300
    my %input = (
303
    my %input = (
(-)a/installer/data/mysql/atomicupdate/bug_14224-add_new_issue_columns.sql (+2 lines)
Line 0 Link Here
1
ALTER IGNORE TABLE issues ADD `note` mediumtext default NULL;
2
ALTER IGNORE TABLE issues ADD `notedate` datetime default NULL;
(-)a/installer/data/mysql/atomicupdate/bug_14224-add_patron_notice_to_letters.sql (+1 lines)
Line 0 Link Here
1
INSERT IGNORE INTO letter (`module`, `code`, `branchcode`, `name`, `is_html`, `title`, `content`, `message_transport_type`) VALUES ('circulation', 'PATRON_NOTE', '', 'Patron note on item', '0', 'Patron issue note', '<<borrowers.firstname>> <<borrowers.surname>> has added a note to the item <<biblio.item>> - <<biblio.author>> (<<biblio.biblionumber>>).','email');
(-)a/installer/data/mysql/atomicupdate/bug_14224-issue_notes_syspref.sql (+1 lines)
Line 0 Link Here
1
INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`,`type`) VALUES ('AllowIssueNotes', '0', NULL, 'Allow patrons to submit notes about checked out items.','YesNo');
(-)a/installer/data/mysql/kohastructure.sql (+30 lines)
Lines 841-846 CREATE TABLE `import_items` ( Link Here
841
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
841
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
842
842
843
--
843
--
844
-- Table structure for table `issues`
845
--
846
847
DROP TABLE IF EXISTS `issues`;
848
CREATE TABLE `issues` ( -- information related to check outs or issues
849
  `issue_id` int(11) NOT NULL AUTO_INCREMENT, -- primary key for issues table
850
  `borrowernumber` int(11), -- foreign key, linking this to the borrowers table for the patron this item was checked out to
851
  `itemnumber` int(11), -- foreign key, linking this to the items table for the item that was checked out
852
  `date_due` datetime default NULL, -- datetime the item is due (yyyy-mm-dd hh:mm::ss)
853
  `branchcode` varchar(10) default NULL, -- foreign key, linking to the branches table for the location the item was checked out
854
  `returndate` datetime default NULL, -- date the item was returned, will be NULL until moved to old_issues
855
  `lastreneweddate` datetime default NULL, -- date the item was last renewed
856
  `return` varchar(4) default NULL,
857
  `renewals` tinyint(4) default NULL, -- lists the number of times the item was renewed
858
  `auto_renew` BOOLEAN default FALSE, -- automatic renewal
859
  `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, -- the date and time this record was last touched
860
  `issuedate` datetime default NULL, -- date the item was checked out or issued
861
  `onsite_checkout` int(1) NOT NULL default 0, -- in house use flag
862
  `note` mediumtext default NULL, -- issue note text
863
  `notedate` datetime default NULL, -- datetime of issue note (yyyy-mm-dd hh:mm::ss)
864
  PRIMARY KEY (`issue_id`),
865
  KEY `issuesborridx` (`borrowernumber`),
866
  KEY `itemnumber_idx` (`itemnumber`),
867
  KEY `branchcode_idx` (`branchcode`),
868
  KEY `bordate` (`borrowernumber`,`timestamp`),
869
  CONSTRAINT `issues_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE RESTRICT ON UPDATE CASCADE,
870
  CONSTRAINT `issues_ibfk_2` FOREIGN KEY (`itemnumber`) REFERENCES `items` (`itemnumber`) ON DELETE RESTRICT ON UPDATE CASCADE
871
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
872
873
--
844
-- Table structure for table `issuingrules`
874
-- Table structure for table `issuingrules`
845
--
875
--
846
876
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 29-34 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
29
('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
29
('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
30
('AllowOfflineCirculation','0','','If on, enables HTML5 offline circulation functionality.','YesNo'),
30
('AllowOfflineCirculation','0','','If on, enables HTML5 offline circulation functionality.','YesNo'),
31
('AllowPatronToSetCheckoutsVisibilityForGuarantor',  '0', NULL, 'If enabled, the patron can set checkouts to be visible to his or her guarantor',  'YesNo'),
31
('AllowPatronToSetCheckoutsVisibilityForGuarantor',  '0', NULL, 'If enabled, the patron can set checkouts to be visible to his or her guarantor',  'YesNo'),
32
('AllowIssueNotes', '0', NULL, 'Allow patrons to submit notes about checked out items.','YesNo'),
32
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
33
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
33
('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
34
('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
34
('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo'),
35
('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+6 lines)
Lines 136-141 Circulation: Link Here
136
                  yes: Show
136
                  yes: Show
137
                  no: "Do not show"
137
                  no: "Do not show"
138
            - all items in the "Checked-in items" list, even items that were not checked out.
138
            - all items in the "Checked-in items" list, even items that were not checked out.
139
        -
140
            - pref: AllowIssueNotes
141
              choices:
142
                  yes: Allow
143
                  no: "Don't allow"
144
            - patrons to submit notes about checked out items.
139
145
140
    Checkout Policy:
146
    Checkout Policy:
141
        -
147
        -
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt (+10 lines)
Lines 183-188 $(document).ready(function () { Link Here
183
</div>
183
</div>
184
[% END %]
184
[% END %]
185
185
186
<!-- Patron has added an issue note -->
187
[% IF ( issue.note) %]
188
    <div class="dialog message">
189
        <h1>Patron note</h1>
190
        <p>[% issue.notedate %]</p>
191
        <p><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]"> [% title |html %]</a> [% author %]</p>
192
        <p>[% issue.note %]</p>
193
    </div>
194
[% END %]
195
186
<!-- Patron has fines -->
196
<!-- Patron has fines -->
187
[% IF ( fines ) %]
197
[% IF ( fines ) %]
188
    <div class="dialog alert">
198
    <div class="dialog alert">
(-)a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js (-4 / +9 lines)
Lines 67-72 $(document).ready(function() { Link Here
67
                    content = CIRCULATION_RETURNED;
67
                    content = CIRCULATION_RETURNED;
68
                    $(id).parent().parent().addClass('ok');
68
                    $(id).parent().parent().addClass('ok');
69
                    $('#date_due_' + data.itemnumber).html(CIRCULATION_RETURNED);
69
                    $('#date_due_' + data.itemnumber).html(CIRCULATION_RETURNED);
70
                    $('#patron_note_' + data.itemnumber).html("Patron note: " + data.patronnote);
70
                } else {
71
                } else {
71
                    content = CIRCULATION_NOT_RETURNED;
72
                    content = CIRCULATION_NOT_RETURNED;
72
                    $(id).parent().parent().addClass('warn');
73
                    $(id).parent().parent().addClass('warn');
Lines 218-224 $(document).ready(function() { Link Here
218
                },
219
                },
219
                {
220
                {
220
                    "mDataProp": function ( oObj ) {
221
                    "mDataProp": function ( oObj ) {
221
                        title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
222
                        title = "<span id='title_" + oObj.itemnumber + "' class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
222
                              + oObj.biblionumber
223
                              + oObj.biblionumber
223
                              + "'>"
224
                              + "'>"
224
                              + oObj.title;
225
                              + oObj.title;
Lines 242-248 $(document).ready(function() { Link Here
242
                            if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
243
                            if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
243
                                span_class = "circ-hlt";
244
                                span_class = "circ-hlt";
244
                            }
245
                            }
245
                            title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
246
                            title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>";
246
                        }
247
                        }
247
248
248
                        if ( oObj.itemnotes_nonpublic ) {
249
                        if ( oObj.itemnotes_nonpublic ) {
Lines 250-256 $(document).ready(function() { Link Here
250
                            if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
251
                            if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
251
                                span_class = "circ-hlt";
252
                                span_class = "circ-hlt";
252
                            }
253
                            }
253
                            title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic + "</span>"
254
                            title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic + "</span>";
254
                        }
255
                        }
255
256
256
                        var onsite_checkout = '';
257
                        var onsite_checkout = '';
Lines 258-263 $(document).ready(function() { Link Here
258
                            onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
259
                            onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
259
                        }
260
                        }
260
261
262
                        var patron_note = " <span id='patron_note_" + oObj.itemnumber + "'></span>";
263
261
                        title += " "
264
                        title += " "
262
                              + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
265
                              + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
263
                              + oObj.biblionumber
266
                              + oObj.biblionumber
Lines 268-274 $(document).ready(function() { Link Here
268
                              + "'>"
271
                              + "'>"
269
                              + oObj.barcode
272
                              + oObj.barcode
270
                              + "</a>"
273
                              + "</a>"
271
                              + onsite_checkout;
274
                              + onsite_checkout
275
                              + "<br>"
276
                              + patron_note
272
277
273
                        return title;
278
                        return title;
274
                    },
279
                    },
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-issue-note.tt (+54 lines)
Line 0 Link Here
1
[% USE Koha %]
2
[% USE KohaDates %]
3
[% USE Branches %]
4
[% INCLUDE 'doc-head-open.inc' %]
5
<title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Your library home</title>
6
[% INCLUDE 'doc-head-close.inc' %]
7
[% BLOCK cssinclude %][% END %]
8
</head>
9
[% INCLUDE 'bodytag.inc' bodyid='opac-issue-note' %]
10
[% INCLUDE 'masthead.inc' %]
11
12
<div class="main">
13
    <ul class="breadcrumb">
14
        <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
15
        <li><a href="/cgi-bin/koha/opac-user.pl">[% firstname %] [% surname %]</a><span class="divider">&rsaquo;</span></li>
16
        <li><a href="#">Editing issue note for [% ISSUE.title %] - [% ISSUE.author %]</a></li>
17
    </ul>
18
19
    <div class="container-fluid">
20
        <div class="row-fluid">
21
            <div class="span2">
22
                <div id="navigation">
23
                    [% INCLUDE 'navigation.inc' IsPatronPage=1 %]
24
                </div>
25
            </div>
26
            <div class="span10">
27
                <div id="issuenote" class="maincontent">
28
                    <h3>Editing issue note for [% title %] [% author %]</h3>
29
                        [% IF not(Koha.Preference("AllowIssueNotes")) %]
30
                            Issue notes have not been enabled. Please contact the library.
31
                        [% ELSE %]
32
                            <form id="issue-note" action="/cgi-bin/koha/opac-issue-note.pl" method="post">
33
                                <fieldset>
34
                                    <label for="note" class="required">Note:</label>
35
                                    <input type="text" name="note" value="[% note %]">
36
                                    <input type="hidden" name="borrowernumber" value="[% borrowernumber %]">
37
                                    <input type="hidden" name="itemnumber" value="[% itemnumber %]">
38
                                    <input type="hidden" name="issue_id" value="[% issue_id %]">
39
                                    <input type="hidden" name="action" value="issuenote">
40
                                </fieldset>
41
                                <fieldset class="action">
42
                                    <input type="submit" value="Submit note" class="btn"><a href="/cgi-bin/koha/opac-user.pl" class="cancel">Cancel</a>
43
                                </fieldset>
44
                            </form> <!-- issue-note -->
45
                        [% END %]
46
                </div> <!-- issuenote -->
47
            </div> <!-- span10 -->
48
        </div> <!-- row-fluid -->
49
    </div> <!-- container-fluid -->
50
51
</div> <!-- main -->
52
53
[% INCLUDE 'opac-bottom.inc' %]
54
[% BLOCK jsinclude %][% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt (+94 lines)
Lines 120-125 Using this account is not recommended because some parts of Koha will not functi Link Here
120
                        </div>
120
                        </div>
121
                    [% END # / IF patron_flagged %]
121
                    [% END # / IF patron_flagged %]
122
122
123
                    <div class="alert alert-info" id="notesaved" style="display:none;"></div>
124
123
                    [% SET OPACMySummaryNote = Koha.Preference('OPACMySummaryNote') %]
125
                    [% SET OPACMySummaryNote = Koha.Preference('OPACMySummaryNote') %]
124
                    [% IF OPACMySummaryNote %][% OPACMySummaryNote %][% END %]
126
                    [% IF OPACMySummaryNote %][% OPACMySummaryNote %][% END %]
125
127
Lines 165-170 Using this account is not recommended because some parts of Koha will not functi Link Here
165
                                                [% IF ( OPACMySummaryHTML ) %]
167
                                                [% IF ( OPACMySummaryHTML ) %]
166
                                                    <th class="nosort">Links</th>
168
                                                    <th class="nosort">Links</th>
167
                                                [% END %]
169
                                                [% END %]
170
                                                [% IF ( AllowIssueNotes ) %]
171
                                                    <th class="nosort">Note</th>
172
                                                [% END %]
168
                                            </tr>
173
                                            </tr>
169
                                        </thead>
174
                                        </thead>
170
                                        <tbody>
175
                                        <tbody>
Lines 283-288 Using this account is not recommended because some parts of Koha will not functi Link Here
283
                                                [% IF ( OPACMySummaryHTML ) %]
288
                                                [% IF ( OPACMySummaryHTML ) %]
284
                                                    <td class="links">[% ISSUE.MySummaryHTML %]</td>
289
                                                    <td class="links">[% ISSUE.MySummaryHTML %]</td>
285
                                                [% END %]
290
                                                [% END %]
291
                                                [% IF ( AllowIssueNotes ) %]
292
                                                    <td class="note">
293
                                                        <input type="text" name="note" data-issue_id="[% ISSUE.issue_id %]" data-origvalue="[% ISSUE.note %]" value="[% ISSUE.note %]" readonly>
294
                                                        <a class="btn" name="js_submitnote" id="save_[% ISSUE.issue_id %]" style="display:none;">Submit note</a>
295
                                                        <a class="btn" name="nonjs_submitnote" href="/cgi-bin/koha/opac-issue-note.pl?issue_id=[% ISSUE.issue_id | url %]">Edit / Create note</a>
296
                                                    </td>
297
                                                [% END %]
286
                                            </tr>
298
                                            </tr>
287
                                        [% END # /FOREACH ISSUES %]
299
                                        [% END # /FOREACH ISSUES %]
288
                                    </tbody>
300
                                    </tbody>
Lines 883-888 Using this account is not recommended because some parts of Koha will not functi Link Here
883
                [% END %]
895
                [% END %]
884
            [% END %]
896
            [% END %]
885
897
898
            [% IF ( AllowIssueNotes ) %]
899
900
                /* If JS enabled, show button, otherwise show link to redirect to a page where note can be submitted */
901
                $("a[name='nonjs_submitnote']").hide();
902
903
                $("input[name='note']").prop('readonly', false);
904
                $("input[name='note']").keyup(function(e){
905
                    /* prevent submitting of renewselected form */
906
                    if(e.which == 13)
907
                        e.preventDefault();
908
909
                    var $btn_save = $('#save_'+$(this).data('issue_id'));
910
                    var origvalue = $(this).data('origvalue');
911
                    var value = $(this).val();
912
913
                    if(origvalue != value) {
914
                        if(origvalue != "")
915
                            $btn_save.text('Submit changes');
916
                        else
917
                            $btn_save.text('Submit note');
918
                        $btn_save.show();
919
                    } else {
920
                        $btn_save.hide();
921
                    }
922
                });
923
924
                $("a[name='js_submitnote']").click(function(e){
925
                    var $self = $(this);
926
                    var title = $(this).parent().siblings('.title').html();
927
                    var $noteinput = $(this).siblings('input[name="note"]').first();
928
929
                    var ajaxData = {
930
                        'action': 'issuenote',
931
                        'issue_id': $noteinput.data('issue_id'),
932
                        'note': $noteinput.val(),
933
                    };
934
935
                    $.ajax({
936
                        url: '/cgi-bin/koha/svc/patron_notes/',
937
                        type: 'POST',
938
                        dataType: 'json',
939
                        data: ajaxData,
940
                    })
941
                    .done(function(data) {
942
                        var message = "";
943
                        if(data.status == 'saved') {
944
                            $("#notesaved").removeClass("alert-error");
945
                            $("#notesaved").addClass("alert-info");
946
                            $noteinput.data('origvalue', data.note);
947
                            $noteinput.val(data.note);
948
                            message = "<p>Your note about " + title + " has been saved and sent to the library.</p>";
949
                            $self.hide();
950
                        } else if(data.status == 'removed') {
951
                            $("#notesaved").removeClass("alert-error");
952
                            $("#notesaved").addClass("alert-info");
953
                            $noteinput.data('origvalue', "");
954
                            $noteinput.val("");
955
                            message = "<p>Your note about " + title + " was removed.</p>";
956
                            $self.hide();
957
                        } else {
958
                            $("#notesaved").removeClass("alert-info");
959
                            $("#notesaved").addClass("alert-error");
960
                            message = "<p>Your note about " + title + " could not be saved.</p>" +
961
                                      "<p style=\"font-weight:bold;\">" + data.error + "</p>";
962
                        }
963
964
                        message += "<p style=\"font-style:italic;\">" + data.note + "</p>";
965
                        $("#notesaved").html(message);
966
                    })
967
                    .fail(function(data) {
968
                        $("#notesaved").removeClass("alert-info");
969
                        $("#notesaved").addClass("alert-error");
970
                        var message = "<p>Your note about " + title + " could not be saved.</p>" +
971
                                      "<p style=\"font-weight:bold;\">Ajax request has failed.</p>";
972
                        $("#notesaved").html(message);
973
                    })
974
                    .always(function() {
975
                        $("#notesaved").show();
976
                    });
977
                });
978
            [% END %]
979
886
            $( ".suspend-until" ).datepicker({ minDate: 1 }); // Require that "until date" be in the future
980
            $( ".suspend-until" ).datepicker({ minDate: 1 }); // Require that "until date" be in the future
887
        });
981
        });
888
        //]]>
982
        //]]>
(-)a/opac/opac-issue-note.pl (+92 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 strict;
23
use warnings;
24
25
use CGI qw ( -utf8 );
26
use C4::Koha;
27
use C4::Context;
28
use C4::Scrubber;
29
use C4::Members;
30
use C4::Output;
31
use C4::Auth;
32
use C4::Biblio;
33
use C4::Letters;
34
use Koha::Issues;
35
use Koha::DateUtils;
36
37
my $query = new CGI;
38
39
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
40
    {
41
        template_name   => "opac-issue-note.tt",
42
        query           => $query,
43
        type            => "opac",
44
        authnotrequired => 0,
45
        debug           => 1,
46
    }
47
);
48
49
my $member = C4::Members::GetMember( borrowernumber => $borrowernumber );
50
$template->param(
51
    firstname      => $member->{'firstname'},
52
    surname        => $member->{'surname'},
53
    borrowernumber => $borrowernumber,
54
);
55
56
my $issue_id = $query->param('issue_id');
57
my $issueobj = Koha::Issues->find( $issue_id );
58
my $issue = $issueobj->unblessed;
59
my $itemnumber = $issue->{'itemnumber'};
60
my $biblio = GetBiblioFromItemNumber($itemnumber);
61
$template->param(
62
    issue_id   => $issue_id,
63
    title      => $biblio->{'title'},
64
    author     => $biblio->{'author'},
65
    note       => $issue->{'note'},
66
    itemnumber => $issue->{'itemnumber'},
67
);
68
69
my $action = $query->param('action') || "";
70
if ( $action eq 'issuenote' && C4::Context->preference('AllowIssueNotes') ) {
71
    my $note = $query->param('note');
72
    my $scrubber = C4::Scrubber->new();
73
    my $clean_note = $scrubber->scrub($note);
74
    if ( $issueobj->set({ notedate => dt_from_string(), note => $clean_note })->store ) {
75
        if ($clean_note) { # only send email if note not empty
76
            my $branch = Koha::Libraries->find( $issue->{branchcode} );
77
            my $letter = C4::Letters::GetPreparedLetter (
78
                module => 'circulation',
79
                letter_code => 'PATRON_NOTE',
80
                branchcode => $branch,
81
                tables => {
82
                    'biblio' => $biblio->{biblionumber},
83
                    'borrowers' => $member->{borrowernumber},
84
                },
85
            );
86
            C4::Message->enqueue($letter, $member, 'email');
87
        }
88
    }
89
    print $query->redirect("/cgi-bin/koha/opac-user.pl");
90
}
91
92
output_html_with_http_headers $query, $cookie, $template->output, undef, { force_no_caching => 1 };
(-)a/opac/opac-user.pl (+3 lines)
Lines 33-38 use C4::Output; Link Here
33
use C4::Biblio;
33
use C4::Biblio;
34
use C4::Items;
34
use C4::Items;
35
use C4::Letters;
35
use C4::Letters;
36
use Koha::Libraries;
36
use Koha::DateUtils;
37
use Koha::DateUtils;
37
use Koha::Holds;
38
use Koha::Holds;
38
use Koha::Database;
39
use Koha::Database;
Lines 260-265 if ($issues){ Link Here
260
}
261
}
261
my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing');
262
my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing');
262
$canrenew = 0 if ($overduesblockrenewing ne 'allow' and $overdues_count == $count);
263
$canrenew = 0 if ($overduesblockrenewing ne 'allow' and $overdues_count == $count);
264
265
$template->param( AllowIssueNotes => C4::Context->preference('AllowIssueNotes') );
263
$template->param( ISSUES       => \@issuedat );
266
$template->param( ISSUES       => \@issuedat );
264
$template->param( issues_count => $count );
267
$template->param( issues_count => $count );
265
$template->param( canrenew     => $canrenew );
268
$template->param( canrenew     => $canrenew );
(-)a/opac/svc/patron_notes (+120 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Copyright 2014 BibLibre
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 C4::Letters;
25
use CGI::Cookie; # need to check cookies before having CGI parse the POST request
26
use C4::Output qw(:DEFAULT :ajax);
27
use C4::Scrubber;
28
use C4::Circulation;
29
use C4::Members;
30
use C4::Biblio;
31
use Koha::Issues;
32
use Koha::DateUtils;
33
34
=head1 NAME
35
36
svc/patron_notes - Web service for setting patron notes on items
37
38
=head1 DESCRIPTION
39
40
=cut
41
42
sub ajax_auth_cgi {     # returns CGI object
43
    my $needed_flags = shift;
44
    my %cookies = fetch CGI::Cookie;
45
    my $input = CGI->new;
46
    my $sessid = $cookies{'CGISESSID'}->value;
47
    my ($auth_status, $auth_sessid) = check_cookie_auth($sessid, $needed_flags);
48
    if ($auth_status ne "ok") {
49
        output_with_http_headers $input, undef,
50
        "window.alert('Your CGI session cookie ($sessid) is not current.  " .
51
        "Please refresh the page and try again.');\n", 'js';
52
        exit 0;
53
    }
54
    return $input;
55
}
56
57
# AJAX requests
58
my $is_ajax = is_ajax();
59
my $query = ($is_ajax) ? &ajax_auth_cgi({}) : CGI->new();
60
if ($is_ajax) {
61
    my $action = $query->param('action');
62
63
    # Issue Note
64
    if ( $action eq 'issuenote' && C4::Context->preference('AllowIssueNotes') ) {
65
        my $scrubber = C4::Scrubber->new();
66
        my $note = $query->param('note');
67
        my $issue_id = $query->param('issue_id');
68
        my $clean_note = $scrubber->scrub($note);
69
        my $status = "saved";
70
        my $error = "";
71
        my ($member, $issueobj, $issue);
72
73
        my ( $template, $borrowernumber, $cookie ) = C4::Auth::get_template_and_user({
74
            template_name   => "opac-user.tt",
75
            query           => $query,
76
            type            => "opac",
77
            authnotrequired => 1,
78
        });
79
80
        # verify issue_id
81
        if ( $issue_id =~ /\d+/ ) {
82
            $member = GetMember(borrowernumber => $borrowernumber);
83
            $issueobj = Koha::Issues->find($issue_id);
84
            $issue = $issueobj->unblessed;
85
            if ( $issue->{'borrowernumber'} != $borrowernumber ) {
86
                $status = "fail";
87
                $error = "Invalid issue id!";
88
            }
89
        } else {
90
            $status = "fail";
91
            $error = "Invalid issue id!";
92
        }
93
94
        if ( (not $error) && $issueobj->set({ notedate => dt_from_string(), note => $clean_note })->store ) {
95
            if($clean_note) { # only send email if note not empty
96
                my $branch = Koha::Libraries->find( $issue->{branchcode} );
97
                my $biblio = GetBiblioFromItemNumber($issue->{'itemnumber'});
98
                my $letter = C4::Letters::GetPreparedLetter (
99
                    module => 'circulation',
100
                    letter_code => 'PATRON_NOTE',
101
                    branchcode => $branch,
102
                    tables => {
103
                        'biblio' => $biblio->{biblionumber},
104
                        'borrowers' => $member->{borrowernumber},
105
                    },
106
                );
107
                C4::Message->enqueue($letter, $member, 'email');
108
            } else { # note empty, i.e removed
109
                $status = "removed";
110
            }
111
        } else {
112
            $status = "fail";
113
            $error = "Perhaps the item has already been checked in?";
114
        }
115
116
        my $response = "{\"status\": \"$status\", \"note\": \"$clean_note\", \"issue_id\": \"$issue_id\", \"error\": \"$error\"}";
117
        output_with_http_headers($query, undef, $response, 'js');
118
        exit;
119
    } # END Issue Note
120
}
(-)a/svc/checkin (-1 / +8 lines)
Lines 72-77 if ( C4::Context->preference("ReturnToShelvingCart") ) { Link Here
72
    ModItem( $item, $item->{'biblionumber'}, $item->{'itemnumber'} );
72
    ModItem( $item, $item->{'biblionumber'}, $item->{'itemnumber'} );
73
}
73
}
74
74
75
my $dbh = C4::Context->dbh;
76
my $query = "SELECT note FROM issues WHERE itemnumber = ?";
77
my $sth = $dbh->prepare($query);
78
$sth->execute($itemnumber);
79
my $issue = $sth->fetchrow_hashref;
80
my $patronnote = $issue->{note};
81
$data->{patronnote} = $patronnote;
82
75
( $data->{returned} ) = AddReturn( $barcode, $branchcode, $exempt_fine );
83
( $data->{returned} ) = AddReturn( $barcode, $branchcode, $exempt_fine );
76
84
77
print to_json($data);
85
print to_json($data);
78
- 

Return to bug 14224