Bug 36329: Make POST /transfer_limits/batch honor BranchTransferLimitsType
[koha.git] / Koha / REST / V1 / TransferLimits.pm
1 package Koha::REST::V1::TransferLimits;
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 use Koha::Item::Transfer::Limits;
22 use Koha::Libraries;
23
24 use Koha::Exceptions::TransferLimit;
25
26 use Scalar::Util qw( blessed );
27
28 use Try::Tiny qw( catch try );
29
30 =head1 NAME
31
32 Koha::REST::V1::TransferLimits - Koha REST API for handling libraries (V1)
33
34 =head1 API
35
36 =head2 Methods
37
38 =cut
39
40 =head3 list
41
42 Controller function that handles listing Koha::Item::Transfer::Limits objects
43
44 =cut
45
46 sub list {
47     my $c = shift->openapi->valid_input or return;
48
49     return try {
50         my $limits = $c->objects->search( Koha::Item::Transfer::Limits->new );
51         return $c->render( status => 200, openapi => $limits );
52     }
53     catch {
54         $c->unhandled_exception( $_ );
55     };
56 }
57
58 =head3 add
59
60 Controller function that handles adding a new transfer limit
61
62 =cut
63
64 sub add {
65     my $c = shift->openapi->valid_input or return;
66
67     return try {
68         my $params = $c->req->json;
69         my $transfer_limit = Koha::Item::Transfer::Limit->new_from_api( $params );
70
71         if ( Koha::Item::Transfer::Limits->search( $transfer_limit->attributes_from_api($params) )->count == 0 ) {
72             $transfer_limit->store;
73         } else {
74             Koha::Exceptions::TransferLimit::Duplicate->throw();
75         }
76
77         return $c->render(
78             status  => 201,
79             openapi => $transfer_limit->to_api
80         );
81     }
82     catch {
83         if ( blessed $_ && $_->isa('Koha::Exceptions::TransferLimit::Duplicate') ) {
84             return $c->render(
85                 status  => 409,
86                 openapi => { error => "$_" }
87             );
88         }
89
90         $c->unhandled_exception($_);
91     };
92 }
93
94 =head3 delete
95
96 Controller function that handles deleting a transfer limit
97
98 =cut
99
100 sub delete {
101
102     my $c = shift->openapi->valid_input or return;
103
104     my $transfer_limit = Koha::Item::Transfer::Limits->find( $c->param( 'limit_id' ) );
105
106     if ( not defined $transfer_limit ) {
107         return $c->render( status => 404, openapi => { error => "Transfer limit not found" } );
108     }
109
110     return try {
111         $transfer_limit->delete;
112         return $c->render( status => 204, openapi => '');
113     }
114     catch {
115         $c->unhandled_exception($_);
116     };
117 }
118
119 =head3 batch_add
120
121 Controller function that handles adding a new transfer limit
122
123 =cut
124
125 sub batch_add {
126     my $c = shift->openapi->valid_input or return;
127
128     return try {
129         my $params = $c->req->json;
130
131         if ( $params->{item_type} && $params->{collection_code} ) {
132             return $c->render(
133                 status  => 400,
134                 openapi => {
135                     error => "You can only pass 'item_type' or 'collection_code' at a time",
136                 }
137             );
138         }
139
140         if (   ( C4::Context->preference("BranchTransferLimitsType") eq 'itemtype' && $params->{collection_code} )
141             || ( C4::Context->preference("BranchTransferLimitsType") eq 'ccode' && $params->{item_type} ) )
142         {
143             return $c->render(
144                 status  => 409,
145                 openapi => {
146                     error => $params->{collection_code}
147                     ? "You passed 'collection_code' but configuration expects 'item_type'"
148                     : "You passed 'item_type' but configuration expects 'collection_code'"
149                 }
150             );
151         }
152
153         my ( @from_branches, @to_branches );
154         if ( $params->{from_library_id} ) {
155             @from_branches = ( $params->{from_library_id} );
156         }
157         if ( $params->{to_library_id} ) {
158             @to_branches = ( $params->{to_library_id} );
159         }
160         unless ( $params->{from_library_id} && $params->{to_library_id} ) {
161             my @library_ids = Koha::Libraries->search->get_column('branchcode');
162             @from_branches = @library_ids unless $params->{from_library_id};
163             @to_branches   = @library_ids unless $params->{to_library_id};
164         }
165
166         my $dbic_params = Koha::Item::Transfer::Limits->new->attributes_from_api($params);
167         my %existing_limits =
168             map { sprintf( "%s:%s:%s:%s", $_->fromBranch, $_->toBranch, $_->itemtype // q{}, $_->ccode // q{} ) => 1 }
169             Koha::Item::Transfer::Limits->search($dbic_params)->as_list;
170
171         my @results;
172         foreach my $from (@from_branches) {
173             foreach my $to (@to_branches) {
174                 my $limit_params = {%$params};
175
176                 $limit_params->{from_library_id} = $from;
177                 $limit_params->{to_library_id}   = $to;
178
179                 next if $to eq $from;
180
181                 my $key = sprintf(
182                     "%s:%s:%s:%s", $limit_params->{from_branch_id} || q{},
183                     $limit_params->{to_branch_id} || q{}, $limit_params->{item_type} || q{},
184                     $limit_params->{collection_code} || q{}
185                 );
186                 next if exists $existing_limits{$key};
187
188                 my $transfer_limit = Koha::Item::Transfer::Limit->new_from_api($limit_params);
189                 $transfer_limit->store;
190                 push( @results, $transfer_limit->to_api() );
191             }
192         }
193
194         return $c->render(
195             status  => 201,
196             openapi => \@results
197         );
198     } catch {
199         $c->unhandled_exception($_);
200     };
201 }
202
203 =head3 batch_delete
204
205 Controller function that handles batch deleting transfer limits
206
207 =cut
208
209 sub batch_delete {
210
211     my $c = shift->openapi->valid_input or return;
212
213     return try {
214         my $params = $c->req->json;
215         my $transfer_limit = Koha::Item::Transfer::Limit->new_from_api( $params );
216         my $search_params = $transfer_limit->unblessed;
217
218         Koha::Item::Transfer::Limits->search($search_params)->delete;
219
220         return $c->render( status => 204, openapi => q{} );
221     }
222     catch {
223         $c->unhandled_exception($_);
224     };
225 }
226
227 1;