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

(-)a/Koha/Illrequest.pm (-6 / +95 lines)
Lines 116-121 available for request. Link Here
116
116
117
=head2 Class methods
117
=head2 Class methods
118
118
119
=head3 init_processors
120
121
    $request->init_processors()
122
123
Initialises an empty processors arrayref
124
125
=cut
126
127
sub init_processors {
128
    my ( $self ) = @_;
129
130
    $self->{processors} = [];
131
}
132
133
=head3 push_processor
134
135
    $request->push_processors(sub { ...something... });
136
137
Pushes a passed processor function into our processors arrayref
138
139
=cut
140
141
sub push_processor {
142
    my ( $self, $processor ) = @_;
143
    push @{$self->{processors}}, $processor;
144
}
145
119
=head3 statusalias
146
=head3 statusalias
120
147
121
    my $statusalias = $request->statusalias;
148
    my $statusalias = $request->statusalias;
Lines 371-376 sub _backend_capability { Link Here
371
    try {
398
    try {
372
        $capability = $self->_backend->capabilities($name);
399
        $capability = $self->_backend->capabilities($name);
373
    } catch {
400
    } catch {
401
        warn $_;
374
        return 0;
402
        return 0;
375
    };
403
    };
376
    # Try to invoke it
404
    # Try to invoke it
Lines 879-884 sub backend_create { Link Here
879
    return $self->expandTemplate($result);
907
    return $self->expandTemplate($result);
880
}
908
}
881
909
910
=head3 backend_get_update
911
912
    my $update = backend_get_update($request);
913
914
    Given a request, returns an update in a prescribed
915
    format that can then be passed to update parsers
916
917
=cut
918
919
sub backend_get_update {
920
    my ( $self, $options ) = @_;
921
922
    my $response = $self->_backend_capability(
923
        'get_supplier_update',
924
        {
925
            request => $self,
926
            %{$options}
927
        }
928
    );
929
    return $response;
930
}
931
882
=head3 expandTemplate
932
=head3 expandTemplate
883
933
884
    my $params = $abstract->expandTemplate($params);
934
    my $params = $abstract->expandTemplate($params);
Lines 1402-1408 Send a specified notice regarding this request to a patron Link Here
1402
=cut
1452
=cut
1403
1453
1404
sub send_patron_notice {
1454
sub send_patron_notice {
1405
    my ( $self, $notice_code ) = @_;
1455
    my ( $self, $notice_code, $additional_text ) = @_;
1406
1456
1407
    # We need a notice code
1457
    # We need a notice code
1408
    if (!$notice_code) {
1458
    if (!$notice_code) {
Lines 1413-1420 sub send_patron_notice { Link Here
1413
1463
1414
    # Map from the notice code to the messaging preference
1464
    # Map from the notice code to the messaging preference
1415
    my %message_name = (
1465
    my %message_name = (
1416
        ILL_PICKUP_READY   => 'Ill_ready',
1466
        ILL_PICKUP_READY    => 'Ill_ready',
1417
        ILL_REQUEST_UNAVAIL => 'Ill_unavailable'
1467
        ILL_REQUEST_UNAVAIL => 'Ill_unavailable',
1468
        ILL_REQUEST_UPDATE  => 'Ill_update'
1418
    );
1469
    );
1419
1470
1420
    # Get the patron's messaging preferences
1471
    # Get the patron's messaging preferences
Lines 1436-1443 sub send_patron_notice { Link Here
1436
    my @fail = ();
1487
    my @fail = ();
1437
    for my $transport (@transports) {
1488
    for my $transport (@transports) {
1438
        my $letter = $self->get_notice({
1489
        my $letter = $self->get_notice({
1439
            notice_code => $notice_code,
1490
            notice_code     => $notice_code,
1440
            transport   => $transport
1491
            transport       => $transport,
1492
            additional_text => $additional_text
1441
        });
1493
        });
1442
        if ($letter) {
1494
        if ($letter) {
1443
            my $result = C4::Letters::EnqueueLetter({
1495
            my $result = C4::Letters::EnqueueLetter({
Lines 1578-1590 sub get_notice { Link Here
1578
        substitute  => {
1630
        substitute  => {
1579
            ill_bib_title      => $title ? $title->value : '',
1631
            ill_bib_title      => $title ? $title->value : '',
1580
            ill_bib_author     => $author ? $author->value : '',
1632
            ill_bib_author     => $author ? $author->value : '',
1581
            ill_full_metadata  => $metastring
1633
            ill_full_metadata  => $metastring,
1634
            additional_text    => $params->{additional_text}
1582
        }
1635
        }
1583
    );
1636
    );
1584
1637
1585
    return $letter;
1638
    return $letter;
1586
}
1639
}
1587
1640
1641
1642
=head3 attach_processors
1643
1644
Receive a Koha::Illrequest::SupplierUpdate and attach
1645
any processors we have for it
1646
1647
=cut
1648
1649
sub attach_processors {
1650
    my ( $self, $update ) = @_;
1651
1652
    foreach my $processor(@{$self->{processors}}) {
1653
        if (
1654
            $processor->{target_source_type} eq $update->{source_type} &&
1655
            $processor->{target_source_name} eq $update->{source_name}
1656
        ) {
1657
            $update->attach_processor($processor);
1658
        }
1659
    }
1660
}
1661
1662
=head3 append_to_note
1663
1664
    append_to_note("Some text");
1665
1666
Append some text to the staff note
1667
1668
=cut
1669
1670
sub append_to_note {
1671
    my ($self, $text) = @_;
1672
    my $current = $self->notesstaff;
1673
    $text = ($current && length $current > 0) ? "$current\n\n$text" : $text;
1674
    $self->notesstaff($text)->store;
1675
}
1676
1588
=head3 id_prefix
1677
=head3 id_prefix
1589
1678
1590
    my $prefix = $record->id_prefix;
1679
    my $prefix = $record->id_prefix;
(-)a/Koha/Illrequest/SupplierUpdate.pm (+111 lines)
Line 0 Link Here
1
package Koha::Illrequest::SupplierUpdate;
2
3
# Copyright 2022 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
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
=head1 NAME
23
24
Koha::Illrequest::SupplierUpdate - Represents a single request update from a supplier
25
26
=head1 SYNOPSIS
27
28
Object-oriented class that provides an object allowing us to interact with
29
an update from a supplier
30
31
=head1 DESCRIPTION
32
33
Object-oriented class that provides an object allowing us to interact with
34
an update from a supplier
35
36
=head1 API
37
38
=head2 Class Methods
39
40
=head3 new
41
42
    my $update = Koha::Illrequest::SupplierUpdate->new(
43
        $source_type,
44
        $source_name,
45
        $update
46
    );
47
48
Create a new Koha::Illrequest::SupplierUpdate object.
49
50
=cut
51
52
sub new {
53
    my ( $class, $source_type, $source_name, $update, $request ) = @_;
54
    my $self  = {};
55
56
    $self->{source_type} = $source_type;
57
    $self->{source_name} = $source_name;
58
    $self->{update} = $update;
59
    $self->{request} = $request;
60
    $self->{processors} = [];
61
62
    bless $self, $class;
63
64
    return $self;
65
}
66
67
=head3 attach_processor
68
69
    Koha::Illrequest::SupplierUpdate->attach_processor($processor);
70
71
Pushes a processor function onto the 'processors' arrayref
72
73
=cut
74
75
sub attach_processor {
76
    my ( $self, $processor ) = @_;
77
    push(@{$self->{processors}}, $processor);
78
}
79
80
=head3 run_processors
81
82
    Koha::Illrequest::SupplierUpdate->run_processors();
83
84
Iterates all processors on this object and runs each
85
86
=cut
87
88
sub run_processors {
89
    my ( $self, $options ) = @_;
90
    my $results = [];
91
    foreach my $processor(@{$self->{processors}}) {
92
        my $processor_result = {
93
            name   => $processor->{name},
94
            result => {
95
                success => [],
96
                error   => []
97
            }
98
        };
99
        $processor->run($self, $options, $processor_result->{result});
100
        push @{$results}, $processor_result;
101
    }
102
    return $results;
103
}
104
105
=head1 AUTHOR
106
107
Andrew Isherwood <andrew.isherwood@ptfs-europe.com>
108
109
=cut
110
111
1;
(-)a/Koha/Illrequest/SupplierUpdateProcessor.pm (+85 lines)
Line 0 Link Here
1
package Koha::Illrequest::SupplierUpdateProcessor;
2
3
# Copyright 2022 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
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
=head1 NAME
23
24
Koha::Illrequest::SupplierUpdateProcessor - Represents a SupplerUpdate processor
25
26
=head1 SYNOPSIS
27
28
Object-oriented class that provides an object allowing us to perform processing on
29
a SupplierUpdate
30
31
=head1 DESCRIPTION
32
33
Object-oriented base class that provides an object allowing us to perform processing on
34
a SupplierUpdate
35
** This class should not be directly instantiated, it should only be sub-classed **
36
37
=head1 API
38
39
=head2 Class Methods
40
41
=head3 new
42
43
    my $processor = Koha::Illrequest::SupplierUpdateProcessor->new(
44
        $target_source_type,
45
        $target_source_name
46
    );
47
48
Create a new Koha::Illrequest::SupplierUpdateProcessor object.
49
50
=cut
51
52
sub new {
53
    my ( $class, $target_source_type, $target_source_name, $processor_name ) = @_;
54
    my $self  = {};
55
56
    $self->{target_source_type} = $target_source_type;
57
    $self->{target_source_name} = $target_source_name;
58
    $self->{name} = $processor_name;
59
60
    bless $self, $class;
61
62
    return $self;
63
}
64
65
=head3 run
66
67
    Koha::Illrequest::SupplierUpdateProcessor->run();
68
69
Runs the processor
70
71
=cut
72
73
sub run {
74
    my ( $self ) = @_;
75
    my ( $package, $filename ) = caller;
76
    warn __PACKAGE__ . " run should only be invoked by a subclass\n";
77
}
78
79
=head1 AUTHOR
80
81
Andrew Isherwood <andrew.isherwood@ptfs-europe.com>
82
83
=cut
84
85
1;
(-)a/misc/process_ill_updates.pl (-1 / +214 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Copyright (C) 2022 PTFS Europe
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
use Getopt::Long qw( GetOptions );
22
use POSIX;
23
24
use Koha::Script;
25
use Koha::Illrequests;
26
27
# Command line option values
28
my $get_help = 0;
29
my $statuses = "";
30
my $status_alias = "";
31
my $status_to = "";
32
my $status_alias_to = "";
33
my $backend = "";
34
my $dry_run = 0;
35
my $delay = 0;
36
my $debug = 0;
37
38
my $options = GetOptions(
39
    'h|help'            => \$get_help,
40
    'statuses:s'        => \$statuses,
41
    'status-alias:s'    => \$status_alias,
42
    'status-to:s'       => \$status_to,
43
    'status-alias-to:s' => \$status_alias_to,
44
    'backend=s'         => \$backend,
45
    'dry-run'           => \$dry_run,
46
    'api-delay:i'       => \$delay,
47
    'debug'             => \$debug
48
);
49
50
if ($get_help) {
51
    get_help();
52
    exit 1;
53
}
54
55
if (!$backend) {
56
    print "No backend specified\n";
57
    exit 0;
58
}
59
60
# First check we can proceed
61
my $cfg = Koha::Illrequest::Config->new;
62
my $backends = $cfg->available_backends;
63
my $has_branch = $cfg->has_branch;
64
my $backends_available = ( scalar @{$backends} > 0 );
65
if (!$has_branch || $backends_available == 0) {
66
    print "Unable to proceed:\n";
67
    print "Branch configured: $has_branch\n";
68
    print "Backends available: $backends_available\n";
69
    exit 0;
70
}
71
72
# Get all required requests
73
my @statuses_arr = split(/:/, $statuses);
74
my @status_alias_arr = split(/:/, $status_alias);
75
76
my $where = {
77
    backend => $backend
78
};
79
80
if (scalar @statuses_arr > 0) {
81
    my @or = grep(!/null/, @statuses_arr);
82
    if (scalar @or < scalar @statuses_arr) {
83
        push @or, undef;
84
    }
85
    $where->{status} = \@or;
86
}
87
88
if (scalar @status_alias_arr > 0) {
89
    my @or = grep(!/null/, @status_alias_arr);
90
    if (scalar @or < scalar @status_alias_arr) {
91
        push @or, undef;
92
    }
93
    $where->{status_alias} = \@or;    
94
}
95
96
debug_msg("DBIC WHERE:");
97
debug_msg($where);
98
99
my $requests = Koha::Illrequests->search($where);
100
101
debug_msg("Processing " . $requests->count . " requests");
102
103
# Create an options hashref to pass to processors
104
my $options_to_pass = {
105
    dry_run         => $dry_run,
106
    status_to       => $status_to,
107
    status_alias_to => $status_alias_to,
108
    delay           => $delay,
109
    debug           => \&debug_msg
110
};
111
112
# The progress log
113
my $output = [];
114
115
while (my $request = $requests->next) {
116
    debug_msg("- Request ID " . $request->illrequest_id);
117
    my $update = $request->backend_get_update($options_to_pass);
118
    # The log for this request
119
    my $update_log = {
120
        request_id     => $request->illrequest_id,
121
        processed_by   => $request->_backend->name,
122
        processors_run => []
123
    };
124
    if ($update) {
125
        # Currently we make an assumption, this may need revisiting
126
        # if we need to extend the functionality:
127
        #
128
        # Only the backend that originated the update will want to
129
        # process it
130
        #
131
        # Since each backend's update format is different, it may
132
        # be necessary for a backend to subclass Koha::Illrequest::SupplierUpdate
133
        # so it can provide methods (corresponding to a generic interface) that
134
        # return pertinent info to core ILL when it is processing updates
135
        #
136
        # Attach any request processors
137
        $request->attach_processors($update);
138
        # Attach any processors from this request's backend
139
        $request->_backend->attach_processors($update);
140
        my $processor_results = $update->run_processors($options_to_pass);
141
        # Update our progress log
142
        $update_log->{processors_run} = $processor_results;
143
    }
144
    push @{$output}, $update_log;
145
}
146
147
print_summary($output);
148
149
sub print_summary {
150
    my ( $log ) = @_;
151
152
    my $timestamp = POSIX::strftime("%d/%m/%Y %H:%M:%S\n", localtime);
153
    print "Run details:\n";
154
    foreach my $entry(@{$log}) {
155
        my @processors_run = @{$entry->{processors_run}};
156
        print "Request ID: " . $entry->{request_id} . "\n";
157
        print "  Processing by: " . $entry->{processed_by} . "\n";
158
        print "  Number of processors run: " . scalar @processors_run . "\n";
159
        if (scalar @processors_run > 0) {
160
            print "  Processor details:\n";
161
            foreach my $processor(@processors_run) {
162
                print "    Processor name: " . $processor->{name} . "\n";
163
                print "    Success messages: " . join(", ", @{$processor->{result}->{success}}) . "\n";
164
                print "    Error messages: " . join(", ", @{$processor->{result}->{error}}) . "\n";
165
            }
166
        }
167
    }
168
    print "Job completed at $timestamp\n====================================\n\n"
169
}
170
171
sub debug_msg {
172
    my ( $msg ) = @_;
173
174
    if (!$debug) {
175
        return;
176
    }
177
178
    if (ref $msg eq 'HASH') {
179
        use Data::Dumper;
180
        $msg = Dumper $msg;
181
    }
182
    print STDERR "$msg\n";
183
}
184
185
sub get_help {
186
    print <<"HELP";
187
$0: Fetch and process outstanding ILL updates
188
189
This script will fetch all requests that have the specified
190
statuses and run any applicable processor scripts on them.
191
For example, the RapidILL backend provides a processor script
192
that emails users when their requested electronic resource
193
request has been fulfilled
194
195
Parameters:
196
    --statuses <statuses>                specify the statuses a request must have in order to be processed,
197
                                         statuses should be separated by a : e.g. REQ:COMP:NEW. A null value
198
                                         can be specified by passing null, e.g. --statuses null
199
200
    --status-aliases <status-aliases>    specify the statuses aliases a request must have in order to be processed,
201
                                         statuses should be separated by a : e.g. STA:OLD:PRE. A null value
202
                                         can be specified by passing null, e.g. --status-aliases null
203
    --status-to <status-to>              specify the status a successfully processed request must be set to
204
                                         after processing
205
    --status-alias-to <status-alias-to>  specify the status alias a successfully processed request must be set to
206
                                         after processing
207
    --dry-run                            only produce a run report, without actually doing anything permanent
208
    --api-delay <seconds>                if a processing script needs to make an API call, how long a pause
209
                                         should be inserted between each API call
210
    --debug                              print additional debugging info during run
211
212
    --help or -h                         get help
213
HELP
214
}

Return to bug 30484