package Koha::ImportBatch; # This file is part of Koha. # # Copyright 2020 Koha Development Team # # Koha is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # # Koha is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General # Public License along with Koha; if not, see # use Modern::Perl; use Try::Tiny; use Koha::Database; use Koha::ImportBatches; use C4::Matcher; use C4::ImportBatch qw( RecordsFromMARCXMLFile RecordsFromISO2709File RecordsFromMarcPlugin BatchStageMarcRecords BatchFindDuplicates SetImportBatchMatcher SetImportBatchOverlayAction SetImportBatchNoMatchAction SetImportBatchItemAction ); use base qw(Koha::Object); =head1 NAME Koha::ImportBatch - Koha ImportBatch Object class =head1 API =head2 Class Methods =head3 new_from_file Koha::ImportBatch->new_from_file($args); This method is used to create a new Koha::ImportBatch object from a file. If being called from a background job, $args->{job} must be set. =cut sub new_from_file { my ( $self, $args ) = @_; my $job = $args->{job}; my $record_type = $args->{record_type}; my $encoding = $args->{encoding}; my $format = $args->{format}; my $filepath = $args->{filepath}; my $filename = $args->{filename}; my $marc_modification_template = $args->{marc_modification_template}; my $comments = $args->{comments}; my $parse_items = $args->{parse_items}; my $matcher_id = $args->{matcher_id}; my $overlay_action = $args->{overlay_action}; my $nomatch_action = $args->{nomatch_action}; my $item_action = $args->{item_action}; my $vendor_id = $args->{vendor_id}; my $basket_id = $args->{basket_id}; my $profile_id = $args->{profile_id}; my @messages; my ( $batch_id, $num_valid, $num_items, @import_errors ); my $num_with_matches = 0; my $checked_matches = 0; my $matcher_failed = 0; my $matcher_code = ""; my $schema = Koha::Database->new->schema; try { $schema->storage->txn_begin; my ( $errors, $marcrecords ); if ( $format eq 'MARCXML' ) { ( $errors, $marcrecords ) = C4::ImportBatch::RecordsFromMARCXMLFile( $filepath, $encoding ); } elsif ( $format eq 'ISO2709' ) { ( $errors, $marcrecords ) = C4::ImportBatch::RecordsFromISO2709File( $filepath, $record_type, $encoding ); } else { # plugin based $errors = []; $marcrecords = C4::ImportBatch::RecordsFromMarcPlugin( $filepath, $format, $encoding ); } if ($errors) { Koha::Logger->get->warn( 'The following error(s) occurred during ' . ( defined $format ? ( $format . " " ) : "" ) . "record import:\nERROR: " . join( "\nERROR: ", @$errors ) ); } $job->size( scalar @$marcrecords )->store if $job; ( $batch_id, $num_valid, $num_items, @import_errors ) = BatchStageMarcRecords( $record_type, $encoding, $marcrecords, $filename, $marc_modification_template, $comments, '', $parse_items, 0, 50, sub { my $job_progress = shift; if ($matcher_id) { $job_progress /= 2; } $job->progress( int($job_progress) )->store if $job; } ); if ( $num_valid && $job ) { $job->set( { progress => $num_valid, size => $num_valid } ); } else { # We must assume that something went wrong here $job->set( { progress => 0, status => 'failed' } ) if $job; } if ($profile_id) { my $ibatch = Koha::ImportBatches->find($batch_id); $ibatch->set( { profile_id => $profile_id } )->store; } if ($matcher_id) { my $matcher = C4::Matcher->fetch($matcher_id); if ( defined $matcher ) { $checked_matches = 1; $matcher_code = $matcher->code(); $num_with_matches = BatchFindDuplicates( $batch_id, $matcher, 10, 50, sub { my $job_progress = shift; $job->progress($job_progress)->store if $job } ); SetImportBatchMatcher( $batch_id, $matcher_id ); SetImportBatchOverlayAction( $batch_id, $overlay_action ); SetImportBatchNoMatchAction( $batch_id, $nomatch_action ); SetImportBatchItemAction( $batch_id, $item_action ); $schema->storage->txn_commit; } else { $matcher_failed = 1; $schema->storage->txn_rollback; } } else { $schema->storage->txn_commit; } } catch { warn $_; $schema->storage->txn_rollback; die "Something terrible has happened!" if ( $_ =~ /Rollback failed/ ); # TODO Check test: Rollback failed $job->set( { progress => 0, status => 'failed' } ) if $job; }; my $report = { staged => $num_valid, matched => $num_with_matches, num_items => $num_items, import_errors => scalar(@import_errors), total => $num_valid + scalar(@import_errors), checked_matches => $checked_matches, matcher_failed => $matcher_failed, matcher_code => $matcher_code, import_batch_id => $batch_id, vendor_id => $vendor_id, basket_id => $basket_id, }; return { report => $report, messages => \@messages }; } =head3 _type =cut sub _type { return 'ImportBatch'; } 1;