Bug 16330: Add routes to add, update and delete patrons
[koha.git] / Koha / REST / V1 / Patron.pm
1 package Koha::REST::V1::Patron;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 3 of the License, or (at your option) any later
8 # version.
9 #
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 use Modern::Perl;
19
20 use Mojo::Base 'Mojolicious::Controller';
21
22 use C4::Members qw( AddMember ModMember );
23 use Koha::AuthUtils qw(hash_password);
24 use Koha::Patrons;
25 use Koha::Patron::Categories;
26 use Koha::Patron::Modifications;
27 use Koha::Libraries;
28
29 use Scalar::Util qw(blessed);
30 use Try::Tiny;
31
32 sub list {
33     my $c = shift->openapi->valid_input or return;
34
35
36     my $args   = $c->req->params->to_hash;
37     my $filter = {};
38     for my $filter_param ( keys %$args ) {
39         $filter->{$filter_param} = { LIKE => $args->{$filter_param} . "%" };
40     }
41
42     return try {
43         my $patrons = Koha::Patrons->search_limited($filter);
44         return $c->render(status => 200, openapi => $patrons);
45     }
46     catch {
47         if ( $_->isa('DBIx::Class::Exception') ) {
48             return $c->render( status => 500, openapi => { error => $_->{msg} } );
49         }
50         else {
51             return $c->render( status => 500, openapi => { error => "Something went wrong, check the logs." } );
52         }
53     };
54 }
55
56 sub get {
57     my $c = shift->openapi->valid_input or return;
58
59     my $borrowernumber = $c->validation->param('borrowernumber');
60     my $patron = Koha::Patrons->find($borrowernumber);
61
62     unless ($patron) {
63         return $c->render(status => 404, openapi => { error => "Patron not found." });
64     }
65
66     return $c->render(status => 200, openapi => $patron);
67 }
68
69 sub add {
70     my ($c, $args, $cb) = @_;
71
72     return try {
73         my $body = $c->req->json;
74
75         Koha::Patron->new($body)->_validate;
76         # TODO: Use AddMember until it has been moved to Koha-namespace
77         my $borrowernumber = AddMember(%$body);
78         my $patron = Koha::Patrons->find($borrowernumber);
79
80         return $c->$cb($patron, 201);
81     }
82     catch {
83         unless (blessed $_ && $_->can('rethrow')) {
84             return $c->$cb({ error =>
85                 "Something went wrong, check Koha logs for details."}, 500);
86         }
87         if ($_->isa('Koha::Exceptions::Patron::DuplicateObject')) {
88             return $c->$cb({ error => $_->error, conflict => $_->conflict }, 409);
89         }
90         elsif ($_->isa('Koha::Exceptions::Library::BranchcodeNotFound')) {
91             return $c->$cb({ error => "Given branchcode does not exist" }, 400);
92         }
93         elsif ($_->isa('Koha::Exceptions::Category::CategorycodeNotFound')) {
94             return $c->$cb({ error => "Given categorycode does not exist"}, 400);
95         }
96         else {
97             return $c->$cb({ error =>
98                 "Something went wrong, check Koha logs for details."}, 500);
99         }
100     };
101 }
102
103 sub edit {
104     my ($c, $args, $cb) = @_;
105
106     my $patron;
107     return try {
108         my $user = $c->stash('koha.user');
109         $patron = Koha::Patrons->find($args->{borrowernumber});
110         my $body = $c->req->json;
111
112         $body->{borrowernumber} = $args->{borrowernumber};
113
114         if (!C4::Auth::haspermission($user->userid, { borrowers => 1 }) &&
115             $user->borrowernumber == $patron->borrowernumber){
116             if (C4::Context->preference('OPACPatronDetails')) {
117                 $body = _delete_unmodifiable_parameters($body);
118                 die unless $patron->set($body)->_validate;
119                 my $m = Koha::Patron::Modification->new($body)->store();
120                 return $c->$cb({}, 202);
121             } else {
122                 return $c->$cb({ error => "You need a permission to change"
123                                 ." Your personal details"}, 403);
124             }
125         }
126         else {
127             delete $body->{borrowernumber};
128             die unless $patron->set($body)->_validate;
129             # TODO: Use ModMember until it has been moved to Koha-namespace
130             $body->{borrowernumber} = $args->{borrowernumber};
131             die unless ModMember(%$body);
132             return $c->$cb($patron, 200);
133         }
134     }
135     catch {
136         unless ($patron) {
137             return $c->$cb({error => "Patron not found"}, 404);
138         }
139         unless (blessed $_ && $_->can('rethrow')) {
140             return $c->$cb({ error =>
141                 "Something went wrong, check Koha logs for details."}, 500);
142         }
143         if ($_->isa('Koha::Exceptions::Patron::DuplicateObject')) {
144             return $c->$cb({ error => $_->error, conflict => $_->conflict }, 409);
145         }
146         elsif ($_->isa('Koha::Exceptions::Library::BranchcodeNotFound')) {
147             return $c->$cb({ error => "Given branchcode does not exist" }, 400);
148         }
149         elsif ($_->isa('Koha::Exceptions::Category::CategorycodeNotFound')) {
150             return $c->$cb({ error => "Given categorycode does not exist"}, 400);
151         }
152         elsif ($_->isa('Koha::Exceptions::MissingParameter')) {
153             return $c->$cb({error => "Missing mandatory parameter(s)",
154                             parameters => $_->parameter }, 400);
155         }
156         elsif ($_->isa('Koha::Exceptions::BadParameter')) {
157             return $c->$cb({error => "Invalid parameter(s)",
158                             parameters => $_->parameter }, 400);
159         }
160         elsif ($_->isa('Koha::Exceptions::NoChanges')) {
161             return $c->$cb({error => "No changes have been made"}, 204);
162         }
163         else {
164             return $c->$cb({ error =>
165                 "Something went wrong, check Koha logs for details."}, 500);
166         }
167     };
168 }
169
170 sub delete {
171     my ($c, $args, $cb) = @_;
172
173     my $patron;
174
175     return try {
176         $patron = Koha::Patrons->find($args->{borrowernumber});
177         # check if loans, reservations, debarrment, etc. before deletion!
178         my $res = $patron->delete;
179
180         return $c->$cb({}, 200);
181     }
182     catch {
183         unless ($patron) {
184             return $c->$cb({error => "Patron not found"}, 404);
185         }
186         else {
187             return $c->$cb({ error =>
188                 "Something went wrong, check Koha logs for details."}, 500);
189         }
190     };
191 }
192
193 sub _delete_unmodifiable_parameters {
194     my ($body) = @_;
195
196     my %columns = map { $_ => 1 } Koha::Patron::Modifications->columns;
197     foreach my $param (keys %$body) {
198         unless (exists $columns{$param}) {
199             delete $body->{$param};
200         }
201     }
202     return $body;
203 }
204
205 1;