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 896-901 sub backend_create { Link Here
896
    return $self->expandTemplate($result);
924
    return $self->expandTemplate($result);
897
}
925
}
898
926
927
=head3 backend_get_update
928
929
    my $update = backend_get_update($request);
930
931
    Given a request, returns an update in a prescribed
932
    format that can then be passed to update parsers
933
934
=cut
935
936
sub backend_get_update {
937
    my ( $self, $options ) = @_;
938
939
    my $response = $self->_backend_capability(
940
        'get_supplier_update',
941
        {
942
            request => $self,
943
            %{$options}
944
        }
945
    );
946
    return $response;
947
}
948
899
=head3 expandTemplate
949
=head3 expandTemplate
900
950
901
    my $params = $abstract->expandTemplate($params);
951
    my $params = $abstract->expandTemplate($params);
Lines 1419-1425 Send a specified notice regarding this request to a patron Link Here
1419
=cut
1469
=cut
1420
1470
1421
sub send_patron_notice {
1471
sub send_patron_notice {
1422
    my ( $self, $notice_code ) = @_;
1472
    my ( $self, $notice_code, $additional_text ) = @_;
1423
1473
1424
    # We need a notice code
1474
    # We need a notice code
1425
    if (!$notice_code) {
1475
    if (!$notice_code) {
Lines 1430-1437 sub send_patron_notice { Link Here
1430
1480
1431
    # Map from the notice code to the messaging preference
1481
    # Map from the notice code to the messaging preference
1432
    my %message_name = (
1482
    my %message_name = (
1433
        ILL_PICKUP_READY   => 'Ill_ready',
1483
        ILL_PICKUP_READY    => 'Ill_ready',
1434
        ILL_REQUEST_UNAVAIL => 'Ill_unavailable'
1484
        ILL_REQUEST_UNAVAIL => 'Ill_unavailable',
1485
        ILL_REQUEST_UPDATE  => 'Ill_update'
1435
    );
1486
    );
1436
1487
1437
    # Get the patron's messaging preferences
1488
    # Get the patron's messaging preferences
Lines 1453-1460 sub send_patron_notice { Link Here
1453
    my @fail = ();
1504
    my @fail = ();
1454
    for my $transport (@transports) {
1505
    for my $transport (@transports) {
1455
        my $letter = $self->get_notice({
1506
        my $letter = $self->get_notice({
1456
            notice_code => $notice_code,
1507
            notice_code     => $notice_code,
1457
            transport   => $transport
1508
            transport       => $transport,
1509
            additional_text => $additional_text
1458
        });
1510
        });
1459
        if ($letter) {
1511
        if ($letter) {
1460
            my $result = C4::Letters::EnqueueLetter({
1512
            my $result = C4::Letters::EnqueueLetter({
Lines 1595-1607 sub get_notice { Link Here
1595
        substitute  => {
1647
        substitute  => {
1596
            ill_bib_title      => $title ? $title->value : '',
1648
            ill_bib_title      => $title ? $title->value : '',
1597
            ill_bib_author     => $author ? $author->value : '',
1649
            ill_bib_author     => $author ? $author->value : '',
1598
            ill_full_metadata  => $metastring
1650
            ill_full_metadata  => $metastring,
1651
            additional_text    => $params->{additional_text}
1599
        }
1652
        }
1600
    );
1653
    );
1601
1654
1602
    return $letter;
1655
    return $letter;
1603
}
1656
}
1604
1657
1658
1659
=head3 attach_processors
1660
1661
Receive a Koha::Illrequest::SupplierUpdate and attach
1662
any processors we have for it
1663
1664
=cut
1665
1666
sub attach_processors {
1667
    my ( $self, $update ) = @_;
1668
1669
    foreach my $processor(@{$self->{processors}}) {
1670
        if (
1671
            $processor->{target_source_type} eq $update->{source_type} &&
1672
            $processor->{target_source_name} eq $update->{source_name}
1673
        ) {
1674
            $update->attach_processor($processor);
1675
        }
1676
    }
1677
}
1678
1679
=head3 append_to_note
1680
1681
    append_to_note("Some text");
1682
1683
Append some text to the staff note
1684
1685
=cut
1686
1687
sub append_to_note {
1688
    my ($self, $text) = @_;
1689
    my $current = $self->notesstaff;
1690
    $text = ($current && length $current > 0) ? "$current\n\n$text" : $text;
1691
    $self->notesstaff($text)->store;
1692
}
1693
1605
=head3 id_prefix
1694
=head3 id_prefix
1606
1695
1607
    my $prefix = $record->id_prefix;
1696
    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