Bug 21756: Replace manualinvoice with add_debit in tests
[koha.git] / t / db_dependent / api / v1 / patrons_accounts.t
1 #!/usr/bin/perl
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 Test::More tests => 2;
21
22 use Test::Mojo;
23 use Test::Warn;
24
25 use t::lib::TestBuilder;
26 use t::lib::Mocks;
27
28 use C4::Auth;
29 use Koha::Account::Line;
30
31 my $schema  = Koha::Database->new->schema;
32 my $builder = t::lib::TestBuilder->new;
33
34 # FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
35 # this affects the other REST api tests
36 t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
37
38 my $remote_address = '127.0.0.1';
39 my $t              = Test::Mojo->new('Koha::REST::V1');
40
41 subtest 'get_balance() tests' => sub {
42
43     plan tests => 12;
44
45     $schema->storage->txn_begin;
46
47     my ( $patron, $session_id ) = create_user_and_session({ authorized => 0 });
48     my $library   = $builder->build_object({ class => 'Koha::Libraries' });
49     my $patron_id = $patron->id;
50     my $account   = $patron->account;
51
52     my $tx = $t->ua->build_tx(GET => "/api/v1/patrons/$patron_id/account");
53     $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
54     $tx->req->env({ REMOTE_ADDR => '127.0.0.1' });
55     $t->request_ok($tx)->status_is(200)->json_is(
56         {   balance             => 0.00,
57             outstanding_debits  => { total => 0, lines => [] },
58             outstanding_credits => { total => 0, lines => [] }
59         }
60     );
61
62     my $account_line_1 = Koha::Account::Line->new(
63         {
64             borrowernumber    => $patron->borrowernumber,
65             date              => \'NOW()',
66             amount            => 50,
67             description       => "A description",
68             accounttype       => "N", # New card
69             amountoutstanding => 50,
70             manager_id        => $patron->borrowernumber,
71             branchcode        => $library->id
72         }
73     )->store();
74     $account_line_1->discard_changes;
75
76     my $account_line_2 = Koha::Account::Line->new(
77         {
78             borrowernumber    => $patron->borrowernumber,
79             date              => \'NOW()',
80             amount            => 50.01,
81             description       => "A description",
82             accounttype       => "N", # New card
83             amountoutstanding => 50.01,
84             manager_id        => $patron->borrowernumber,
85             branchcode        => $library->id
86         }
87     )->store();
88     $account_line_2->discard_changes;
89
90     $tx = $t->ua->build_tx( GET => "/api/v1/patrons/$patron_id/account" );
91     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
92     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
93     $t->request_ok($tx)->status_is(200)->json_is(
94         {   balance            => 100.01,
95             outstanding_debits => {
96                 total => 100.01,
97                 lines => [
98                     Koha::REST::V1::Patrons::Account::_to_api( $account_line_1->TO_JSON ),
99                     Koha::REST::V1::Patrons::Account::_to_api( $account_line_2->TO_JSON )
100                 ]
101             },
102             outstanding_credits => {
103                 total => 0,
104                 lines => []
105             }
106         }
107     );
108
109     $account->pay(
110         {   amount       => 100.01,
111             note         => 'He paid!',
112             description  => 'Finally!',
113             library_id   => $patron->branchcode,
114             account_type => 'Pay',
115             offset_type  => 'Payment'
116         }
117     );
118
119     $tx = $t->ua->build_tx( GET => "/api/v1/patrons/$patron_id/account" );
120     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
121     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
122     $t->request_ok($tx)->status_is(200)->json_is(
123         {   balance             => 0,
124             outstanding_debits  => { total => 0, lines => [] },
125             outstanding_credits => { total => 0, lines => [] }
126         }
127     );
128
129     # add a credit
130     my $credit_line = $account->add_credit(
131         { amount => 10, user_id => $patron->id, library_id => $library->id } );
132     # re-read from the DB
133     $credit_line->discard_changes;
134     $tx = $t->ua->build_tx( GET => "/api/v1/patrons/$patron_id/account" );
135     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
136     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
137     $t->request_ok($tx)->status_is(200)->json_is(
138         {   balance            => -10,
139             outstanding_debits => {
140                 total => 0,
141                 lines => []
142             },
143             outstanding_credits => {
144                 total => -10,
145                 lines => [ Koha::REST::V1::Patrons::Account::_to_api( $credit_line->TO_JSON ) ]
146             }
147         }
148     );
149
150     $schema->storage->txn_rollback;
151 };
152
153 subtest 'add_credit() tests' => sub {
154
155     plan tests => 18;
156
157     $schema->storage->txn_begin;
158
159     my ( $patron, $session_id ) = create_user_and_session( { authorized => 1 } );
160     my $library   = $builder->build_object({ class => 'Koha::Libraries' });
161     my $patron_id = $patron->id;
162     my $account   = $patron->account;
163
164     is( $account->outstanding_debits->count,  0, 'No outstanding debits for patron' );
165     is( $account->outstanding_credits->count, 0, 'No outstanding credits for patron' );
166
167     my $credit = { amount => 100 };
168
169     my $tx = $t->ua->build_tx(
170         POST => "/api/v1/patrons/$patron_id/account/credits" => json => $credit );
171     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
172     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
173     $t->request_ok($tx)->status_is(200)->json_has('/account_line_id');
174
175     my $outstanding_credits = $account->outstanding_credits;
176     is( $outstanding_credits->count,             1 );
177     is( $outstanding_credits->total_outstanding, -100 );
178
179     my $debit_1 = Koha::Account::Line->new(
180         {   borrowernumber    => $patron->borrowernumber,
181             date              => \'NOW()',
182             amount            => 10,
183             description       => "A description",
184             accounttype       => "N",                       # New card
185             amountoutstanding => 10,
186             manager_id        => $patron->borrowernumber,
187         }
188     )->store();
189     my $debit_2 = Koha::Account::Line->new(
190         {   borrowernumber    => $patron->borrowernumber,
191             date              => \'NOW()',
192             amount            => 15,
193             description       => "A description",
194             accounttype       => "N",                       # New card
195             amountoutstanding => 15,
196             manager_id        => $patron->borrowernumber,
197         }
198     )->store();
199
200     is( $account->outstanding_debits->total_outstanding, 25 );
201     $credit->{library_id} = $library->id;
202     $tx = $t->ua->build_tx(
203         POST => "/api/v1/patrons/$patron_id/account/credits" => json => $credit );
204     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
205     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
206     $t->request_ok($tx)->status_is(200)->json_has('/account_line_id');
207
208     my $account_line_id = $tx->res->json->{account_line_id};
209     is( Koha::Account::Lines->find($account_line_id)->branchcode,
210         $library->id, 'Library id is sored correctly' );
211
212     is( $account->outstanding_debits->total_outstanding,
213         0, "Debits have been cancelled automatically" );
214
215     my $debit_3 = Koha::Account::Line->new(
216         {   borrowernumber    => $patron->borrowernumber,
217             date              => \'NOW()',
218             amount            => 100,
219             description       => "A description",
220             accounttype       => "N",                       # New card
221             amountoutstanding => 100,
222             manager_id        => $patron->borrowernumber,
223         }
224     )->store();
225
226     $credit = {
227         amount            => 35,
228         account_lines_ids => [ $debit_1->id, $debit_2->id, $debit_3->id ]
229     };
230
231     $tx = $t->ua->build_tx(
232         POST => "/api/v1/patrons/$patron_id/account/credits" => json => $credit );
233     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
234     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
235     $t->request_ok($tx)->status_is(200)->json_has('/account_line_id');
236
237     my $outstanding_debits = $account->outstanding_debits;
238     is( $outstanding_debits->total_outstanding, 65 );
239     is( $outstanding_debits->count,             1 );
240
241     $schema->storage->txn_rollback;
242 };
243
244 sub create_user_and_session {
245
246     my $args  = shift;
247     my $flags = ( $args->{authorized} ) ? 2**10 : 0;
248
249     my $patron = $builder->build_object(
250         {
251             class => 'Koha::Patrons',
252             value  => {
253                 flags         => $flags
254             }
255         }
256     );
257
258     # Create a session for the authorized user
259     my $session = C4::Auth::get_session('');
260     $session->param( 'number',   $patron->id );
261     $session->param( 'id',       $patron->userid );
262     $session->param( 'ip',       '127.0.0.1' );
263     $session->param( 'lasttime', time() );
264     $session->flush;
265
266     return ( $patron, $session->id );
267 }