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

(-)a/Koha/BackgroundJob.pm (+2 lines)
Lines 449-454 sub core_types_to_classes { Link Here
449
        batch_biblio_record_modification    => 'Koha::BackgroundJob::BatchUpdateBiblio',
449
        batch_biblio_record_modification    => 'Koha::BackgroundJob::BatchUpdateBiblio',
450
        batch_item_record_deletion          => 'Koha::BackgroundJob::BatchDeleteItem',
450
        batch_item_record_deletion          => 'Koha::BackgroundJob::BatchDeleteItem',
451
        batch_item_record_modification      => 'Koha::BackgroundJob::BatchUpdateItem',
451
        batch_item_record_modification      => 'Koha::BackgroundJob::BatchUpdateItem',
452
        batch_add_display_items              => 'Koha::BackgroundJob::BatchAddDisplayItems',
453
        batch_delete_display_items          => 'Koha::BackgroundJob::BatchDeleteDisplayItems',
452
        erm_sushi_harvester                 => 'Koha::BackgroundJob::ErmSushiHarvester',
454
        erm_sushi_harvester                 => 'Koha::BackgroundJob::ErmSushiHarvester',
453
        batch_hold_cancel                   => 'Koha::BackgroundJob::BatchCancelHold',
455
        batch_hold_cancel                   => 'Koha::BackgroundJob::BatchCancelHold',
454
        create_eholdings_from_biblios       => 'Koha::BackgroundJob::CreateEHoldingsFromBiblios',
456
        create_eholdings_from_biblios       => 'Koha::BackgroundJob::CreateEHoldingsFromBiblios',
(-)a/Koha/BackgroundJob/BatchAddDisplayItems.pm (+202 lines)
Line 0 Link Here
1
package Koha::BackgroundJob::BatchAddDisplayItems;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
use Try::Tiny qw( catch try );
20
use DateTime;
21
use C4::Context;
22
23
use Koha::DisplayItem;
24
use Koha::DisplayItems;
25
use Koha::Items;
26
use Koha::Displays;
27
28
use base 'Koha::BackgroundJob';
29
30
=head1 NAME
31
32
Koha::BackgroundJob::BatchAddDisplayItems - Background job to add multiple items to a display
33
34
=head1 API
35
36
=head2 Class methods
37
38
=head3 job_type
39
40
Return the job type 'batch_add_display_items'.
41
42
=cut
43
44
sub job_type {
45
    return 'batch_add_display_items';
46
}
47
48
=head3 process
49
50
Process the batch addition of items to a display
51
52
=cut
53
54
sub process {
55
    my ( $self, $args ) = @_;
56
57
    if ( $self->status eq 'cancelled' ) {
58
        return;
59
    }
60
61
    $self->start;
62
63
    my $display_id  = $args->{display_id};
64
    my @item_ids    = @{ $args->{item_ids} };
65
    my $date_remove = $args->{date_remove};
66
67
    my $report = {
68
        total_records => scalar @item_ids,
69
        total_success => 0,
70
        total_errors  => 0,
71
    };
72
73
    my @messages;
74
    my @added_items;
75
    my @failed_items;
76
77
    # Validate display exists
78
    my $display = Koha::Displays->find($display_id);
79
    unless ($display) {
80
        push @messages, {
81
            type       => 'error',
82
            code       => 'display_not_found',
83
            display_id => $display_id,
84
        };
85
        $self->finish( { messages => \@messages, report => $report } );
86
        return;
87
    }
88
89
    # Calculate date_remove from display_days if not provided
90
    unless ($date_remove) {
91
        if ( $display->display_days ) {
92
            my $dt = DateTime->now( time_zone => C4::Context->tz() );
93
            $dt->add( days => $display->display_days );
94
            $date_remove = $dt->ymd;
95
        }
96
    }
97
98
    try {
99
        my $schema = Koha::Database->new->schema;
100
        $schema->txn_do(
101
            sub {
102
                for my $item_id ( sort { $a <=> $b } @item_ids ) {
103
104
                    last if $self->get_from_storage->status eq 'cancelled';
105
106
                    my $item = Koha::Items->find($item_id);
107
                    unless ($item) {
108
                        push @failed_items, {
109
                            itemnumber => $item_id,
110
                            error      => 'Item not found'
111
                        };
112
                        $report->{total_errors}++;
113
                        next;
114
                    }
115
116
                    # Check if item is already in this display
117
                    my $existing = Koha::DisplayItems->search(
118
                        {
119
                            display_id => $display_id,
120
                            itemnumber => $item_id,
121
                        }
122
                    )->next;
123
124
                    if ($existing) {
125
                        push @failed_items, {
126
                            itemnumber => $item_id,
127
                            error      => 'Item already in display'
128
                        };
129
                        $report->{total_errors}++;
130
                        next;
131
                    }
132
133
                    # Create display item
134
                    my $display_item = Koha::DisplayItem->new(
135
                        {
136
                            display_id   => $display_id,
137
                            itemnumber   => $item_id,
138
                            biblionumber => $item->biblionumber,
139
                            date_remove  => $date_remove,
140
                        }
141
                    )->store;
142
143
                    push @added_items, {
144
                        display_item_id => $display_item->display_item_id,
145
                        itemnumber      => $item_id,
146
                        biblionumber    => $item->biblionumber,
147
                    };
148
149
                    $report->{total_success}++;
150
                    $self->step;
151
                }
152
            }
153
        );
154
    } catch {
155
        warn $_;
156
        push @messages, {
157
            type  => 'error',
158
            code  => 'unknown',
159
            error => $_,
160
        };
161
        die "Something terrible has happened!" if ( $_ =~ /Rollback failed/ );
162
    };
163
164
    $report->{added_items}  = \@added_items;
165
    $report->{failed_items} = \@failed_items;
166
167
    my $data = $self->decoded_data;
168
    $data->{messages} = \@messages;
169
    $data->{report}   = $report;
170
171
    $self->finish($data);
172
}
173
174
=head3 enqueue
175
176
Enqueue the job.
177
178
=cut
179
180
sub enqueue {
181
    my ( $self, $args ) = @_;
182
183
    return unless exists $args->{item_ids} && exists $args->{display_id};
184
185
    my @item_ids    = @{ $args->{item_ids} };
186
    my $display_id  = $args->{display_id};
187
    my $date_remove = $args->{date_remove};
188
189
    $self->SUPER::enqueue(
190
        {
191
            job_size => scalar @item_ids,
192
            job_args => {
193
                display_id  => $display_id,
194
                item_ids    => \@item_ids,
195
                date_remove => $date_remove,
196
            },
197
            job_queue => 'long_tasks',
198
        }
199
    );
200
}
201
202
1;
(-)a/Koha/BackgroundJob/BatchDeleteDisplayItems.pm (-1 / +173 lines)
Line 0 Link Here
0
- 
1
package Koha::BackgroundJob::BatchDeleteDisplayItems;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
use Try::Tiny qw( catch try );
20
21
use Koha::DisplayItem;
22
use Koha::DisplayItems;
23
use Koha::Items;
24
25
use base 'Koha::BackgroundJob';
26
27
=head1 NAME
28
29
Koha::BackgroundJob::BatchDeleteDisplayItems - Background job to remove multiple items from displays
30
31
=head1 API
32
33
=head2 Class methods
34
35
=head3 job_type
36
37
Return the job type 'batch_delete_display_items'.
38
39
=cut
40
41
sub job_type {
42
    return 'batch_delete_display_items';
43
}
44
45
=head3 process
46
47
Process the batch removal of items from displays
48
49
=cut
50
51
sub process {
52
    my ( $self, $args ) = @_;
53
54
    if ( $self->status eq 'cancelled' ) {
55
        return;
56
    }
57
58
    $self->start;
59
60
    my @item_ids   = @{ $args->{item_ids} };
61
    my $display_id = $args->{display_id}; # Optional: if specified, only remove from this display
62
63
    my $report = {
64
        total_records => scalar @item_ids,
65
        total_success => 0,
66
        total_errors  => 0,
67
    };
68
69
    my @messages;
70
    my @deleted_items;
71
    my @failed_items;
72
73
    try {
74
        my $schema = Koha::Database->new->schema;
75
        $schema->txn_do(
76
            sub {
77
                for my $item_id ( sort { $a <=> $b } @item_ids ) {
78
79
                    last if $self->get_from_storage->status eq 'cancelled';
80
81
                    # Build search criteria
82
                    my $search_criteria = { itemnumber => $item_id };
83
                    $search_criteria->{display_id} = $display_id if $display_id;
84
85
                    my $display_items = Koha::DisplayItems->search($search_criteria);
86
87
                    unless ($display_items->count) {
88
                        push @failed_items, {
89
                            itemnumber => $item_id,
90
                            error => $display_id ? 'Item not found in specified display' : 'Item not found in any display'
91
                        };
92
                        $report->{total_errors}++;
93
                        next;
94
                    }
95
96
                    my $deleted_count = 0;
97
                    my @deleted_from_displays;
98
99
                    while (my $display_item = $display_items->next) {
100
                        push @deleted_from_displays, {
101
                            display_id => $display_item->display_id,
102
                            display_item_id => $display_item->display_item_id,
103
                        };
104
                        $display_item->delete;
105
                        $deleted_count++;
106
                    }
107
108
                    if ($deleted_count > 0) {
109
                        push @deleted_items, {
110
                            itemnumber => $item_id,
111
                            displays_removed_from => \@deleted_from_displays,
112
                            count => $deleted_count,
113
                        };
114
                        $report->{total_success}++;
115
                    } else {
116
                        push @failed_items, {
117
                            itemnumber => $item_id,
118
                            error => 'No display items could be deleted'
119
                        };
120
                        $report->{total_errors}++;
121
                    }
122
123
                    $self->step;
124
                }
125
            }
126
        );
127
    } catch {
128
        warn $_;
129
        push @messages, {
130
            type => 'error',
131
            code => 'unknown',
132
            error => $_,
133
        };
134
        die "Something terrible has happened!" if ( $_ =~ /Rollback failed/ );
135
    };
136
137
    $report->{deleted_items} = \@deleted_items;
138
    $report->{failed_items} = \@failed_items;
139
140
    my $data = $self->decoded_data;
141
    $data->{messages} = \@messages;
142
    $data->{report} = $report;
143
144
    $self->finish($data);
145
}
146
147
=head3 enqueue
148
149
Enqueue the job.
150
151
=cut
152
153
sub enqueue {
154
    my ( $self, $args ) = @_;
155
156
    return unless exists $args->{item_ids};
157
158
    my @item_ids = @{ $args->{item_ids} };
159
    my $display_id = $args->{display_id}; # Optional
160
161
    $self->SUPER::enqueue(
162
        {
163
            job_size => scalar @item_ids,
164
            job_args => {
165
                item_ids   => \@item_ids,
166
                display_id => $display_id,
167
            },
168
            job_queue => 'long_tasks',
169
        }
170
    );
171
}
172
173
1;

Return to bug 14962