Bug 19915: (QA follow-up) Tidy up GetItemsForInventory.t
[koha.git] / tools / batch_delete_records.pl
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Copyright 2013 BibLibre
6 #
7 # Koha is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as
9 # published by the Free Software Foundation; either version 3
10 # of the License, or (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
18 # Public License along with Koha; if not, see
19 # <http://www.gnu.org/licenses>
20
21 use Modern::Perl;
22
23 use CGI;
24 use List::MoreUtils qw( uniq );
25
26 use C4::Auth;
27 use C4::Output;
28 use C4::AuthoritiesMarc;
29 use C4::Biblio;
30
31 use Koha::Authorities;
32 use Koha::Biblios;
33 use Koha::Items;
34
35 my $input = new CGI;
36 my $op = $input->param('op') // q|form|;
37 my $recordtype = $input->param('recordtype') // 'biblio';
38
39 my ($template, $loggedinuser, $cookie) = get_template_and_user({
40         template_name => 'tools/batch_delete_records.tt',
41         query => $input,
42         type => "intranet",
43         authnotrequired => 0,
44         flagsrequired => { tools => 'records_batchdel' },
45 });
46
47 my @records;
48 my @messages;
49 if ( $op eq 'form' ) {
50     # Display the form
51     $template->param( op => 'form' );
52 } elsif ( $op eq 'list' ) {
53     # List all records to process
54     my @record_ids;
55     if ( my $bib_list = $input->param('bib_list') ) {
56         # Come from the basket
57         @record_ids = split /\//, $bib_list;
58         $recordtype = 'biblio';
59     } elsif ( my $uploadfile = $input->param('uploadfile') ) {
60         # A file of id is given
61         binmode $uploadfile, ':encoding(UTF-8)';
62         while ( my $content = <$uploadfile> ) {
63             next unless $content;
64             $content =~ s/[\r\n]*$//;
65             push @record_ids, $content if $content;
66         }
67     } else {
68         # The user enters manually the list of id
69         push @record_ids, split( /\s\n/, $input->param('recordnumber_list') );
70     }
71
72     for my $record_id ( uniq @record_ids ) {
73         if ( $recordtype eq 'biblio' ) {
74             # Retrieve biblio information
75             my $biblio = Koha::Biblios->find( $record_id );
76             unless ( $biblio ) {
77                 push @messages, {
78                     type => 'warning',
79                     code => 'biblio_not_exists',
80                     biblionumber => $record_id,
81                 };
82                 next;
83             }
84             my $holds_count = $biblio->holds->count;
85             $biblio = $biblio->unblessed;
86             my $record = &GetMarcBiblio({ biblionumber => $record_id });
87             $biblio->{subtitle} = GetRecordValue( 'subtitle', $record, GetFrameworkCode( $record_id ) );
88             $biblio->{itemnumbers} = [Koha::Items->search({ biblionumber => $record_id })->get_column('itemnumber')];
89             $biblio->{holds_count} = $holds_count;
90             $biblio->{issues_count} = C4::Biblio::CountItemsIssued( $record_id );
91             push @records, $biblio;
92         } else {
93             # Retrieve authority information
94             my $authority = C4::AuthoritiesMarc::GetAuthority( $record_id );
95             unless ( $authority ) {
96                 push @messages, {
97                     type => 'warning',
98                     code => 'authority_not_exists',
99                     authid => $record_id,
100                 };
101                 next;
102             }
103
104             $authority = {
105                 authid => $record_id,
106                 summary => C4::AuthoritiesMarc::BuildSummary( $authority, $record_id ),
107                 count_usage => Koha::Authorities->get_usage_count({ authid => $record_id }),
108             };
109             push @records, $authority;
110         }
111     }
112     $template->param(
113         records => \@records,
114         op => 'list',
115     );
116 } elsif ( $op eq 'delete' ) {
117     # We want to delete selected records!
118     my @record_ids = $input->multi_param('record_id');
119     my $schema = Koha::Database->new->schema;
120
121     my $error;
122     my $report = {
123         total_records => 0,
124         total_success => 0,
125     };
126     RECORD_IDS: for my $record_id ( sort { $a <=> $b } @record_ids ) {
127         $report->{total_records}++;
128         next unless $record_id;
129         $schema->storage->txn_begin;
130
131         if ( $recordtype eq 'biblio' ) {
132             # Biblios
133             my $biblionumber = $record_id;
134             # First, checking if issues exist.
135             # If yes, nothing to do
136             my $biblio = Koha::Biblios->find( $biblionumber );
137
138             # TODO Replace with $biblio->get_issues->count
139             if ( C4::Biblio::CountItemsIssued( $biblionumber ) ) {
140                 push @messages, {
141                     type => 'warning',
142                     code => 'item_issued',
143                     biblionumber => $biblionumber,
144                 };
145                 $schema->storage->txn_rollback;
146                 next;
147             }
148
149             # Cancel reserves
150             my $holds = $biblio->holds;
151             while ( my $hold = $holds->next ) {
152                 eval{
153                     $hold->cancel;
154                 };
155                 if ( $@ ) {
156                     push @messages, {
157                         type => 'error',
158                         code => 'reserve_not_cancelled',
159                         biblionumber => $biblionumber,
160                         reserve_id => $hold->reserve_id,
161                         error => $@,
162                     };
163                     $schema->storage->txn_rollback;
164                     next RECORD_IDS;
165                 }
166             }
167
168             # Delete items
169             my @itemnumbers = Koha::Items->search({ biblionumber => $biblionumber })->get_column('itemnumber');
170             ITEMNUMBER: for my $itemnumber ( @itemnumbers ) {
171                 my $error = eval { C4::Items::DelItemCheck( $biblionumber, $itemnumber ) };
172                 if ( $error != 1 or $@ ) {
173                     push @messages, {
174                         type => 'error',
175                         code => 'item_not_deleted',
176                         biblionumber => $biblionumber,
177                         itemnumber => $itemnumber,
178                         error => ($@ ? $@ : $error),
179                     };
180                     $schema->storage->txn_rollback;
181                     next RECORD_IDS;
182                 }
183             }
184
185             # Finally, delete the biblio
186             my $error = eval {
187                 C4::Biblio::DelBiblio( $biblionumber );
188             };
189             if ( $error or $@ ) {
190                 push @messages, {
191                     type => 'error',
192                     code => 'biblio_not_deleted',
193                     biblionumber => $biblionumber,
194                     error => ($@ ? $@ : $error),
195                 };
196                 $schema->storage->txn_rollback;
197                 next;
198             }
199
200             push @messages, {
201                 type => 'success',
202                 code => 'biblio_deleted',
203                 biblionumber => $biblionumber,
204             };
205             $report->{total_success}++;
206             $schema->storage->txn_commit;
207         } else {
208             # Authorities
209             my $authid = $record_id;
210             eval { C4::AuthoritiesMarc::DelAuthority({ authid => $authid }) };
211             if ( $@ ) {
212                 push @messages, {
213                     type => 'error',
214                     code => 'authority_not_deleted',
215                     authid => $authid,
216                     error => ($@ ? $@ : 0),
217                 };
218                 $schema->storage->txn_rollback;
219                 next;
220             } else {
221                 push @messages, {
222                     type => 'success',
223                     code => 'authority_deleted',
224                     authid => $authid,
225                 };
226                 $report->{total_success}++;
227                 $schema->storage->txn_commit;
228             }
229         }
230     }
231     $template->param(
232         op => 'report',
233         report => $report,
234     );
235 }
236
237 $template->param(
238     messages => \@messages,
239     recordtype => $recordtype,
240 );
241
242 output_html_with_http_headers $input, $cookie, $template->output;