Bug 34587: Add reports by data provider
[koha.git] / Koha / REST / V1 / ERM / UsageDataProviders.pm
1 package Koha::REST::V1::ERM::UsageDataProviders;
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
20 use Mojo::Base 'Mojolicious::Controller';
21
22 use Koha::ERM::UsageDataProviders;
23
24 use Scalar::Util qw( blessed );
25 use Try::Tiny    qw( catch try );
26
27 =head1 API
28
29 =head2 Methods
30
31 =head3 list
32
33 =cut
34
35 sub list {
36     my $c = shift->openapi->valid_input or return;
37
38     return try {
39         my $usage_data_providers_set = Koha::ERM::UsageDataProviders->new;
40         my $usage_data_providers =
41           $c->objects->search($usage_data_providers_set);
42         if (   $c->validation->output->{"x-koha-embed"}[0]
43             && $c->validation->output->{"x-koha-embed"}[0] eq 'counter_files' )
44         {
45             foreach my $provider (@$usage_data_providers) {
46                 my $title_dates = _get_earliest_and_latest_dates( 'TR',
47                     $provider->{erm_usage_data_provider_id} );
48                 $provider->{earliest_title} =
49                     $title_dates->{earliest_date}
50                   ? $title_dates->{earliest_date}
51                   : '';
52                 $provider->{latest_title} =
53                     $title_dates->{latest_date}
54                   ? $title_dates->{latest_date}
55                   : '';
56
57                 my $platform_dates = _get_earliest_and_latest_dates( 'PR',
58                     $provider->{erm_usage_data_provider_id} );
59                 $provider->{earliest_platform} =
60                     $platform_dates->{earliest_date}
61                   ? $platform_dates->{earliest_date}
62                   : '';
63                 $provider->{latest_platform} =
64                     $platform_dates->{latest_date}
65                   ? $platform_dates->{latest_date}
66                   : '';
67
68                 my $item_dates = _get_earliest_and_latest_dates( 'IR',
69                     $provider->{erm_usage_data_provider_id} );
70                 $provider->{earliest_item} =
71                     $item_dates->{earliest_date}
72                   ? $item_dates->{earliest_date}
73                   : '';
74                 $provider->{latest_item} =
75                   $item_dates->{latest_date} ? $item_dates->{latest_date} : '';
76
77                 my $database_dates = _get_earliest_and_latest_dates( 'DR',
78                     $provider->{erm_usage_data_provider_id} );
79                 $provider->{earliest_database} =
80                     $database_dates->{earliest_date}
81                   ? $database_dates->{earliest_date}
82                   : '';
83                 $provider->{latest_database} =
84                     $database_dates->{latest_date}
85                   ? $database_dates->{latest_date}
86                   : '';
87             }
88         }
89
90         return $c->render( status => 200, openapi => $usage_data_providers );
91     }
92     catch {
93         $c->unhandled_exception($_);
94     };
95
96 }
97
98 =head3 get
99
100 Controller function that handles retrieving a single Koha::ERM::UsageDataProvider object
101
102 =cut
103
104 sub get {
105     my $c = shift->openapi->valid_input or return;
106
107     return try {
108         my $usage_data_provider_id =
109           $c->validation->param('erm_usage_data_provider_id');
110         my $usage_data_provider =
111           $c->objects->find( Koha::ERM::UsageDataProviders->search,
112             $usage_data_provider_id );
113
114         unless ($usage_data_provider) {
115             return $c->render(
116                 status  => 404,
117                 openapi => { error => "Usage data provider not found" }
118             );
119         }
120
121         return $c->render(
122             status  => 200,
123             openapi => $usage_data_provider
124         );
125     }
126     catch {
127         $c->unhandled_exception($_);
128     };
129 }
130
131 =head3 add
132
133 Controller function that handles adding a new Koha::ERM::UsageDataProvider object
134
135 =cut
136
137 sub add {
138     my $c = shift->openapi->valid_input or return;
139
140     return try {
141         Koha::Database->new->schema->txn_do(
142             sub {
143
144                 my $body = $c->validation->param('body');
145
146                 my $usage_data_provider =
147                   Koha::ERM::UsageDataProvider->new_from_api($body)->store;
148
149                 $c->res->headers->location( $c->req->url->to_string . '/'
150                       . $usage_data_provider->erm_usage_data_provider_id );
151                 return $c->render(
152                     status  => 201,
153                     openapi => $usage_data_provider->to_api
154                 );
155             }
156         );
157     }
158     catch {
159
160         my $to_api_mapping = Koha::ERM::UsageDataProvider->new->to_api_mapping;
161
162         if ( blessed $_ ) {
163             if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
164                 return $c->render(
165                     status  => 409,
166                     openapi =>
167                       { error => $_->error, conflict => $_->duplicate_id }
168                 );
169             }
170             elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) {
171                 return $c->render(
172                     status  => 400,
173                     openapi => {
174                             error => "Given "
175                           . $to_api_mapping->{ $_->broken_fk }
176                           . " does not exist"
177                     }
178                 );
179             }
180             elsif ( $_->isa('Koha::Exceptions::BadParameter') ) {
181                 return $c->render(
182                     status  => 400,
183                     openapi => {
184                             error => "Given "
185                           . $to_api_mapping->{ $_->parameter }
186                           . " does not exist"
187                     }
188                 );
189             }
190             elsif ( $_->isa('Koha::Exceptions::PayloadTooLarge') ) {
191                 return $c->render(
192                     status  => 413,
193                     openapi => { error => $_->error }
194                 );
195             }
196         }
197
198         $c->unhandled_exception($_);
199     };
200 }
201
202 =head3 update
203
204 Controller function that handles updating a Koha::ERM::UsageDataProvider object
205
206 =cut
207
208 sub update {
209     my $c = shift->openapi->valid_input or return;
210
211     my $usage_data_provider_id =
212       $c->validation->param('erm_usage_data_provider_id');
213     my $usage_data_provider =
214       Koha::ERM::UsageDataProviders->find($usage_data_provider_id);
215
216     unless ($usage_data_provider) {
217         return $c->render(
218             status  => 404,
219             openapi => { error => "Usage data provider not found" }
220         );
221     }
222
223     return try {
224         Koha::Database->new->schema->txn_do(
225             sub {
226
227                 my $body = $c->validation->param('body');
228
229                 $usage_data_provider->set_from_api($body)->store;
230
231                 $c->res->headers->location( $c->req->url->to_string . '/'
232                       . $usage_data_provider->erm_usage_data_provider_id );
233                 return $c->render(
234                     status  => 200,
235                     openapi => $usage_data_provider->to_api
236                 );
237             }
238         );
239     }
240     catch {
241         my $to_api_mapping = Koha::ERM::UsageDataProvider->new->to_api_mapping;
242
243         if ( blessed $_ ) {
244             if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) {
245                 return $c->render(
246                     status  => 400,
247                     openapi => {
248                             error => "Given "
249                           . $to_api_mapping->{ $_->broken_fk }
250                           . " does not exist"
251                     }
252                 );
253             }
254             elsif ( $_->isa('Koha::Exceptions::BadParameter') ) {
255                 return $c->render(
256                     status  => 400,
257                     openapi => {
258                             error => "Given "
259                           . $to_api_mapping->{ $_->parameter }
260                           . " does not exist"
261                     }
262                 );
263             }
264             elsif ( $_->isa('Koha::Exceptions::PayloadTooLarge') ) {
265                 return $c->render(
266                     status  => 413,
267                     openapi => { error => $_->error }
268                 );
269             }
270         }
271
272         $c->unhandled_exception($_);
273     };
274 }
275
276 =head3 delete
277
278 =cut
279
280 sub delete {
281     my $c = shift->openapi->valid_input or return;
282
283     my $usage_data_provider_id =
284       $c->validation->param('erm_usage_data_provider_id');
285     my $usage_data_provider =
286       Koha::ERM::UsageDataProviders->find($usage_data_provider_id);
287     unless ($usage_data_provider) {
288         return $c->render(
289             status  => 404,
290             openapi => { error => "Usage data provider not found" }
291         );
292     }
293
294     return try {
295         $usage_data_provider->delete;
296         return $c->render(
297             status  => 204,
298             openapi => q{}
299         );
300     }
301     catch {
302         $c->unhandled_exception($_);
303     };
304 }
305
306 =head3 run
307
308 =cut
309
310 sub run {
311     my $c = shift->openapi->valid_input or return;
312
313     my $udprovider = Koha::ERM::UsageDataProviders->find( $c->validation->param('erm_usage_data_provider_id') );
314
315     unless ($udprovider) {
316         return $c->render(
317             status  => 404,
318             openapi => { error => "Usage data provider not found" }
319         );
320     }
321
322     return try {
323         my $jobs = $udprovider->run;
324
325         return $c->render(
326             status  => 200,
327             openapi => { jobs => [ @{$jobs} ] }
328         );
329     }
330     catch {
331         $c->unhandled_exception($_);
332     };
333 }
334
335 =head3 test_connection
336
337 =cut
338
339 sub test_connection {
340     my $c = shift->openapi->valid_input or return;
341
342     my $udprovider = Koha::ERM::UsageDataProviders->find( $c->validation->param('erm_usage_data_provider_id') );
343
344     unless ($udprovider) {
345         return $c->render(
346             status  => 404,
347             openapi => { error => "Usage data provider not found" }
348         );
349     }
350     try {
351         my $service_active = $udprovider->test_connection;
352         return $c->render(
353             status  => 200,
354             openapi => $service_active
355         );
356     }
357     catch {
358         $c->unhandled_exception($_);
359     };
360 }
361
362 =head3 providers_report
363
364 =cut
365
366 sub providers_report {
367     my $c = shift->openapi->valid_input or return;
368
369     return try {
370
371         my $args = $c->validation->output;
372
373         my $usage_data_providers_set = Koha::ERM::UsageDataProviders->new;
374         my $usage_data_providers = $c->objects->search( $usage_data_providers_set );
375
376         my @query_params_array;
377         my $json = JSON->new;
378
379         if ( ref( $args->{q} ) eq 'ARRAY' ) {
380             foreach my $q ( @{ $args->{q} } ) {
381                 push @query_params_array, $json->decode($q)
382                     if $q; 
383             }
384         }
385
386         my $metric_types = $query_params_array[0][0]->{'erm_usage_titles.erm_usage_muses.metric_type'};
387
388         my @usage_data_provider_report_data;
389
390         for my $usage_data_provider ( @{ $usage_data_providers } ) {
391
392             # Split usage_data_providers into metric_types i.e. one table row per metric_type
393             for my $metric_type ( @$metric_types ) {
394                 my @filtered_title_data;
395
396                 for my $title ( @{ $usage_data_provider->{'erm_usage_titles'} }) {
397                     my $statistics = $title->{'erm_usage_muses'};
398                     my @filtered_statistics = grep { $metric_type eq $_->{metric_type} } @$statistics;
399
400                     my %title_hash = (
401                         usage_data_provider_id => $title->{usage_data_provider_id},
402                         title_id => $title->{title_id},
403                         title => $title->{title},
404                         erm_usage_muses => \@filtered_statistics,
405                         online_issn => $title->{online_issn},
406                         print_issn => $title->{print_issn},
407                         title_doi => $title->{title_doi},
408                         title_uri => $title->{title_uri},
409                         metric_type => $metric_type,
410                         publisher => $title->{publisher},
411                         publisher_id => $title->{publisher_id},
412                     );
413
414                     push @filtered_title_data, \%title_hash;
415                 }
416
417
418                 my %usage_data_provider_hash = (
419                     erm_usage_data_provider_id => $usage_data_provider->{erm_usage_data_provider_id},
420                     erm_usage_titles => \@filtered_title_data,
421                     aggregator => $usage_data_provider->{aggregator},
422                     api_key => $usage_data_provider->{api_key},
423                     begin_date => $usage_data_provider->{begin_date},
424                     customer_id => $usage_data_provider->{customer_id},
425                     description => $usage_data_provider->{description},
426                     end_date => $usage_data_provider->{end_date},
427                     method => $usage_data_provider->{method},
428                     name => $usage_data_provider->{name},
429                     report_release => $usage_data_provider->{report_release},
430                     report_types => $usage_data_provider->{report_types},
431                     requestor_email => $usage_data_provider->{requestor_email},
432                     requestor_id => $usage_data_provider->{requestor_id},
433                     requestor_name => $usage_data_provider->{requestor_name},
434                     service_type => $usage_data_provider->{service_type},
435                     service_url => $usage_data_provider->{service_url},
436                     metric_type => $metric_type
437                 );
438
439                 push @usage_data_provider_report_data, \%usage_data_provider_hash;
440             };
441         };
442
443         return $c->render( status => 200, openapi => \@usage_data_provider_report_data );
444     }
445     catch {
446         $c->unhandled_exception($_);
447     };
448 }
449
450 1;