Bug 21683: Remove accountlines.accountno
[koha.git] / Koha / REST / V1 / Patrons / Account.pm
blobb0d623b719f2d59d4975a2295d23217eccf00846
1 package Koha::REST::V1::Patrons::Account;
3 # This file is part of Koha.
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.
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.
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.
18 use Modern::Perl;
20 use Mojo::Base 'Mojolicious::Controller';
22 use Koha::Patrons;
24 use Scalar::Util qw(blessed);
25 use Try::Tiny;
27 =head1 NAME
29 Koha::REST::V1::Patrons::Account
31 =head1 API
33 =head2 Methods
35 =head3 get
37 Controller function that handles retrieving a patron's account balance
39 =cut
41 sub get {
42 my $c = shift->openapi->valid_input or return;
44 my $patron_id = $c->validation->param('patron_id');
45 my $patron = Koha::Patrons->find($patron_id);
47 unless ($patron) {
48 return $c->render( status => 404, openapi => { error => "Patron not found." } );
51 my $account = $patron->account;
52 my $balance;
54 $balance->{balance} = $account->balance;
56 # get outstanding debits and credits
57 my $debits = $account->outstanding_debits;
58 my $credits = $account->outstanding_credits;
60 my @debit_lines = map { _to_api( $_->TO_JSON ) } @{ $debits->as_list };
61 $balance->{outstanding_debits} = {
62 total => $debits->total_outstanding,
63 lines => \@debit_lines
66 my @credit_lines = map { _to_api( $_->TO_JSON ) } @{ $credits->as_list };
67 $balance->{outstanding_credits} = {
68 total => $credits->total_outstanding,
69 lines => \@credit_lines
72 return $c->render( status => 200, openapi => $balance );
75 =head3 add_credit
77 Controller function that handles adding a credit to a patron's account
79 =cut
81 sub add_credit {
82 my $c = shift->openapi->valid_input or return;
84 my $patron_id = $c->validation->param('patron_id');
85 my $patron = Koha::Patrons->find($patron_id);
86 my $user = $c->stash('koha.user');
89 unless ($patron) {
90 return $c->render( status => 404, openapi => { error => "Patron not found." } );
93 my $account = $patron->account;
94 my $body = $c->validation->param('body');
96 return try {
97 my $credit_type = $body->{credit_type} || 'payment'; # default to 'payment'
98 my $amount = $body->{amount}; # mandatory, validated by openapi
100 unless ( $amount > 0 ) { # until we support newer JSON::Validator and thus minimumExclusive
101 Koha::Exceptions::BadParameter->throw( { parameter => 'amount' } );
104 # read the rest of the params
105 my $payment_type = $body->{payment_type};
106 my $description = $body->{description};
107 my $note = $body->{note};
108 my $library_id = $body->{library_id};
110 my $credit = $account->add_credit(
111 { amount => $amount,
112 credit_type => $credit_type,
113 payment_type => $payment_type,
114 description => $description,
115 note => $note,
116 user_id => $user->id,
117 library_id => $library_id
120 $credit->discard_changes;
122 my $date = $body->{date};
123 $credit->date( $date )->store
124 if $date;
126 my $debits_ids = $body->{account_lines_ids};
127 my $debits;
128 $debits = Koha::Account::Lines->search({ accountlines_id => { -in => $debits_ids } })
129 if $debits_ids;
131 my $outstanding_credit = $credit->amountoutstanding;
132 if ($debits) {
133 # pay them!
134 $outstanding_credit = $credit->apply({ debits => $debits, offset_type => 'payment' });
137 if ($outstanding_credit) {
138 my $outstanding_debits = $account->outstanding_debits;
139 $credit->apply({ debits => $outstanding_debits, offset_type => 'payment' });
142 return $c->render( status => 200, openapi => { account_line_id => $credit->id } );
144 catch {
145 if ( blessed $_ && $_->can('rethrow') ) {
146 return $c->render(
147 status => 400,
148 openapi => { error => "$_" }
151 else {
152 # Exception, rely on the stringified exception
153 return $c->render(
154 status => 500,
155 openapi => { error => "Something went wrong, check the logs" }
162 =head3 _to_api
164 Helper function that maps unblessed Koha::Account::Line objects
165 into REST API attribute names.
167 =cut
169 sub _to_api {
170 my $account_line = shift;
172 # Rename attributes
173 foreach my $column ( keys %{ $Koha::REST::V1::Patrons::Account::to_api_mapping } ) {
174 my $mapped_column = $Koha::REST::V1::Patrons::Account::to_api_mapping->{$column};
175 if ( exists $account_line->{ $column }
176 && defined $mapped_column )
178 # key != undef
179 $account_line->{ $mapped_column } = delete $account_line->{ $column };
181 elsif ( exists $account_line->{ $column }
182 && !defined $mapped_column )
184 # key == undef
185 delete $account_line->{ $column };
189 return $account_line;
192 =head3 _to_model
194 Helper function that maps REST API objects into Koha::Account::Line
195 attribute names.
197 =cut
199 sub _to_model {
200 my $account_line = shift;
202 foreach my $attribute ( keys %{ $Koha::REST::V1::Patrons::Account::to_model_mapping } ) {
203 my $mapped_attribute = $Koha::REST::V1::Patrons::Account::to_model_mapping->{$attribute};
204 if ( exists $account_line->{ $attribute }
205 && defined $mapped_attribute )
207 # key => !undef
208 $account_line->{ $mapped_attribute } = delete $account_line->{ $attribute };
210 elsif ( exists $account_line->{ $attribute }
211 && !defined $mapped_attribute )
213 # key => undef / to be deleted
214 delete $account_line->{ $attribute };
218 return $account_line;
221 =head2 Global variables
223 =head3 $to_api_mapping
225 =cut
227 our $to_api_mapping = {
228 accountlines_id => 'account_line_id',
229 accounttype => 'account_type',
230 amountoutstanding => 'amount_outstanding',
231 borrowernumber => 'patron_id',
232 branchcode => 'library_id',
233 issue_id => 'checkout_id',
234 itemnumber => 'item_id',
235 manager_id => 'user_id',
236 note => 'internal_note',
239 =head3 $to_model_mapping
241 =cut
243 our $to_model_mapping = {
244 account_line_id => 'accountlines_id',
245 account_type => 'accounttype',
246 amount_outstanding => 'amountoutstanding',
247 checkout_id => 'issue_id',
248 internal_note => 'note',
249 item_id => 'itemnumber',
250 library_id => 'branchcode',
251 patron_id => 'borrowernumber',
252 user_id => 'manager_id'