Bug 34587: Add IR_A1 fields to COUNTER report
[koha.git] / Koha / BackgroundJob / CreateEHoldingsFromBiblios.pm
1 package Koha::BackgroundJob::CreateEHoldingsFromBiblios;
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 JSON qw( decode_json encode_json );
20 use Try::Tiny;
21
22 use Koha::Biblios;
23 use Koha::ERM::EHoldings::Titles;
24 use Koha::ERM::EHoldings::Resources;
25
26 use C4::Context;
27
28 use base 'Koha::BackgroundJob';
29
30 =head1 NAME
31
32 CreateEHoldingsFromBiblios - Create new eHoldings titles from biblios
33
34 This is a subclass of Koha::BackgroundJob.
35
36 =head1 API
37
38 =head2 Class methods
39
40 =head3 job_type
41
42 Define the job type of this job.
43
44 =cut
45
46 sub job_type {
47     return 'create_eholdings_from_biblios';
48 }
49
50
51 my $fix_coverage = sub {
52     my $coverage = shift || q{};
53     my @coverages = split '-', $coverage;
54     return ($coverages[0], (@coverages > 1 ? $coverages[1] : q{}));
55 };
56
57 sub _get_unimarc_mapping {
58     my ($biblio)          = @_;
59     my $record            = $biblio->metadata->record;
60     my $biblio_id         = $biblio->biblionumber;
61     my $publication_title = $biblio->title;
62     my $print_identifier =
63          $record->subfield( '010', 'a' )
64       || $record->subfield( '010', 'z' )
65       || $record->subfield( '011', 'a' )
66       || $record->subfield( '011', 'y' );
67     my $online_identifier               = $print_identifier;
68     my $date_first_issue_online         = $record->subfield( '955', 'a' );
69     my $date_last_issue_online          = $record->subfield( '955', 'k' );
70     my $num_first_vol_online            = $record->subfield( '955', 'd' );
71     my $num_last_vol_online             = $record->subfield( '955', 'n' );
72     my $num_first_issue_online          = $record->subfield( '955', 'e' );
73     my $num_last_issue_online           = $record->subfield( '955', 'o' );
74     my $title_url                       = $record->subfield( '856', 'u' );
75     my $first_author                    = $biblio->author;
76     my $embargo_info                    = $record->subfield( '371', 'a' );
77     my $coverage_depth                  = $title_url ? 'fulltext' : 'print';
78     my $notes                           = $record->subfield( '336', 'a' );
79     my $publisher_name                  = $record->subfield( '214', 'c' );
80     my $label_pos67                     = substr( $record->leader, 6, 2 );
81     my $publication_type                = $label_pos67 eq 'am' ? 'monograph' : $label_pos67 eq 'as' ? 'serial' : '';
82     my $date_monograph_published_print  = $record->subfield( '214', 'd' ) || substr( $record->subfield(100, 'a'), 9, 4 ) || '';
83     my $date_monograph_published_online = $date_monograph_published_print;
84     my $monograph_volume                = $record->subfield( '200', 'v' );
85     my $monograph_edition               = $record->subfield( '205', 'a' );
86     my $first_editor                    = $publisher_name;
87     my $parent_publication_title_id     = '';                                  # FIXME ?
88     my $preceding_publication_title_id  = '';                                  # FIXME ?
89     my $access_type                     = $record->subfield( '856', 'y' );
90
91     return {
92         biblio_id                       => $biblio_id,
93         publication_title               => $publication_title,
94         print_identifier                => $print_identifier,
95         online_identifier               => $online_identifier,
96         date_first_issue_online         => $date_first_issue_online,
97         num_first_vol_online            => $num_first_vol_online,
98         num_first_issue_online          => $num_first_issue_online,
99         date_last_issue_online          => $date_last_issue_online,
100         num_last_vol_online             => $num_last_vol_online,
101         num_last_issue_online           => $num_last_issue_online,
102         title_url                       => $title_url,
103         first_author                    => $first_author,
104         embargo_info                    => $embargo_info,
105         coverage_depth                  => $coverage_depth,
106         notes                           => $notes,
107         publisher_name                  => $publisher_name,
108         publication_type                => $publication_type,
109         date_monograph_published_print  => $date_monograph_published_print,
110         date_monograph_published_online => $date_monograph_published_online,
111         monograph_volume                => $monograph_volume,
112         monograph_edition               => $monograph_edition,
113         first_editor                    => $first_editor,
114         parent_publication_title_id     => $parent_publication_title_id,
115         preceding_publication_title_id  => $preceding_publication_title_id,
116         access_type                     => $access_type,
117     };
118 }
119
120 sub _get_marc21_mapping {
121     my ($biblio)          = @_;
122     my $record            = $biblio->metadata->record;
123     my $biblio_id         = $biblio->biblionumber;
124     my $publication_title = $biblio->title;
125     my $print_identifier =
126          $record->subfield( '020', 'a' )
127       || $record->subfield( '020', 'z' )
128       || $record->subfield( '022', 'a' )
129       || $record->subfield( '022', 'y' );
130     my $online_identifier = $print_identifier;
131     my ( $date_first_issue_online, $date_last_issue_online ) =
132       $fix_coverage->( $record->subfield( '866', 'a' ) );
133     my ( $num_first_vol_online, $num_last_vol_online ) =
134       $fix_coverage->( $record->subfield( '863', 'a' ) );
135     my ( $num_first_issue_online, $num_last_issue_online ) = ( '', '' );    # FIXME ?
136     my $title_url                       = $record->subfield( '856', 'u' );
137     my $first_author                    = $biblio->author;
138     my $embargo_info                    = '';                                  # FIXME ?
139     my $coverage_depth                  = $title_url ? 'fulltext' : 'print';
140     my $notes                           = $record->subfield( '852', 'z' );
141     my $publisher_name                  = $record->subfield( '260', 'b' );
142     my $publication_type                = '';                                  # FIXME ?
143     my $date_monograph_published_print  = '';                                  # FIXME ?
144     my $date_monograph_published_online = '';                                  # FIXME ?
145     my $monograph_volume                = '';                                  # FIXME ?
146     my $monograph_edition               = '';                                  # FIXME ?
147     my $first_editor                    = '';                                  # FIXME ?
148     my $parent_publication_title_id     = '';                                  # FIXME ?
149     my $preceding_publication_title_id  = '';                                  # FIXME ?
150     my $access_type                     = '';                                  # FIXME ?
151
152     return {
153         biblio_id                       => $biblio_id,
154         publication_title               => $publication_title,
155         print_identifier                => $print_identifier,
156         online_identifier               => $online_identifier,
157         date_first_issue_online         => $date_first_issue_online,
158         num_first_vol_online            => $num_first_vol_online,
159         num_first_issue_online          => $num_first_issue_online,
160         date_last_issue_online          => $date_last_issue_online,
161         num_last_vol_online             => $num_last_vol_online,
162         num_last_issue_online           => $num_last_issue_online,
163         title_url                       => $title_url,
164         first_author                    => $first_author,
165         embargo_info                    => $embargo_info,
166         coverage_depth                  => $coverage_depth,
167         notes                           => $notes,
168         publisher_name                  => $publisher_name,
169         publication_type                => $publication_type,
170         date_monograph_published_print  => $date_monograph_published_print,
171         date_monograph_published_online => $date_monograph_published_online,
172         monograph_volume                => $monograph_volume,
173         monograph_edition               => $monograph_edition,
174         first_editor                    => $first_editor,
175         parent_publication_title_id     => $parent_publication_title_id,
176         preceding_publication_title_id  => $preceding_publication_title_id,
177         access_type                     => $access_type,
178     };
179 }
180
181 =head3 process
182
183 Process the import.
184
185 =cut
186
187 sub process {
188     my ( $self, $args ) = @_;
189
190     if ( $self->status eq 'cancelled' ) {
191         return;
192     }
193
194     $self->start;
195
196     my @messages;
197     my @record_ids = @{ $args->{record_ids} };
198     my $package_id = $args->{package_id};
199
200     my $report = {
201         total_records => scalar @record_ids,
202         total_success => 0,
203     };
204
205     my $package = Koha::ERM::EHoldings::Packages->find($package_id);
206     unless ( $package ) {
207         push @messages, {
208             type => 'error',
209             code => 'package_do_not_exist',
210             package_id => $package_id,
211         };
212
213         my $data = $self->decoded_data;
214         $data->{messages} = \@messages;
215         $data->{report} = $report;
216
217         return $self->finish( $data );
218     }
219
220     my %existing_biblio_ids = map {
221         my $resource = $_;
222         map { $_->biblio_id => $resource->resource_id } $resource->title
223     } $package->resources->as_list;
224
225     RECORD_IDS: for my $biblio_id ( sort { $a <=> $b } @record_ids ) {
226
227         last if $self->get_from_storage->status eq 'cancelled';
228
229         next unless $biblio_id;
230
231         try {
232             if ( grep { $_ eq $biblio_id } keys %existing_biblio_ids ) {
233                 push @messages,
234                   {
235                     type        => 'warning',
236                     code        => 'biblio_already_exists',
237                     biblio_id   => $biblio_id,
238                     resource_id => $existing_biblio_ids{$biblio_id},
239                   };
240                 return;
241             }
242             my $biblio = Koha::Biblios->find($biblio_id);
243             my $eholding_title = C4::Context->preference('marcflavour') eq 'UNIMARC'
244                 ? _get_unimarc_mapping($biblio)
245                 : _get_marc21_mapping($biblio);
246
247             $eholding_title = Koha::ERM::EHoldings::Title->new($eholding_title)->store;
248             Koha::ERM::EHoldings::Resource->new({ title_id => $eholding_title->title_id, package_id => $package_id })->store;
249             $report->{total_success}++;
250         } catch {
251             push @messages, {
252                 type => 'error',
253                 code => 'eholding_not_created',
254                 error => $_,
255             };
256         };
257         $self->step;
258     }
259
260
261     my $data = $self->decoded_data;
262     $data->{messages} = \@messages;
263     $data->{report} = $report;
264
265     $self->finish( $data );
266 }
267
268 =head3 enqueue
269
270 Enqueue the new job
271
272 =cut
273
274 sub enqueue {
275     my ( $self, $args) = @_;
276
277     return unless exists $args->{package_id};
278     return unless exists $args->{record_ids};
279
280     $self->SUPER::enqueue({
281         job_size  => scalar @{$args->{record_ids}},
282         job_args  => $args,
283         job_queue => 'long_tasks',
284     });
285 }
286
287 =head3 additional_report
288
289 =cut
290
291 sub additional_report {
292     my ($self) = @_;
293
294     my $loggedinuser = C4::Context->userenv ? C4::Context->userenv->{'number'} : undef;
295     return {};
296 }
297
298 1;