302 lines
12 KiB
Perl
302 lines
12 KiB
Perl
package Koha::BackgroundJob::CreateEHoldingsFromBiblios;
|
|
|
|
# This file is part of Koha.
|
|
#
|
|
# 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 <https://www.gnu.org/licenses>.
|
|
|
|
use Modern::Perl;
|
|
use JSON qw( decode_json encode_json );
|
|
use Try::Tiny;
|
|
|
|
use Koha::Biblios;
|
|
use Koha::ERM::EHoldings::Titles;
|
|
use Koha::ERM::EHoldings::Resources;
|
|
|
|
use C4::Context;
|
|
|
|
use base 'Koha::BackgroundJob';
|
|
|
|
=head1 NAME
|
|
|
|
CreateEHoldingsFromBiblios - Create new eHoldings titles from biblios
|
|
|
|
This is a subclass of Koha::BackgroundJob.
|
|
|
|
=head1 API
|
|
|
|
=head2 Class methods
|
|
|
|
=head3 job_type
|
|
|
|
Define the job type of this job.
|
|
|
|
=cut
|
|
|
|
sub job_type {
|
|
return 'create_eholdings_from_biblios';
|
|
}
|
|
|
|
my $fix_coverage = sub {
|
|
my $coverage = shift || q{};
|
|
my @coverages = split '-', $coverage;
|
|
return ( $coverages[0], ( @coverages > 1 ? $coverages[1] : q{} ) );
|
|
};
|
|
|
|
sub _get_unimarc_mapping {
|
|
my ($biblio) = @_;
|
|
my $record = $biblio->metadata->record;
|
|
my $biblio_id = $biblio->biblionumber;
|
|
my $publication_title = $biblio->title;
|
|
my $print_identifier =
|
|
$record->subfield( '010', 'a' )
|
|
|| $record->subfield( '010', 'z' )
|
|
|| $record->subfield( '011', 'a' )
|
|
|| $record->subfield( '011', 'y' );
|
|
my $online_identifier = $print_identifier;
|
|
my $date_first_issue_online = $record->subfield( '955', 'a' );
|
|
my $date_last_issue_online = $record->subfield( '955', 'k' );
|
|
my $num_first_vol_online = $record->subfield( '955', 'd' );
|
|
my $num_last_vol_online = $record->subfield( '955', 'n' );
|
|
my $num_first_issue_online = $record->subfield( '955', 'e' );
|
|
my $num_last_issue_online = $record->subfield( '955', 'o' );
|
|
my $title_url = $record->subfield( '856', 'u' );
|
|
my $first_author = $biblio->author;
|
|
my $embargo_info = $record->subfield( '371', 'a' );
|
|
my $coverage_depth = $title_url ? 'fulltext' : 'print';
|
|
my $notes = $record->subfield( '336', 'a' );
|
|
my $publisher_name = $record->subfield( '214', 'c' );
|
|
my $label_pos67 = substr( $record->leader, 6, 2 );
|
|
my $publication_type = $label_pos67 eq 'am' ? 'monograph' : $label_pos67 eq 'as' ? 'serial' : '';
|
|
my $date_monograph_published_print =
|
|
$record->subfield( '214', 'd' ) || substr( $record->subfield( 100, 'a' ), 9, 4 ) || '';
|
|
my $date_monograph_published_online = $date_monograph_published_print;
|
|
my $monograph_volume = $record->subfield( '200', 'v' );
|
|
my $monograph_edition = $record->subfield( '205', 'a' );
|
|
my $first_editor = $publisher_name;
|
|
my $parent_publication_title_id = ''; # FIXME ?
|
|
my $preceding_publication_title_id = ''; # FIXME ?
|
|
my $access_type = $record->subfield( '856', 'y' );
|
|
|
|
return {
|
|
biblio_id => $biblio_id,
|
|
publication_title => $publication_title,
|
|
print_identifier => $print_identifier,
|
|
online_identifier => $online_identifier,
|
|
date_first_issue_online => $date_first_issue_online,
|
|
num_first_vol_online => $num_first_vol_online,
|
|
num_first_issue_online => $num_first_issue_online,
|
|
date_last_issue_online => $date_last_issue_online,
|
|
num_last_vol_online => $num_last_vol_online,
|
|
num_last_issue_online => $num_last_issue_online,
|
|
title_url => $title_url,
|
|
first_author => $first_author,
|
|
embargo_info => $embargo_info,
|
|
coverage_depth => $coverage_depth,
|
|
notes => $notes,
|
|
publisher_name => $publisher_name,
|
|
publication_type => $publication_type,
|
|
date_monograph_published_print => $date_monograph_published_print,
|
|
date_monograph_published_online => $date_monograph_published_online,
|
|
monograph_volume => $monograph_volume,
|
|
monograph_edition => $monograph_edition,
|
|
first_editor => $first_editor,
|
|
parent_publication_title_id => $parent_publication_title_id,
|
|
preceding_publication_title_id => $preceding_publication_title_id,
|
|
access_type => $access_type,
|
|
};
|
|
}
|
|
|
|
sub _get_marc21_mapping {
|
|
my ($biblio) = @_;
|
|
my $record = $biblio->metadata->record;
|
|
my $biblio_id = $biblio->biblionumber;
|
|
my $publication_title = $biblio->title;
|
|
my $print_identifier =
|
|
$record->subfield( '020', 'a' )
|
|
|| $record->subfield( '020', 'z' )
|
|
|| $record->subfield( '022', 'a' )
|
|
|| $record->subfield( '022', 'y' );
|
|
my $online_identifier = $print_identifier;
|
|
my ( $date_first_issue_online, $date_last_issue_online ) =
|
|
$fix_coverage->( $record->subfield( '866', 'a' ) );
|
|
my ( $num_first_vol_online, $num_last_vol_online ) =
|
|
$fix_coverage->( $record->subfield( '863', 'a' ) );
|
|
my ( $num_first_issue_online, $num_last_issue_online ) = ( '', '' ); # FIXME ?
|
|
my $title_url = $record->subfield( '856', 'u' );
|
|
my $first_author = $biblio->author;
|
|
my $embargo_info = ''; # FIXME ?
|
|
my $coverage_depth = $title_url ? 'fulltext' : 'print';
|
|
my $notes = $record->subfield( '852', 'z' );
|
|
my $publisher_name = $record->subfield( '260', 'b' );
|
|
my $publication_type = ''; # FIXME ?
|
|
my $date_monograph_published_print = ''; # FIXME ?
|
|
my $date_monograph_published_online = ''; # FIXME ?
|
|
my $monograph_volume = ''; # FIXME ?
|
|
my $monograph_edition = ''; # FIXME ?
|
|
my $first_editor = ''; # FIXME ?
|
|
my $parent_publication_title_id = ''; # FIXME ?
|
|
my $preceding_publication_title_id = ''; # FIXME ?
|
|
my $access_type = ''; # FIXME ?
|
|
|
|
return {
|
|
biblio_id => $biblio_id,
|
|
publication_title => $publication_title,
|
|
print_identifier => $print_identifier,
|
|
online_identifier => $online_identifier,
|
|
date_first_issue_online => $date_first_issue_online,
|
|
num_first_vol_online => $num_first_vol_online,
|
|
num_first_issue_online => $num_first_issue_online,
|
|
date_last_issue_online => $date_last_issue_online,
|
|
num_last_vol_online => $num_last_vol_online,
|
|
num_last_issue_online => $num_last_issue_online,
|
|
title_url => $title_url,
|
|
first_author => $first_author,
|
|
embargo_info => $embargo_info,
|
|
coverage_depth => $coverage_depth,
|
|
notes => $notes,
|
|
publisher_name => $publisher_name,
|
|
publication_type => $publication_type,
|
|
date_monograph_published_print => $date_monograph_published_print,
|
|
date_monograph_published_online => $date_monograph_published_online,
|
|
monograph_volume => $monograph_volume,
|
|
monograph_edition => $monograph_edition,
|
|
first_editor => $first_editor,
|
|
parent_publication_title_id => $parent_publication_title_id,
|
|
preceding_publication_title_id => $preceding_publication_title_id,
|
|
access_type => $access_type,
|
|
};
|
|
}
|
|
|
|
=head3 process
|
|
|
|
Process the import.
|
|
|
|
=cut
|
|
|
|
sub process {
|
|
my ( $self, $args ) = @_;
|
|
|
|
if ( $self->status eq 'cancelled' ) {
|
|
return;
|
|
}
|
|
|
|
$self->start;
|
|
|
|
my @messages;
|
|
my @record_ids = @{ $args->{record_ids} };
|
|
my $package_id = $args->{package_id};
|
|
|
|
my $report = {
|
|
total_records => scalar @record_ids,
|
|
total_success => 0,
|
|
};
|
|
|
|
my $package = Koha::ERM::EHoldings::Packages->find($package_id);
|
|
unless ($package) {
|
|
push @messages, {
|
|
type => 'error',
|
|
code => 'package_do_not_exist',
|
|
package_id => $package_id,
|
|
};
|
|
|
|
my $data = $self->decoded_data;
|
|
$data->{messages} = \@messages;
|
|
$data->{report} = $report;
|
|
|
|
return $self->finish($data);
|
|
}
|
|
|
|
my %existing_biblio_ids = map {
|
|
my $resource = $_;
|
|
map { $_->biblio_id => $resource->resource_id } $resource->title
|
|
} $package->resources->as_list;
|
|
|
|
RECORD_IDS: for my $biblio_id ( sort { $a <=> $b } @record_ids ) {
|
|
|
|
last if $self->get_from_storage->status eq 'cancelled';
|
|
|
|
next unless $biblio_id;
|
|
|
|
try {
|
|
if ( grep { $_ eq $biblio_id } keys %existing_biblio_ids ) {
|
|
push @messages,
|
|
{
|
|
type => 'warning',
|
|
code => 'biblio_already_exists',
|
|
biblio_id => $biblio_id,
|
|
resource_id => $existing_biblio_ids{$biblio_id},
|
|
};
|
|
return;
|
|
}
|
|
my $biblio = Koha::Biblios->find($biblio_id);
|
|
my $eholding_title =
|
|
C4::Context->preference('marcflavour') eq 'UNIMARC'
|
|
? _get_unimarc_mapping($biblio)
|
|
: _get_marc21_mapping($biblio);
|
|
|
|
$eholding_title = Koha::ERM::EHoldings::Title->new($eholding_title)->store;
|
|
Koha::ERM::EHoldings::Resource->new( { title_id => $eholding_title->title_id, package_id => $package_id } )
|
|
->store;
|
|
$report->{total_success}++;
|
|
} catch {
|
|
push @messages, {
|
|
type => 'error',
|
|
code => 'eholding_not_created',
|
|
error => $_,
|
|
};
|
|
};
|
|
$self->step;
|
|
}
|
|
|
|
my $data = $self->decoded_data;
|
|
$data->{messages} = \@messages;
|
|
$data->{report} = $report;
|
|
|
|
$self->finish($data);
|
|
}
|
|
|
|
=head3 enqueue
|
|
|
|
Enqueue the new job
|
|
|
|
=cut
|
|
|
|
sub enqueue {
|
|
my ( $self, $args ) = @_;
|
|
|
|
return unless exists $args->{package_id};
|
|
return unless exists $args->{record_ids};
|
|
|
|
$self->SUPER::enqueue(
|
|
{
|
|
job_size => scalar @{ $args->{record_ids} },
|
|
job_args => $args,
|
|
job_queue => 'long_tasks',
|
|
}
|
|
);
|
|
}
|
|
|
|
=head3 additional_report
|
|
|
|
=cut
|
|
|
|
sub additional_report {
|
|
my ($self) = @_;
|
|
|
|
my $loggedinuser = C4::Context->userenv ? C4::Context->userenv->{'number'} : undef;
|
|
return {};
|
|
}
|
|
|
|
1;
|