Bug 30708: Add REST API controllers
[koha.git] / Koha / REST / V1 / Preservation / Trains.pm
1 package Koha::REST::V1::Preservation::Trains;
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::Preservation::Trains;
23 use Koha::Preservation::Train::Items;
24
25 use Scalar::Util qw( blessed );
26 use Try::Tiny;
27
28 =head1 API
29
30 =head2 Methods
31
32 =head3 list
33
34 Controller function that handles listing the items from a train
35
36 =cut
37
38 sub list {
39     my $c = shift->openapi->valid_input or return;
40
41     return try {
42         my $trains_set = Koha::Preservation::Trains->new;
43         my $trains = $c->objects->search( $trains_set );
44         return $c->render( status => 200, openapi => $trains );
45     }
46     catch {
47         $c->unhandled_exception($_);
48     };
49 }
50
51 =head3 get
52
53 Controller function that handles retrieving a single Koha::Preservation::Train object
54
55 =cut
56
57 sub get {
58     my $c = shift->openapi->valid_input or return;
59
60     return try {
61         my $train_id = $c->validation->param('train_id');
62         my $train    = $c->objects->find( Koha::Preservation::Trains->search, $train_id );
63
64         unless ($train) {
65             return $c->render(
66                 status  => 404,
67                 openapi => { error => "Train not found" }
68             );
69         }
70
71         return $c->render(
72             status  => 200,
73             openapi => $train
74         );
75     }
76     catch {
77         $c->unhandled_exception($_);
78     };
79 }
80
81 =head3 add
82
83 Controller function that handles adding a new Koha::Preservation::Train object
84
85 =cut
86
87 sub add {
88     my $c = shift->openapi->valid_input or return;
89
90     return try {
91         Koha::Database->new->schema->txn_do(
92             sub {
93
94                 my $body = $c->validation->param('body');
95
96                 my $train = Koha::Preservation::Train->new_from_api($body)->store;
97
98                 $c->res->headers->location($c->req->url->to_string . '/' . $train->train_id);
99                 return $c->render(
100                     status  => 201,
101                     openapi => $train->to_api
102                 );
103             }
104         );
105     }
106     catch {
107
108         my $to_api_mapping = Koha::Preservation::Train->new->to_api_mapping;
109
110         if ( blessed $_ ) {
111             if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
112                 return $c->render(
113                     status  => 409,
114                     openapi => { error => $_->error, conflict => $_->duplicate_id }
115                 );
116             }
117             elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) {
118                 return $c->render(
119                     status  => 400,
120                     openapi => {
121                             error => "Given "
122                             . $to_api_mapping->{ $_->broken_fk }
123                             . " does not exist"
124                     }
125                 );
126             }
127             elsif ( $_->isa('Koha::Exceptions::BadParameter') ) {
128                 return $c->render(
129                     status  => 400,
130                     openapi => {
131                             error => "Given "
132                             . $to_api_mapping->{ $_->parameter }
133                             . " does not exist"
134                     }
135                 );
136             }
137             elsif ( $_->isa('Koha::Exceptions::PayloadTooLarge') ) {
138                 return $c->render(
139                     status  => 413,
140                     openapi => { error => $_->error }
141                 );
142             }
143         }
144
145         $c->unhandled_exception($_);
146     };
147 }
148
149 =head3 update
150
151 Controller function that handles updating a Koha::Preservation::Train object
152
153 =cut
154
155 sub update {
156     my $c = shift->openapi->valid_input or return;
157
158     my $train_id = $c->validation->param('train_id');
159     my $train = Koha::Preservation::Trains->find( $train_id );
160
161     unless ($train) {
162         return $c->render(
163             status  => 404,
164             openapi => { error => "Train not found" }
165         );
166     }
167
168     return try {
169         Koha::Database->new->schema->txn_do(
170             sub {
171
172                 my $body = $c->validation->param('body');
173
174                 $train->set_from_api($body)->store;
175
176                 $c->res->headers->location($c->req->url->to_string . '/' . $train->train_id);
177                 return $c->render(
178                     status  => 200,
179                     openapi => $train->to_api
180                 );
181             }
182         );
183     }
184     catch {
185         my $to_api_mapping = Koha::Preservation::Train->new->to_api_mapping;
186
187         if ( blessed $_ ) {
188             if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) {
189                 return $c->render(
190                     status  => 400,
191                     openapi => {
192                             error => "Given "
193                             . $to_api_mapping->{ $_->broken_fk }
194                             . " does not exist"
195                     }
196                 );
197             }
198             elsif ( $_->isa('Koha::Exceptions::BadParameter') ) {
199                 return $c->render(
200                     status  => 400,
201                     openapi => {
202                             error => "Given "
203                             . $to_api_mapping->{ $_->parameter }
204                             . " does not exist"
205                     }
206                 );
207             }
208             elsif ( $_->isa('Koha::Exceptions::PayloadTooLarge') ) {
209                 return $c->render(
210                     status  => 413,
211                     openapi => { error => $_->error }
212                 );
213             }
214         }
215
216         $c->unhandled_exception($_);
217     };
218 };
219
220 =head3 delete
221
222 Controller function that handles deleting a Koha::Preservation::Train object
223
224 =cut
225
226 sub delete {
227     my $c = shift->openapi->valid_input or return;
228
229     my $train = Koha::Preservation::Trains->find( $c->validation->param('train_id') );
230     unless ($train) {
231         return $c->render(
232             status  => 404,
233             openapi => { error => "Train not found" }
234         );
235     }
236
237     return try {
238         $train->delete;
239         return $c->render(
240             status  => 204,
241             openapi => q{}
242         );
243     }
244     catch {
245         $c->unhandled_exception($_);
246     };
247 }
248
249 =head3 get_item
250
251 Controller function that handles getting an item from a train
252
253 =cut
254
255 sub get_item {
256     my $c = shift->openapi->valid_input or return;
257
258     my $train_id = $c->validation->param('train_id');
259     my $train = Koha::Preservation::Trains->find( $train_id );
260
261     unless ($train) {
262         return $c->render(
263             status  => 404,
264             openapi => { error => "Train not found" }
265         );
266     }
267
268     my $train_item_id = $c->validation->param('train_item_id');
269
270     my $train_item = $c->objects->find(Koha::Preservation::Train::Items->search, { train_item_id => $train_item_id, train_id => $train_id });
271
272     unless ($train_item) {
273         return $c->render(
274             status  => 404,
275             openapi => { error => "Item not found" }
276         );
277     }
278
279     return try {
280         Koha::Database->new->schema->txn_do(
281             sub {
282                 return $c->render( status => 200, openapi => $train_item );
283             }
284         );
285     }
286     catch {
287         $c->unhandled_exception($_);
288     };
289 }
290
291 =head3 add_item
292
293 Controller function that handles adding items in batch to a train
294
295 =cut
296
297 sub add_item {
298     my $c = shift->openapi->valid_input or return;
299
300     my $train_id = $c->validation->param('train_id');
301     my $train = Koha::Preservation::Trains->find( $train_id );
302
303     unless ($train) {
304         return $c->render(
305             status  => 404,
306             openapi => { error => "Train not found" }
307         );
308     }
309
310     my $body = $c->validation->param('body');
311     return try {
312         Koha::Database->new->schema->txn_do(
313             sub {
314                 my $attributes = delete $body->{attributes} // [];
315                 my $train_item = $train->add_item($body);
316                 $train_item->attributes($attributes);
317                 return $c->render( status => 201, openapi => $train_item );
318               }
319         );
320     }
321     catch {
322         if ( blessed $_ ) {
323             if ( $_->isa('Koha::Exceptions::Preservation::MissingSettings') ) {
324                 return $c->render(
325                     status  => 400,
326                     openapi => { error => "MissingSettings", parameter => $_->parameter }
327                 );
328             } elsif ( $_->isa('Koha::Exceptions::Preservation::ItemNotFound') ) {
329                 return $c->render(
330                     status  => 404,
331                     openapi => { error => "Item not found" }
332                 );
333             } elsif ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
334                 return $c->render(
335                     status  => 409,
336                     openapi => { error => $_->error, conflict => $_->duplicate_id }
337                 );
338             } elsif ( $_->isa('Koha::Exceptions::Preservation::ItemNotInWaitingList') ) {
339                 return $c->render(
340                     status  => 400,
341                     openapi => { error => 'Item not in waiting list' }
342                 );
343             }
344         }
345
346         $c->unhandled_exception($_);
347     };
348 }
349
350 =head3 update_item
351
352 Controller function that handles updating an item from a train
353
354 =cut
355
356 sub update_item {
357     my $c = shift->openapi->valid_input or return;
358
359     my $train_id = $c->validation->param('train_id');
360     my $train = Koha::Preservation::Trains->find( $train_id );
361
362     unless ($train) {
363         return $c->render(
364             status  => 404,
365             openapi => { error => "Train not found" }
366         );
367     }
368
369     my $train_item_id = $c->validation->param('train_item_id');
370
371     my $train_item = Koha::Preservation::Train::Items->search({ train_item_id => $train_item_id, train_id => $train_id })->single;
372
373     unless ($train_item) {
374         return $c->render(
375             status  => 404,
376             openapi => { error => "Item not found" }
377         );
378     }
379
380     return try {
381         Koha::Database->new->schema->txn_do(
382             sub {
383                 my $body       = $c->validation->param('body');
384                 my $attributes = delete $body->{attributes} // [];
385
386                 $train_item->set_from_api($body)->store;
387                 $train_item->attributes($attributes);
388                 return $c->render( status => 200, openapi => $train_item );
389               }
390         );
391     }
392     catch {
393         $c->unhandled_exception($_);
394     };
395 }
396
397
398 =head3 remove_item
399
400 Controller function that handles removing an item from a train
401
402 =cut
403
404 sub remove_item {
405     my $c = shift->openapi->valid_input or return;
406
407     my $train_id = $c->validation->param('train_id');
408     my $train = Koha::Preservation::Trains->find( $train_id );
409
410     unless ($train) {
411         return $c->render(
412             status  => 404,
413             openapi => { error => "Train not found" }
414         );
415     }
416
417     my $train_item_id = $c->validation->param('train_item_id');
418
419     my $train_item = $train->items->find($train_item_id);
420
421     unless ($train_item) {
422         return $c->render(
423             status  => 404,
424             openapi => { error => "Train item not found" }
425         );
426     }
427
428     return try {
429         $train_item->delete;
430
431         return $c->render(
432             status  => 204,
433             openapi => q{}
434         );
435     }
436     catch {
437         $c->unhandled_exception($_);
438     };
439 }
440
441 1;