Bug 23049: Update existing code to use debit_type
[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 => 1 });
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             debit_type_code   => "N", # New card
69             amountoutstanding => 50,
70             manager_id        => $patron->borrowernumber,
71             branchcode        => $library->id,
72             interface         => 'test',
73         }
74     )->store();
75     $account_line_1->discard_changes;
76
77     my $account_line_2 = Koha::Account::Line->new(
78         {
79             borrowernumber    => $patron->borrowernumber,
80             date              => \'NOW()',
81             amount            => 50.01,
82             description       => "A description",
83             debit_type_code   => "N", # New card
84             amountoutstanding => 50.01,
85             manager_id        => $patron->borrowernumber,
86             branchcode        => $library->id,
87             interface         => 'test',
88         }
89     )->store();
90     $account_line_2->discard_changes;
91
92     $tx = $t->ua->build_tx( GET => "/api/v1/patrons/$patron_id/account" );
93     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
94     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
95     $t->request_ok($tx)->status_is(200)->json_is(
96         {   balance            => 100.01,
97             outstanding_debits => {
98                 total => 100.01,
99                 lines => [
100                     Koha::REST::V1::Patrons::Account::_to_api( $account_line_1->TO_JSON ),
101                     Koha::REST::V1::Patrons::Account::_to_api( $account_line_2->TO_JSON )
102                 ]
103             },
104             outstanding_credits => {
105                 total => 0,
106                 lines => []
107             }
108         }
109     );
110
111     $account->pay(
112         {   amount       => 100.01,
113             note         => 'He paid!',
114             description  => 'Finally!',
115             library_id   => $patron->branchcode,
116             account_type => 'Pay',
117             offset_type  => 'Payment'
118         }
119     );
120
121     $tx = $t->ua->build_tx( GET => "/api/v1/patrons/$patron_id/account" );
122     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
123     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
124     $t->request_ok($tx)->status_is(200)->json_is(
125         {   balance             => 0,
126             outstanding_debits  => { total => 0, lines => [] },
127             outstanding_credits => { total => 0, lines => [] }
128         }
129     );
130
131     # add a credit
132     my $credit_line = $account->add_credit(
133         { amount => 10, user_id => $patron->id, library_id => $library->id, interface => 'test' } );
134     # re-read from the DB
135     $credit_line->discard_changes;
136     $tx = $t->ua->build_tx( GET => "/api/v1/patrons/$patron_id/account" );
137     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
138     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
139     $t->request_ok($tx)->status_is(200)->json_is(
140         {   balance            => -10,
141             outstanding_debits => {
142                 total => 0,
143                 lines => []
144             },
145             outstanding_credits => {
146                 total => -10,
147                 lines => [ Koha::REST::V1::Patrons::Account::_to_api( $credit_line->TO_JSON ) ]
148             }
149         }
150     );
151
152     $schema->storage->txn_rollback;
153 };
154
155 subtest 'add_credit() tests' => sub {
156
157     plan tests => 18;
158
159     $schema->storage->txn_begin;
160
161     my ( $patron, $session_id ) = create_user_and_session( { authorized => 1 } );
162     my $library   = $builder->build_object({ class => 'Koha::Libraries' });
163     my $patron_id = $patron->id;
164     my $account   = $patron->account;
165
166     is( $account->outstanding_debits->count,  0, 'No outstanding debits for patron' );
167     is( $account->outstanding_credits->count, 0, 'No outstanding credits for patron' );
168
169     my $credit = { amount => 100 };
170
171     my $tx = $t->ua->build_tx(
172         POST => "/api/v1/patrons/$patron_id/account/credits" => json => $credit );
173     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
174     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
175     $t->request_ok($tx)->status_is(200)->json_has('/account_line_id');
176
177     my $outstanding_credits = $account->outstanding_credits;
178     is( $outstanding_credits->count,             1 );
179     is( $outstanding_credits->total_outstanding, -100 );
180
181     my $debit_1 = Koha::Account::Line->new(
182         {   borrowernumber    => $patron->borrowernumber,
183             date              => \'NOW()',
184             amount            => 10,
185             description       => "A description",
186             debit_type_code   => "N",                       # New card
187             amountoutstanding => 10,
188             manager_id        => $patron->borrowernumber,
189             interface         => 'test',
190         }
191     )->store();
192     my $debit_2 = Koha::Account::Line->new(
193         {   borrowernumber    => $patron->borrowernumber,
194             date              => \'NOW()',
195             amount            => 15,
196             description       => "A description",
197             debit_type_code   => "N",                       # New card
198             amountoutstanding => 15,
199             manager_id        => $patron->borrowernumber,
200             interface         => 'test',
201         }
202     )->store();
203
204     is( $account->outstanding_debits->total_outstanding, 25 );
205     $credit->{library_id} = $library->id;
206     $tx = $t->ua->build_tx(
207         POST => "/api/v1/patrons/$patron_id/account/credits" => json => $credit );
208     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
209     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
210     $t->request_ok($tx)->status_is(200)->json_has('/account_line_id');
211
212     my $account_line_id = $tx->res->json->{account_line_id};
213     is( Koha::Account::Lines->find($account_line_id)->branchcode,
214         $library->id, 'Library id is sored correctly' );
215
216     is( $account->outstanding_debits->total_outstanding,
217         0, "Debits have been cancelled automatically" );
218
219     my $debit_3 = Koha::Account::Line->new(
220         {   borrowernumber    => $patron->borrowernumber,
221             date              => \'NOW()',
222             amount            => 100,
223             description       => "A description",
224             debit_type_code   => "N",                       # New card
225             amountoutstanding => 100,
226             manager_id        => $patron->borrowernumber,
227             interface         => 'test',
228         }
229     )->store();
230
231     $credit = {
232         amount            => 35,
233         account_lines_ids => [ $debit_1->id, $debit_2->id, $debit_3->id ]
234     };
235
236     $tx = $t->ua->build_tx(
237         POST => "/api/v1/patrons/$patron_id/account/credits" => json => $credit );
238     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
239     $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
240     $t->request_ok($tx)->status_is(200)->json_has('/account_line_id');
241
242     my $outstanding_debits = $account->outstanding_debits;
243     is( $outstanding_debits->total_outstanding, 65 );
244     is( $outstanding_debits->count,             1 );
245
246     $schema->storage->txn_rollback;
247 };
248
249 sub create_user_and_session {
250
251     my $args  = shift;
252     my $flags = ( $args->{authorized} ) ? 1 : 0;
253
254     my $patron = $builder->build_object(
255         {
256             class => 'Koha::Patrons',
257             value  => {
258                 flags         => $flags
259             }
260         }
261     );
262
263     # Create a session for the authorized user
264     my $session = C4::Auth::get_session('');
265     $session->param( 'number',   $patron->id );
266     $session->param( 'id',       $patron->userid );
267     $session->param( 'ip',       '127.0.0.1' );
268     $session->param( 'lasttime', time() );
269     $session->flush;
270
271     return ( $patron, $session->id );
272 }