Bug 15081: (followup) Make test files using TestBuilder handle their transactions
[koha.git] / t / db_dependent / Accounts.t
1 #!/usr/bin/perl
2
3 # Copyright 2015 BibLibre
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 3 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, see <http://www.gnu.org/licenses>.
18
19 use Modern::Perl;
20
21 use Test::More tests => 8;
22 use Test::MockModule;
23 use Test::Warn;
24
25 use t::lib::TestBuilder;
26
27 BEGIN {
28     use_ok('C4::Accounts');
29     use_ok('Koha::Object');
30     use_ok('Koha::Borrower');
31     use_ok('Data::Dumper');
32 }
33
34 can_ok( 'C4::Accounts',
35     qw( recordpayment
36         makepayment
37         getnextacctno
38         chargelostitem
39         manualinvoice
40         getcharges
41         ModNote
42         getcredits
43         getrefunds
44         ReversePayment
45         recordpayment_selectaccts
46         makepartialpayment
47         WriteOffFee )
48 );
49
50 my $schema  = Koha::Database->new->schema;
51 $schema->storage->txn_begin;
52
53 my $builder = t::lib::TestBuilder->new();
54
55 my $dbh = C4::Context->dbh;
56 $dbh->{RaiseError}=1;
57 $dbh->{AutoCommit}=0;
58 $dbh->do(q|DELETE FROM accountlines|);
59 $dbh->do(q|DELETE FROM issues|);
60 $dbh->do(q|DELETE FROM borrowers|);
61
62 my $branchcode = 'CPL';
63 my $borrower_number;
64
65 my $context = new Test::MockModule('C4::Context');
66 $context->mock( 'userenv', sub {
67     return {
68         flags  => 1,
69         id     => 'my_userid',
70         branch => $branchcode,
71     };
72 });
73
74
75 subtest "recordpayment() tests" => sub {
76
77     plan tests => 10;
78
79     # Create a borrower
80     my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
81     my $branchcode   = $builder->build({ source => 'Branch' })->{ branchcode };
82
83     my $borrower = Koha::Borrower->new( {
84         cardnumber => '1234567890',
85         surname => 'McFly',
86         firstname => 'Marty',
87     } );
88     $borrower->categorycode( $categorycode );
89     $borrower->branchcode( $branchcode );
90     $borrower->store;
91
92     my $sth = $dbh->prepare(
93         "INSERT INTO accountlines (
94             borrowernumber,
95             amountoutstanding )
96         VALUES ( ?, ? )"
97     );
98     $sth->execute($borrower->borrowernumber, '100');
99     $sth->execute($borrower->borrowernumber, '200');
100
101     $sth = $dbh->prepare("SELECT count(*) FROM accountlines");
102     $sth->execute;
103     my $count = $sth->fetchrow_array;
104     is ($count, 2, 'There is 2 lines as expected');
105
106     # Testing recordpayment -------------------------
107     # There is $100 in the account
108     $sth = $dbh->prepare("SELECT amountoutstanding FROM accountlines WHERE borrowernumber=?");
109     my $amountoutstanding = $dbh->selectcol_arrayref($sth, {}, $borrower->borrowernumber);
110     my $amountleft = 0;
111     for my $line ( @$amountoutstanding ) {
112         $amountleft += $line;
113     }
114     ok($amountleft == 300, 'The account has 300$ as expected' );
115
116     # We make a $20 payment
117     my $borrowernumber = $borrower->borrowernumber;
118     my $data = '20.00';
119     my $sys_paytype;
120     my $payment_note = '$20.00 payment note';
121     recordpayment($borrowernumber, $data, $sys_paytype, $payment_note);
122     # There is now $280 in the account
123     $sth = $dbh->prepare("SELECT amountoutstanding FROM accountlines WHERE borrowernumber=?");
124     $amountoutstanding = $dbh->selectcol_arrayref($sth, {}, $borrower->borrowernumber);
125     $amountleft = 0;
126     for my $line ( @$amountoutstanding ) {
127         $amountleft += $line;
128     }
129     ok($amountleft == 280, 'The account has $280 as expected' );
130     # Is the payment note well registered
131     $sth = $dbh->prepare("SELECT note FROM accountlines WHERE borrowernumber=? ORDER BY accountlines_id DESC LIMIT 1");
132     $sth->execute($borrower->borrowernumber);
133     my $note = $sth->fetchrow_array;
134     is($note,'$20.00 payment note', '$20.00 payment note is registered');
135
136     # We make a -$30 payment (a NEGATIVE payment)
137     $data = '-30.00';
138     $payment_note = '-$30.00 payment note';
139     recordpayment($borrowernumber, $data, $sys_paytype, $payment_note);
140     # There is now $310 in the account
141     $sth = $dbh->prepare("SELECT amountoutstanding FROM accountlines WHERE borrowernumber=?");
142     $amountoutstanding = $dbh->selectcol_arrayref($sth, {}, $borrower->borrowernumber);
143     $amountleft = 0;
144     for my $line ( @$amountoutstanding ) {
145         $amountleft += $line;
146     }
147     ok($amountleft == 310, 'The account has $310 as expected' );
148     # Is the payment note well registered
149     $sth = $dbh->prepare("SELECT note FROM accountlines WHERE borrowernumber=? ORDER BY accountlines_id DESC LIMIT 1");
150     $sth->execute($borrower->borrowernumber);
151     $note = $sth->fetchrow_array;
152     is($note,'-$30.00 payment note', '-$30.00 payment note is registered');
153
154     #We make a $150 payment ( > 1stLine )
155     $data = '150.00';
156     $payment_note = '$150.00 payment note';
157     recordpayment($borrowernumber, $data, $sys_paytype, $payment_note);
158     # There is now $160 in the account
159     $sth = $dbh->prepare("SELECT amountoutstanding FROM accountlines WHERE borrowernumber=?");
160     $amountoutstanding = $dbh->selectcol_arrayref($sth, {}, $borrower->borrowernumber);
161     $amountleft = 0;
162     for my $line ( @$amountoutstanding ) {
163         $amountleft += $line;
164     }
165     ok($amountleft == 160, 'The account has $160 as expected' );
166     # Is the payment note well registered
167     $sth = $dbh->prepare("SELECT note FROM accountlines WHERE borrowernumber=? ORDER BY accountlines_id DESC LIMIT 1");
168     $sth->execute($borrower->borrowernumber);
169     $note = $sth->fetchrow_array;
170     is($note,'$150.00 payment note', '$150.00 payment note is registered');
171
172     #We make a $200 payment ( > amountleft )
173     $data = '200.00';
174     $payment_note = '$200.00 payment note';
175     recordpayment($borrowernumber, $data, $sys_paytype, $payment_note);
176     # There is now -$40 in the account
177     $sth = $dbh->prepare("SELECT amountoutstanding FROM accountlines WHERE borrowernumber=?");
178     $amountoutstanding = $dbh->selectcol_arrayref($sth, {}, $borrower->borrowernumber);
179     $amountleft = 0;
180     for my $line ( @$amountoutstanding ) {
181         $amountleft += $line;
182     }
183     ok($amountleft == -40, 'The account has -$40 as expected, (credit situation)' );
184     # Is the payment note well registered
185     $sth = $dbh->prepare("SELECT note FROM accountlines WHERE borrowernumber=? ORDER BY accountlines_id DESC LIMIT 1");
186     $sth->execute($borrower->borrowernumber);
187     $note = $sth->fetchrow_array;
188     is($note,'$200.00 payment note', '$200.00 payment note is registered');
189 };
190
191 subtest "makepayment() tests" => sub {
192
193     plan tests => 6;
194
195     # Create a borrower
196     my $category   = $builder->build({ source => 'Category' })->{ categorycode };
197     my $branch     = $builder->build({ source => 'Branch' })->{ branchcode };
198     $branchcode = $branch;
199     my $borrowernumber = $builder->build({
200         source => 'Borrower',
201         value  => { categorycode => $category,
202                     branchcode   => $branch }
203     })->{ borrowernumber };
204
205     my $amount = 100;
206     my $accountline = $builder->build({ source => 'Accountline',
207         value  => { borrowernumber => $borrowernumber,
208                     amount => $amount,
209                     amountoutstanding => $amount }
210     });
211
212     my $rs = $schema->resultset('Accountline')->search({
213         borrowernumber => $borrowernumber
214     });
215
216     is( $rs->count(), 1, 'Accountline created' );
217
218     # make the full payment
219     makepayment(
220         $accountline->{ accountlines_id }, $borrowernumber,
221         $accountline->{ accountno },       $amount,
222         $borrowernumber, $branch, 'A payment note' );
223
224     # TODO: someone should write actual tests for makepayment()
225
226     my $stat = $schema->resultset('Statistic')->search({
227         branch  => $branch,
228         type    => 'payment'
229     }, { order_by => { -desc => 'datetime' } })->next();
230
231     ok( defined $stat, "There's a payment log that matches the branch" );
232
233     SKIP: {
234         skip "No statistic logged", 4 unless defined $stat;
235
236         is( $stat->type, 'payment', "Correct statistic type" );
237         is( $stat->branch, $branch, "Correct branch logged to statistics" );
238         is( $stat->borrowernumber, $borrowernumber, "Correct borrowernumber logged to statistics" );
239         is( $stat->value, "$amount" . "\.0000", "Correct amount logged to statistics" );
240     }
241 };
242
243 subtest "makepartialpayment() tests" => sub {
244
245     plan tests => 6;
246
247     # Create a borrower
248     my $category   = $builder->build({ source => 'Category' })->{ categorycode };
249     my $branch     = $builder->build({ source => 'Branch' })->{ branchcode };
250     $branchcode = $branch;
251     my $borrowernumber = $builder->build({
252         source => 'Borrower',
253         value  => { categorycode => $category,
254                     branchcode   => $branch }
255     })->{ borrowernumber };
256
257     my $amount = 100;
258     my $partialamount = 60;
259     my $accountline = $builder->build({ source => 'Accountline',
260         value  => { borrowernumber => $borrowernumber,
261                     amount => $amount,
262                     amountoutstanding => $amount }
263     });
264
265     my $rs = $schema->resultset('Accountline')->search({
266         borrowernumber => $borrowernumber
267     });
268
269     is( $rs->count(), 1, 'Accountline created' );
270
271     # make the full payment
272     makepartialpayment(
273         $accountline->{ accountlines_id }, $borrowernumber,
274         $accountline->{ accountno },       $partialamount,
275         $borrowernumber, $branch, 'A payment note' );
276
277     # TODO: someone should write actual tests for makepartialpayment()
278
279     my $stat = $schema->resultset('Statistic')->search({
280         branch  => $branch,
281         type    => 'payment'
282     }, { order_by => { -desc => 'datetime' } })->next();
283
284     ok( defined $stat, "There's a payment log that matches the branch" );
285
286     SKIP: {
287         skip "No statistic logged", 4 unless defined $stat;
288
289         is( $stat->type, 'payment', "Correct statistic type" );
290         is( $stat->branch, $branch, "Correct branch logged to statistics" );
291         is( $stat->borrowernumber, $borrowernumber, "Correct borrowernumber logged to statistics" );
292         is( $stat->value, "$partialamount" . "\.0000", "Correct amount logged to statistics" );
293     }
294 };
295
296 $dbh->rollback;
297
298 1;