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