1 package Koha::ERM::Providers::EBSCO;
7 use JSON qw( from_json decode_json encode_json );
8 use List::Util qw( first );
12 use Koha::ERM::EHoldings::Packages;
17 return bless $self, $class;
22 custid => C4::Context->preference('ERMProviderEbscoCustomerID') || C4::Context->config('ERMProviderEbscoCustomerID'),
23 api_key => C4::Context->preference('ERMProviderEbscoApiKey') || C4::Context->config('ERMProviderEbscoApiKey'),
28 my ( $self, $result ) = @_;
30 title_id => $result->{titleId},
31 publication_title => $result->{titleName},
32 # date_first_issue_online => ?,
33 # num_first_vol_online => ?,
34 # num_first_issue_online => ?,
35 # date_last_issue_online => ?,
36 # num_last_vol_online => ?,
37 # num_last_issue_online => ?,
40 # coverage_depth => ?,
42 publisher_name => $result->{publisherName},
43 publication_type => $result->{pubType},
44 # date_monograph_published_print => ?,
45 # date_monograph_published_online => ?,
46 # monograph_volume => ?,
47 # monograph_edition => ?,
49 # parent_publication_title_id => ?,
50 # preceding_publication_title_id => ?,
53 if ( $result->{contributorsList} ) {
54 my @contributors = @{ $result->{contributorsList} };
55 my $first_author = first { $_->{type} eq 'author' || $_->{type} eq 'Author' } @contributors;
56 if ( $first_author ) {
57 $title->{first_author} = $first_author->{contributor};
60 for my $identifier ( @{ $result->{identifiersList} } ) {
62 # FIXME $identifier->{type} : 0 for ISSN and 1 for ISBN
63 if ( $identifier->{subtype} == 1 ) {
64 $title->{print_identifier} = $identifier->{id};
66 elsif ( $identifier->{subtype} == 2 ) {
67 $title->{online_identifier} = $identifier->{id};
70 for my $r ( @{ $result->{customerResourcesList} } ) {
71 if ( $r->{isSelected} ) {
72 $title->{is_selected} = 1;
81 my ( $self, $result ) = @_;
83 vendor_id => $result->{vendorId},
84 name => $result->{vendorName},
85 package_type => $result->{packageType},
91 my ( $self, $result ) = @_;
92 my $local_package = $self->get_local_package(
93 $result->{vendorId} . '-' . $result->{packageId} );
95 package_id => $result->{vendorId} . '-' . $result->{packageId},
97 ? ( koha_internal_id => $local_package->package_id )
99 name => $result->{packageName},
100 content_type => $result->{contentType}, # This does not exist in /vendors/1/packages/2/titles/3
102 is_selected => $result->{isSelected},
103 package_type => $result->{packageType},
104 vendor_id => $result->{vendorId},
110 my ( $self, $result ) = @_;
112 resource_id => $result->{vendorId} . '-'
113 . $result->{packageId} . '-'
114 . $result->{titleId},
115 package_id => $result->{vendorId} . '-' . $result->{packageId},
116 title_id => $result->{titleId},
117 is_selected => $result->{isSelected},
118 started_on => $result->{managedCoverageList}->[0]->{beginCoverage},
119 ended_on => $result->{managedCoverageList}->[0]->{endCoverage},
124 sub build_additional_params {
125 my ( $self, $query_params ) = @_;
127 my $additional_params;
128 if ( $query_params->{q} ) {
129 my $q = from_json $query_params->{q};
130 while ( my ( $attr, $value ) = each %$q ) {
131 $additional_params->{$attr} = $value;
135 return $additional_params;
138 sub get_local_package {
139 my ( $self, $package_id ) = @_;
140 return Koha::ERM::EHoldings::Packages->find(
141 { provider => 'ebsco', external_id => $package_id } );
145 my ( $self, $object, $info, $embed_header ) = @_;
146 $embed_header ||= q{};
150 foreach my $embed_req ( split /\s*,\s*/, $embed_header ) {
151 if ( $embed_req eq 'vendor.name' ) {
152 $object->{vendor} = { name => $info->{vendorName}, };
154 elsif ( $embed_req eq 'vendor' ) {
155 $object->{vendor} = $self->build_vendor($info);
157 elsif ( $embed_req eq 'title' ) {
158 $object->{title} = $self->build_title($info);
160 elsif ( $embed_req eq 'resources+count' ) {
161 $object->{resources_count} = $info->{titleCount};
163 elsif ( $embed_req eq 'package' ) {
164 $object->{package} = $self->build_package($info);
166 elsif ( $embed_req eq 'package.name' ) {
167 $object->{package} = { name => $info->{packageName}, };
169 elsif ( $embed_req eq 'package_agreements.agreement' ) {
170 # How to deal with 'package_agreements.agreement'?
171 $object->{package_agreements} = [];
172 my $package_id = $info->{vendorId} . '-' . $info->{packageId};
173 my $local_package = $self->get_local_package($package_id);
174 if ( $local_package ) {
175 for my $package_agreement (
176 @{ $local_package->package_agreements->as_list } )
178 push @{ $object->{package_agreements} },
180 %{ $package_agreement->unblessed },
181 agreement => $package_agreement->agreement->unblessed,
186 if ( $embed_req eq 'resources' || $embed_req eq 'resources.package' ) {
187 push @embed_resources, $embed_req;
191 if (@embed_resources) {
192 for my $r ( @{ $info->{customerResourcesList} } ) {
194 for my $embed_req ( @embed_resources ) {
195 if ( $embed_req eq 'resources' ) {
196 $resource = $self->build_resource($r);
198 elsif ( $embed_req eq 'resources.package' ) {
199 unless ( %$resource ) {
200 $resource = $self->build_resource($r);
202 $resource->{package} = $self->build_package($r);
205 push @{$object->{resources}}, $resource;
211 sub build_query_pagination {
212 my ( $self, $params ) = @_;
213 my $per_page = $params->{per_page}
214 // C4::Context->preference('RESTdefaultPageSize') // 20;
215 if ( $per_page == -1 || $per_page > 100 ) { $per_page = 100; }
216 my $page = $params->{page} || 1;
218 return ( $per_page, $page );
222 my ( $self, $url, $params ) = @_;
224 return $url unless $params && %$params;
225 while ( my ( $attr, $value ) = each %$params ) {
226 if ( $attr eq 'name' ) {
227 $url .= '&search=' . $value;
229 elsif ( $attr eq 'content_type' ) {
230 $url .= '&contenttype=' . $value;
232 elsif ( $attr eq 'selection_type' ) {
233 $url .= '&selection=' . $value;
235 elsif ( $attr eq 'publication_title' ) {
236 $url .= '&search=' . $value;
238 elsif ( $attr eq 'publication_type' ) {
239 $url .= '&resourcetype=' . $value;
246 my ( $self, $method, $url, $params, $payload ) = @_;
248 $url = $self->build_query($url, $params) if $params;
250 my $config = $self->config;
251 my $base_url = 'https://api.ebsco.io/rm/rmaccounts/' . $config->{custid};
252 my $request = HTTP::Request->new(
253 $method => $base_url . $url,
254 undef, ( $payload ? encode_json($payload) : undef )
256 $request->header( 'x-api-key' => $config->{api_key} );
257 $request->header( 'content-type' => 'application/json; charset=UTF-8' );
258 my $ua = LWP::UserAgent->new;
259 my $response = $ua->simple_request($request);
260 if ( $response->code >= 400 ) {
261 my $result = decode_json( $response->decoded_content );
263 if ( ref($result) eq 'ARRAY' ) {
264 for my $r (@$result) {
265 $message .= $r->{message};
269 $message = $result->{message} || $result->{Message} || q{};
270 if ( $result->{errors} ) {
271 for my $e ( @{ $result->{errors} } ) {
272 $message .= $e->{message};
276 warn sprintf "ERROR - EBSCO API %s returned %s - %s\n", $url, $response->code, $message;
277 if ( $response->code == 404 ) {
278 Koha::Exceptions::ObjectNotFound->throw($message);
279 } elsif ( $response->code == 401 ) {
280 Koha::Exceptions::Authorization::Unauthorized->throw($message);
282 die sprintf "ERROR requesting EBSCO API\n%s\ncode %s: %s\n", $url, $response->code,
285 } elsif ( $response->code == 204 ) { # No content
289 return decode_json( $response->decoded_content );