Bug 33974: (follow-up) Adapt the orders endpoint
[koha.git] / Koha / REST / V1 / Acquisitions / Orders.pm
1 package Koha::REST::V1::Acquisitions::Orders;
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::Acquisition::Orders;
23
24 use Clone qw( clone );
25 use JSON;
26 use Scalar::Util qw( blessed );
27 use Try::Tiny qw( catch try );
28
29 =head1 NAME
30
31 Koha::REST::V1::Acquisitions::Orders
32
33 =head1 API
34
35 =head2 Methods
36
37 =head3 list
38
39 Controller function that handles listing Koha::Acquisition::Order objects
40
41 =cut
42
43 sub list {
44
45     my $c = shift->openapi->valid_input or return;
46
47     return try {
48
49         my $only_active = delete $c->validation->output->{only_active};
50         my $order_id    = delete $c->validation->output->{order_id};
51
52         my $orders_rs;
53
54         if ( $only_active ) {
55             $orders_rs = Koha::Acquisition::Orders->filter_by_active;
56         }
57         else {
58             $orders_rs = Koha::Acquisition::Orders->new;
59         }
60
61         $orders_rs = $orders_rs->filter_by_id_including_transfers({ ordernumber => $order_id })
62             if $order_id;
63
64         my @query_fixers;
65
66         # Look for embeds
67         my $embed = $c->stash('koha.embed');
68         if ( exists $embed->{biblio} ) { # asked to embed biblio
69             my $fixed_embed = clone($embed);
70             # Add biblioitems to prefetch
71             # FIXME remove if we merge biblio + biblioitems
72             $fixed_embed->{biblio}->{children}->{biblioitem} = {};
73             $c->stash('koha.embed', $fixed_embed);
74             push @query_fixers, (sub{ Koha::Biblios->new->api_query_fixer( $_[0], 'biblio', $_[1] ) });
75         }
76
77         return $c->render(
78             status  => 200,
79             openapi => $c->objects->search( $orders_rs, \@query_fixers ),
80         );
81     }
82     catch {
83         $c->unhandled_exception($_);
84     };
85 }
86
87 =head3 get
88
89 Controller function that handles retrieving a single Koha::Acquisition::Order object
90
91 =cut
92
93 sub get {
94     my $c = shift->openapi->valid_input or return;
95
96     my $order = Koha::Acquisition::Orders->find( $c->validation->param('order_id') );
97
98     unless ($order) {
99         return $c->render(
100             status  => 404,
101             openapi => { error => "Order not found" }
102         );
103     }
104
105     return try {
106         my $embed = $c->stash('koha.embed');
107
108         return $c->render(
109             status  => 200,
110             openapi => $order->to_api({ embed => $embed })
111         );
112     }
113     catch {
114         $c->unhandled_exception($_);
115     };
116 }
117
118 =head3 add
119
120 Controller function that handles adding a new Koha::Acquisition::Order object
121
122 =cut
123
124 sub add {
125     my $c = shift->openapi->valid_input or return;
126
127     return try {
128         my $order = Koha::Acquisition::Order->new_from_api( $c->validation->param('body') );
129         $order->store->discard_changes;
130
131         $c->res->headers->location(
132             $c->req->url->to_string . '/' . $order->ordernumber
133         );
134
135         return $c->render(
136             status  => 201,
137             openapi => $order->to_api
138         );
139     }
140     catch {
141         if ( blessed $_ and $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
142             return $c->render(
143                 status  => 409,
144                 openapi => { error => $_->error, conflict => $_->duplicate_id }
145             );
146         }
147
148         $c->unhandled_exception($_);
149     };
150 }
151
152 =head3 update
153
154 Controller function that handles updating a Koha::Acquisition::Order object
155
156 =cut
157
158 sub update {
159     my $c = shift->openapi->valid_input or return;
160
161     my $order = Koha::Acquisition::Orders->find( $c->validation->param('order_id') );
162
163     unless ($order) {
164         return $c->render(
165             status  => 404,
166             openapi => { error => "Order not found" }
167         );
168     }
169
170     return try {
171         $order->set_from_api( $c->validation->param('body') );
172         $order->store()->discard_changes;
173
174         return $c->render(
175             status  => 200,
176             openapi => $order->to_api
177         );
178     }
179     catch {
180         $c->unhandled_exception($_);
181     };
182 }
183
184 =head3 delete
185
186 Controller function that handles deleting a Koha::Patron object
187
188 =cut
189
190 sub delete {
191     my $c = shift->openapi->valid_input or return;
192
193     my $order = Koha::Acquisition::Orders->find( $c->validation->param('order_id') );
194
195     unless ($order) {
196         return $c->render(
197             status  => 404,
198             openapi => { error => 'Order not found' }
199         );
200     }
201
202     return try {
203
204         $order->delete;
205
206         return $c->render(
207             status  => 204,
208             openapi => q{}
209         );
210     }
211     catch {
212         $c->unhandled_exception($_);
213     };
214 }
215
216 =head2 Internal methods
217
218 =head3 table_name_fixer
219
220     $q = $c->table_name_fixer( $q );
221
222 The Koha::Biblio representation includes the biblioitem.* attributes. This is handy
223 for API consumers but as they are different tables, converting the queries that mention
224 biblioitem columns can be tricky. This method renames known column names as used on Koha's
225 UI.
226
227 =cut
228
229 sub table_name_fixer {
230     my ( $self, $q ) = @_;
231     $q =~ s/biblio\.(?=isbn|ean|publisher)/biblio.biblioitem./g;
232     return $q;
233 }
234
235 1;