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

(-)a/C4/Log.pm (+1 lines)
Lines 142-147 sub GetLogStatus { Link Here
142
    $hash{CataloguingLog}  = C4::Context->preference("CataloguingLog");
142
    $hash{CataloguingLog}  = C4::Context->preference("CataloguingLog");
143
    $hash{HoldsLog}        = C4::Context->preference("HoldsLog");
143
    $hash{HoldsLog}        = C4::Context->preference("HoldsLog");
144
    $hash{IssueLog}        = C4::Context->preference("IssueLog");
144
    $hash{IssueLog}        = C4::Context->preference("IssueLog");
145
    $hash{IllLog}          = C4::Context->preference("IllLog");
145
    $hash{ReturnLog}       = C4::Context->preference("ReturnLog");
146
    $hash{ReturnLog}       = C4::Context->preference("ReturnLog");
146
    $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog");
147
    $hash{SubscriptionLog} = C4::Context->preference("SubscriptionLog");
147
    $hash{LetterLog}       = C4::Context->preference("LetterLog");
148
    $hash{LetterLog}       = C4::Context->preference("LetterLog");
(-)a/Koha/Illrequest.pm (-1 / +73 lines)
Lines 32-37 use Koha::Exceptions::Ill; Link Here
32
use Koha::Illcomments;
32
use Koha::Illcomments;
33
use Koha::Illrequestattributes;
33
use Koha::Illrequestattributes;
34
use Koha::AuthorisedValue;
34
use Koha::AuthorisedValue;
35
use Koha::Illrequest::Logger;
35
use Koha::Patron;
36
use Koha::Patron;
36
37
37
use base qw(Koha::Object);
38
use base qw(Koha::Object);
Lines 149-154 sub illcomments { Link Here
149
    );
150
    );
150
}
151
}
151
152
153
=head3 logs
154
155
=cut
156
157
sub logs {
158
    my ( $self ) = @_;
159
    my $logger = Koha::Illrequest::Logger->new;
160
    return $logger->get_request_logs($self);
161
}
162
152
=head3 patron
163
=head3 patron
153
164
154
=cut
165
=cut
Lines 197-203 sub load_backend { Link Here
197
    my $location = join "/", @raw, $backend_name, "Base.pm";    # File to load
208
    my $location = join "/", @raw, $backend_name, "Base.pm";    # File to load
198
    my $backend_class = join "::", @raw, $backend_name, "Base"; # Package name
209
    my $backend_class = join "::", @raw, $backend_name, "Base"; # Package name
199
    require $location;
210
    require $location;
200
    $self->{_my_backend} = $backend_class->new({ config => $self->_config });
211
    $self->{_my_backend} = $backend_class->new({
212
        config => $self->_config,
213
        logger => Koha::Illrequest::Logger->new
214
    });
201
    return $self;
215
    return $self;
202
}
216
}
203
217
Lines 1052-1057 sub _censor { Link Here
1052
    return $params;
1066
    return $params;
1053
}
1067
}
1054
1068
1069
=head3 status
1070
1071
    $Illrequest->status('CANREQ');
1072
1073
Overloaded I<status> method that, in addition to setting the request status
1074
records the fact that the status has changed
1075
1076
=cut
1077
1078
sub status {
1079
    my ( $self, $new_status ) = @_;
1080
1081
    my $current_status = $self->SUPER::status;
1082
1083
    if ($new_status) {
1084
        # Keep a record of the previous status before we change it,
1085
        # we might need it
1086
        $self->{previous_status} = $current_status;
1087
        my $ret = $self->SUPER::status($new_status)->store;
1088
        if ($ret) {
1089
            my $logger = Koha::Illrequest::Logger->new;
1090
            $logger->log_status_change(
1091
                $self,
1092
                $new_status
1093
            );
1094
        } else {
1095
            delete $self->{previous_status};
1096
        }
1097
        return $ret;
1098
    } else {
1099
        return $current_status;
1100
    }
1101
}
1102
1103
=head3 store
1104
1105
    $Illrequest->store;
1106
1107
Overloaded I<store> method that, in addition to performing the 'store',
1108
possibly records the fact that something happened
1109
1110
=cut
1111
1112
sub store {
1113
    my ( $self, $attrs ) = @_;
1114
1115
    my $ret = $self->SUPER::store;
1116
1117
    $attrs->{log_origin} = 'core';
1118
1119
    if ($ret && defined $attrs) {
1120
        my $logger = Koha::Illrequest::Logger->new;
1121
        $logger->log_maybe($self, $attrs);
1122
    }
1123
1124
    return $ret;
1125
}
1126
1055
=head3 TO_JSON
1127
=head3 TO_JSON
1056
1128
1057
    $json = $illrequest->TO_JSON
1129
    $json = $illrequest->TO_JSON
(-)a/Koha/Illrequest/Logger.pm (+242 lines)
Line 0 Link Here
1
package Koha::Illrequest::Logger;
2
3
# Copyright 2018 PTFS Europe Ltd
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
use JSON qw( to_json from_json );
22
23
use C4::Context;
24
use C4::Templates;
25
use C4::Log qw( logaction GetLogs );
26
27
=head1 NAME
28
29
Koha::Illrequest::Logger - Koha ILL Action / Event logger
30
31
=head1 SYNOPSIS
32
33
Object-oriented class that provides event logging functionality for
34
ILL requests
35
36
=head1 DESCRIPTION
37
38
This class provides the ability to log arbitrary actions or events
39
relating to Illrequest to the action log.
40
41
=head1 API
42
43
=head2 Class Methods
44
45
=head3 new
46
47
    my $config = Koha::Illrequest::Logger->new();
48
49
Create a new Koha::Illrequest::Logger object, with skeleton logging data
50
We also set up data of what can be logged, how to do it and how to display
51
log entries we get back out
52
53
=cut
54
55
sub new {
56
    my ( $class ) = @_;
57
    my $self  = {};
58
59
    $self->{data} = {
60
        modulename => 'ILL'
61
    };
62
63
    $self->{loggers} = {
64
        status => sub {
65
            $self->log_status_change(@_);
66
        }
67
    };
68
69
    my ( $htdocs, $theme, $lang, $base ) =
70
        C4::Templates::_get_template_file('ill/log/', 'intranet');
71
72
    $self->{templates} = {
73
        STATUS_CHANGE => $base . 'status_change.tt'
74
    };
75
76
    bless $self, $class;
77
78
    return $self;
79
}
80
81
=head3 log_maybe
82
83
    Koha::IllRequest::Logger->log_maybe($attrs);
84
85
Receive request object and an attributes hashref (which may or may
86
not be defined) If the hashref contains a key matching our "loggers" hashref
87
then we want to log it
88
89
=cut
90
91
sub log_maybe {
92
    my ($self, $req, $attrs) = @_;
93
94
    if (defined $req && defined $attrs) {
95
        foreach my $key (keys %{ $attrs }) {
96
            if (defined($self->{loggers}->{$key})) {
97
                $self->{loggers}->{$key}($req, $attrs->{$key});
98
            }
99
        }
100
    }
101
}
102
103
=head3 log_status_change
104
105
    Koha::IllRequest::Logger->log_status_change();
106
107
Log a request's status change
108
109
=cut
110
111
sub log_status_change {
112
    my ( $self, $req, $new_status ) = @_;
113
114
    $self->set_data({
115
        actionname   => 'STATUS_CHANGE',
116
        objectnumber => $req->id,
117
        infos        => to_json({
118
            log_origin    => 'core',
119
            status_before => $req->{previous_status},
120
            status_after  => $new_status
121
        })
122
    });
123
124
    $self->log_something();
125
}
126
127
=head3 log_something
128
129
    Koha::IllRequest::Logger->log_something();
130
131
If we have the required data set, log an action
132
133
=cut
134
135
sub log_something {
136
    my ( $self ) = @_;
137
138
    if (
139
        defined $self->{data}->{modulename} &&
140
        defined $self->{data}->{actionname} &&
141
        defined $self->{data}->{objectnumber} &&
142
        defined $self->{data}->{infos} &&
143
        C4::Context->preference("IllLog")
144
    ) {
145
        logaction(
146
            $self->{data}->{modulename},
147
            $self->{data}->{actionname},
148
            $self->{data}->{objectnumber},
149
            $self->{data}->{infos}
150
        );
151
    }
152
}
153
154
=head3 set_data
155
156
    Koha::IllRequest::Logger->set_data({
157
        key  => 'value',
158
        key2 => 'value2'
159
    });
160
161
Set arbitrary data propert(ies) on the logger object
162
163
=cut
164
165
sub set_data {
166
    my ( $self, $data ) = @_;
167
168
    foreach my $key (keys %{ $data }) {
169
        $self->{data}->{$key} = $data->{$key};
170
    }
171
}
172
173
=head3 get_log_template
174
175
    $template_path = get_log_template($origin, $action);
176
177
Given a log's origin and action, get the appropriate display template
178
179
=cut
180
181
sub get_log_template {
182
    my ($self, $req, $params) = @_;
183
184
    my $origin = $params->{origin};
185
    my $action = $params->{action};
186
187
    if ($origin eq 'core') {
188
        # It's a core log, so we can just get the template path from
189
        # the hashref above
190
        return $self->{templates}->{$action};
191
    } else {
192
        # It's probably a backend log, so we need to get the path to the
193
        # template from the backend
194
        my $backend =$req->{_my_backend};
195
        return $backend->get_log_template_path($action);
196
    }
197
}
198
199
=head3 get_request_logs
200
201
    $requestlogs = Koha::IllRequest::Logger->get_request_logs($request_id);
202
203
Get all logged actions for a given request
204
205
=cut
206
207
sub get_request_logs {
208
    my ( $self, $request ) = @_;
209
210
    my $logs = GetLogs(
211
        undef,
212
        undef,
213
        undef,
214
        ['ILL'],
215
        undef,
216
        $request->id,
217
        undef,
218
        undef
219
    );
220
    foreach my $log(@{$logs}) {
221
        $log->{info} = from_json($log->{info});
222
        $log->{template} = $self->get_log_template(
223
        $request,
224
            {
225
                origin => $log->{info}->{log_origin},
226
                action => $log->{action}
227
            }
228
        );
229
    }
230
231
    my @sorted = sort {$$b{'timestamp'} <=> $$a{'timestamp'}} @{$logs};
232
233
    return \@sorted;
234
}
235
236
=head1 AUTHOR
237
238
Andrew Isherwood <andrew.isherwood@ptfs-europe.com>
239
240
=cut
241
242
1;
(-)a/installer/data/mysql/atomicupdate/bug_20750-add_illlog_preference.perl (+7 lines)
Line 0 Link Here
1
$DBversion = 'XXX';  # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
3
    $dbh->do( "INSERT IGNORE INTO systempreferences (variable, value, explanation, type) VALUES ('IllLog', 1, 'If ON, log information about ILL requests', 'YesNo')" );
4
5
    SetVersion( $DBversion );
6
    print "Upgrade to $DBversion done (Bug 20750 - Allow timestamped auditing of ILL request events)\n";
7
}
(-)a/installer/data/mysql/en/optional/ill_logging_pref.sql (+1 lines)
Line 0 Link Here
1
INSERT IGNORE INTO systempreferences (variable, value, explanation, type) VALUES ('IllLog', 1, 'If ON, log information about ILL requests', 'YesNo');
(-)a/installer/data/mysql/en/optional/ill_logging_pref.txt (+1 lines)
Line 0 Link Here
1
System preference to determine if logging of ILL requests should occur
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 211-216 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
211
('IDreamBooksResults','0','','Display IDreamBooks.com rating in search results','YesNo'),
211
('IDreamBooksResults','0','','Display IDreamBooks.com rating in search results','YesNo'),
212
('IDreamBooksReviews','0','','Display book review snippets from IDreamBooks.com','YesNo'),
212
('IDreamBooksReviews','0','','Display book review snippets from IDreamBooks.com','YesNo'),
213
('IdRef','0','','Disable/enable the IdRef webservice from the OPAC detail page.','YesNo'),
213
('IdRef','0','','Disable/enable the IdRef webservice from the OPAC detail page.','YesNo'),
214
('IllLog', 1, '', 'If ON, log information about ILL requests', 'YesNo'),
214
('ILLModule','0','If ON, enables the interlibrary loans module.','','YesNo'),
215
('ILLModule','0','If ON, enables the interlibrary loans module.','','YesNo'),
215
('ILLModuleCopyrightClearance','','70|10','Enter text to enable the copyright clearance stage of request creation. Text will be displayed','Textarea'),
216
('ILLModuleCopyrightClearance','','70|10','Enter text to enable the copyright clearance stage of request creation. Text will be displayed','Textarea'),
216
('ILLOpacbackends',NULL,NULL,'ILL backends to enabled for OPAC initiated requests','multiple'),
217
('ILLOpacbackends',NULL,NULL,'ILL backends to enabled for OPAC initiated requests','multiple'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/logs.pref (+6 lines)
Lines 37-42 Logging: Link Here
37
                  off: "Don't log"
37
                  off: "Don't log"
38
            - any actions on holds (create, cancel, suspend, resume, etc).
38
            - any actions on holds (create, cancel, suspend, resume, etc).
39
        -
39
        -
40
            - pref: IllLog
41
              choices:
42
                  on: Log
43
                  off: "Don't log"
44
            - when changes to ILL requests take place
45
        -
40
            - pref: IssueLog
46
            - pref: IssueLog
41
              choices:
47
              choices:
42
                  on: Log
48
                  on: Log
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt (-1 / +34 lines)
Lines 310-315 Link Here
310
                        <a title="Display supplier metadata" id="ill-request-display-metadata" class="btn btn-sm btn-default pull-right" href="#">
310
                        <a title="Display supplier metadata" id="ill-request-display-metadata" class="btn btn-sm btn-default pull-right" href="#">
311
                            <span class="fa fa-eye"></span>
311
                            <span class="fa fa-eye"></span>
312
                            Display supplier metadata
312
                            Display supplier metadata
313
                        <a title="Display request log" id="ill-request-display-log" class="btn btn-sm btn-default pull-right" href="#">
314
                            <span class="fa fa-calendar"></span>
315
                            Display request log
313
                        </a>
316
                        </a>
314
                    </div>
317
                    </div>
315
                    <div id="ill-view-panel" class="panel panel-default">
318
                    <div id="ill-view-panel" class="panel panel-default">
Lines 417-422 Link Here
417
                        </div>
420
                        </div>
418
                    </div>
421
                    </div>
419
422
423
                    <div id="requestLog" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="dataPreviewLabel" aria-hidden="true">
424
                        <div class="modal-dialog">
425
                            <div class="modal-content">
426
                                <div class="modal-header">
427
                                    <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
428
                                    <h3 id="requestLogLabel"> Request log</h3>
429
                                </div>
430
                                <div class="modal-body">
431
                                [% IF request.logs.size > 0 %]
432
                                    [% FOREACH log IN request.logs %]
433
                                        [% tpl = log.template %]
434
                                        [% INCLUDE $tpl %]
435
                                    [% END %]
436
                                [% ELSE %]
437
                                    There are no recorded logs for this request
438
                                [% END %]
439
                                </div>
440
                                <div class="modal-footer">
441
                                    <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
442
                                </div>
443
                            </div>
444
                        </div>
445
                    </div>
446
420
                    <div id="ill-view-panel" class="panel panel-default">
447
                    <div id="ill-view-panel" class="panel panel-default">
421
                        <div class="panel-heading">
448
                        <div class="panel-heading">
422
                            <h3>[% request.illcomments.count | html %] comments</h3>
449
                            <h3>[% request.illcomments.count | html %] comments</h3>
Lines 455-461 Link Here
455
                                        </form>
482
                                        </form>
456
                                    </div>
483
                                    </div>
457
                                </div>
484
                                </div>
458
                            </div>
485
                        </div>
459
                    </div>
486
                    </div>
460
487
461
                [% ELSIF query_type == 'illlist' %]
488
                [% ELSIF query_type == 'illlist' %]
Lines 819-824 Link Here
819
                }
846
                }
820
            };
847
            };
821
848
849
            // Display the modal containing request supplier metadata
850
            $('#ill-request-display-log').on('click', function(e) {
851
                e.preventDefault();
852
                $('#requestLog').modal({show:true});
853
            });
854
822
            // Toggle request attributes in Illview
855
            // Toggle request attributes in Illview
823
            $('#toggle_requestattributes').on('click', function(e) {
856
            $('#toggle_requestattributes').on('click', function(e) {
824
                e.preventDefault();
857
                e.preventDefault();
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/log/status_change.tt (+7 lines)
Line 0 Link Here
1
<p>
2
[% log.timestamp | $KohaDates with_hours => 1 %] : <b>Status changed </b>
3
[% IF log.info.status_before %]
4
from &quot;[% request.capabilities(log.info.status_before).name %]&quot;
5
[% END %]
6
to &quot;[% request.capabilities(log.info.status_after).name %]&quot;
7
</p>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt (-2 / +4 lines)
Lines 28-33 Link Here
28
[%        CASE 'ACQUISITIONS' %]Acquisitions
28
[%        CASE 'ACQUISITIONS' %]Acquisitions
29
[%        CASE 'SERIAL'       %]Serials
29
[%        CASE 'SERIAL'       %]Serials
30
[%        CASE 'HOLDS'        %]Holds
30
[%        CASE 'HOLDS'        %]Holds
31
[%        CASE 'ILL'          %]Interlibrary loans
31
[%        CASE 'CIRCULATION'  %]Circulation
32
[%        CASE 'CIRCULATION'  %]Circulation
32
[%        CASE 'LETTER'       %]Letter
33
[%        CASE 'LETTER'       %]Letter
33
[%        CASE 'FINES'        %]Fines
34
[%        CASE 'FINES'        %]Fines
Lines 53-58 Link Here
53
[%        CASE 'CHANGE PASS' %]Change password
54
[%        CASE 'CHANGE PASS' %]Change password
54
[%        CASE 'ADDCIRCMESSAGE' %]Add circulation message
55
[%        CASE 'ADDCIRCMESSAGE' %]Add circulation message
55
[%        CASE 'DELCIRCMESSAGE' %]Delete circulation message
56
[%        CASE 'DELCIRCMESSAGE' %]Delete circulation message
57
[%        CASE 'STATUS_CHANGE'  %]Change ILL request status
58
[%        CASE 'BLDSS_STATUS_CHECK'  %]Check ILL request status with BLDSS
56
[%        CASE 'Run'    %]Run
59
[%        CASE 'Run'    %]Run
57
[%        CASE %][% action | html %]
60
[%        CASE %][% action | html %]
58
[%    END %]
61
[%    END %]
Lines 101-107 Link Here
101
                                    [% ELSE %]
104
                                    [% ELSE %]
102
                                        <option value="">All</option>
105
                                        <option value="">All</option>
103
                                    [% END %]
106
                                    [% END %]
104
                                    [% FOREACH modx IN [ 'CATALOGUING' 'AUTHORITIES' 'MEMBERS' 'ACQUISITIONS' 'SERIAL' 'HOLDS' 'CIRCULATION' 'LETTER' 'FINES' 'SYSTEMPREFERENCE' 'CRONJOBS', 'REPORTS' ] %]
107
                                    [% FOREACH modx IN [ 'CATALOGUING' 'AUTHORITIES' 'MEMBERS' 'ACQUISITIONS' 'SERIAL' 'HOLDS' 'ILL' 'CIRCULATION' 'LETTER' 'FINES' 'SYSTEMPREFERENCE' 'CRONJOBS', 'REPORTS' ] %]
105
                                        [% IF modules.grep(modx).size %]
108
                                        [% IF modules.grep(modx).size %]
106
                                            <option value="[% modx | html %]" selected="selected">[% PROCESS translate_log_module module=modx %]</option>
109
                                            <option value="[% modx | html %]" selected="selected">[% PROCESS translate_log_module module=modx %]</option>
107
                                        [% ELSE %]
110
                                        [% ELSE %]
108
- 

Return to bug 20750