| Line 0
          
      
      
        Link Here | 
            
              |  |  | 1 | package Koha::BackgroundJob::BatchDeleteBiblio; | 
            
              | 2 |  | 
            
              | 3 | use Modern::Perl; | 
            
              | 4 | use JSON qw( encode_json decode_json ); | 
            
              | 5 |  | 
            
              | 6 | use Koha::BackgroundJobs; | 
            
              | 7 | use Koha::DateUtils qw( dt_from_string ); | 
            
              | 8 | use C4::Biblio; | 
            
              | 9 |  | 
            
              | 10 | use base 'Koha::BackgroundJob'; | 
            
              | 11 |  | 
            
              | 12 | sub job_type { | 
            
              | 13 |     return 'batch_biblio_record_deletion'; | 
            
              | 14 | } | 
            
              | 15 |  | 
            
              | 16 | sub process { | 
            
              | 17 |     my ( $self, $args ) = @_; | 
            
              | 18 |  | 
            
              | 19 |     my $job_type = $args->{job_type}; | 
            
              | 20 |  | 
            
              | 21 |     my $job = Koha::BackgroundJobs->find( $args->{job_id} ); | 
            
              | 22 |  | 
            
              | 23 |     if ( !exists $args->{job_id} || !$job || $job->status eq 'cancelled' ) { | 
            
              | 24 |         return; | 
            
              | 25 |     } | 
            
              | 26 |  | 
            
              | 27 |     # FIXME If the job has already been started, but started again (worker has been restart for instance) | 
            
              | 28 |     # Then we will start from scratch and so double delete the same records | 
            
              | 29 |  | 
            
              | 30 |     my $job_progress = 0; | 
            
              | 31 |     $job->started_on(dt_from_string) | 
            
              | 32 |         ->progress($job_progress) | 
            
              | 33 |         ->status('started') | 
            
              | 34 |         ->store; | 
            
              | 35 |  | 
            
              | 36 |     my $mmtid = $args->{mmtid}; | 
            
              | 37 |     my @record_ids = @{ $args->{record_ids} }; | 
            
              | 38 |  | 
            
              | 39 |     my $report = { | 
            
              | 40 |         total_records => scalar @record_ids, | 
            
              | 41 |         total_success => 0, | 
            
              | 42 |     }; | 
            
              | 43 |     my @messages; | 
            
              | 44 |     my $schema = Koha::Database->new->schema; | 
            
              | 45 |     RECORD_IDS: for my $record_id ( sort { $a <=> $b } @record_ids ) { | 
            
              | 46 |  | 
            
              | 47 |         last if $job->get_from_storage->status eq 'cancelled'; | 
            
              | 48 |  | 
            
              | 49 |         next unless $record_id; | 
            
              | 50 |  | 
            
              | 51 |         $schema->storage->txn_begin; | 
            
              | 52 |  | 
            
              | 53 |         my $biblionumber = $record_id; | 
            
              | 54 |         # First, checking if issues exist. | 
            
              | 55 |         # If yes, nothing to do | 
            
              | 56 |         my $biblio = Koha::Biblios->find( $biblionumber ); | 
            
              | 57 |  | 
            
              | 58 |         # TODO Replace with $biblio->get_issues->count | 
            
              | 59 |         if ( C4::Biblio::CountItemsIssued( $biblionumber ) ) { | 
            
              | 60 |             push @messages, { | 
            
              | 61 |                 type => 'warning', | 
            
              | 62 |                 code => 'item_issued', | 
            
              | 63 |                 biblionumber => $biblionumber, | 
            
              | 64 |             }; | 
            
              | 65 |             $schema->storage->txn_rollback; | 
            
              | 66 |             $job->progress( ++$job_progress )->store; | 
            
              | 67 |             next; | 
            
              | 68 |         } | 
            
              | 69 |  | 
            
              | 70 |         # Cancel reserves | 
            
              | 71 |         my $holds = $biblio->holds; | 
            
              | 72 |         while ( my $hold = $holds->next ) { | 
            
              | 73 |             eval{ | 
            
              | 74 |                 $hold->cancel; | 
            
              | 75 |             }; | 
            
              | 76 |             if ( $@ ) { | 
            
              | 77 |                 push @messages, { | 
            
              | 78 |                     type => 'error', | 
            
              | 79 |                     code => 'reserve_not_cancelled', | 
            
              | 80 |                     biblionumber => $biblionumber, | 
            
              | 81 |                     reserve_id => $hold->reserve_id, | 
            
              | 82 |                     error => $@, | 
            
              | 83 |                 }; | 
            
              | 84 |                 $schema->storage->txn_rollback; | 
            
              | 85 |                 $job->progress( ++$job_progress )->store; | 
            
              | 86 |                 next RECORD_IDS; | 
            
              | 87 |             } | 
            
              | 88 |         } | 
            
              | 89 |  | 
            
              | 90 |         # Delete items | 
            
              | 91 |         my $items = Koha::Items->search({ biblionumber => $biblionumber }); | 
            
              | 92 |         while ( my $item = $items->next ) { | 
            
              | 93 |             my $error = $item->safe_delete; | 
            
              | 94 |             if(ref($error) ne 'Koha::Item'){ | 
            
              | 95 |                 push @messages, { | 
            
              | 96 |                     type => 'error', | 
            
              | 97 |                     code => 'item_not_deleted', | 
            
              | 98 |                     biblionumber => $biblionumber, | 
            
              | 99 |                     itemnumber => $item->itemnumber, | 
            
              | 100 |                     error => $error, | 
            
              | 101 |                 }; | 
            
              | 102 |                 $schema->storage->txn_rollback; | 
            
              | 103 |                 $job->progress( ++$job_progress )->store; | 
            
              | 104 |                 next RECORD_IDS; | 
            
              | 105 |             } | 
            
              | 106 |         } | 
            
              | 107 |  | 
            
              | 108 |         # Finally, delete the biblio | 
            
              | 109 |         my $error = eval { | 
            
              | 110 |             C4::Biblio::DelBiblio( $biblionumber ); | 
            
              | 111 |         }; | 
            
              | 112 |         if ( $error or $@ ) { | 
            
              | 113 |             push @messages, { | 
            
              | 114 |                 type => 'error', | 
            
              | 115 |                 code => 'biblio_not_deleted', | 
            
              | 116 |                 biblionumber => $biblionumber, | 
            
              | 117 |                 error => ($@ ? $@ : $error), | 
            
              | 118 |             }; | 
            
              | 119 |             $schema->storage->txn_rollback; | 
            
              | 120 |             $job->progress( ++$job_progress )->store; | 
            
              | 121 |             next; | 
            
              | 122 |         } | 
            
              | 123 |  | 
            
              | 124 |         push @messages, { | 
            
              | 125 |             type => 'success', | 
            
              | 126 |             code => 'biblio_deleted', | 
            
              | 127 |             biblionumber => $biblionumber, | 
            
              | 128 |         }; | 
            
              | 129 |         $report->{total_success}++; | 
            
              | 130 |         $schema->storage->txn_commit; | 
            
              | 131 |         $job->progress( ++$job_progress )->store; | 
            
              | 132 |     } | 
            
              | 133 |  | 
            
              | 134 |     my $job_data = decode_json $job->data; | 
            
              | 135 |     $job_data->{messages} = \@messages; | 
            
              | 136 |     $job_data->{report} = $report; | 
            
              | 137 |  | 
            
              | 138 |     $job->ended_on(dt_from_string) | 
            
              | 139 |         ->data(encode_json $job_data); | 
            
              | 140 |     $job->status('finished') if $job->status ne 'cancelled'; | 
            
              | 141 |     $job->store; | 
            
              | 142 | } | 
            
              | 143 |  | 
            
              | 144 | sub enqueue { | 
            
              | 145 |     my ( $self, $args) = @_; | 
            
              | 146 |  | 
            
              | 147 |     # TODO Raise exception instead | 
            
              | 148 |     return unless exists $args->{record_ids}; | 
            
              | 149 |  | 
            
              | 150 |     my @record_ids = @{ $args->{record_ids} }; | 
            
              | 151 |  | 
            
              | 152 |     $self->SUPER::enqueue({ | 
            
              | 153 |         job_size => scalar @record_ids, | 
            
              | 154 |         job_args => {record_ids => \@record_ids,} | 
            
              | 155 |     }); | 
            
              | 156 | } | 
            
              | 157 |  | 
            
              | 158 | 1; |