View | Details | Raw Unified | Return to bug 6427
Collapse All | Expand All

(-)a/C4/Accounts.pm (-821 lines)
Lines 1-821 Link Here
1
package C4::Accounts;
2
3
# Copyright 2000-2002 Katipo Communications
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 2 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, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
21
use strict;
22
#use warnings; FIXME - Bug 2505
23
use C4::Context;
24
use C4::Stats;
25
use C4::Members;
26
use C4::Circulation qw(ReturnLostItem);
27
use C4::Log qw(logaction);
28
29
use Data::Dumper qw(Dumper);
30
31
use vars qw($VERSION @ISA @EXPORT);
32
33
BEGIN {
34
	# set the version for version checking
35
    $VERSION = 3.07.00.049;
36
	require Exporter;
37
	@ISA    = qw(Exporter);
38
	@EXPORT = qw(
39
		&recordpayment
40
		&makepayment
41
		&manualinvoice
42
		&getnextacctno
43
		&getcharges
44
		&ModNote
45
		&getcredits
46
		&getrefunds
47
		&chargelostitem
48
		&ReversePayment
49
                &makepartialpayment
50
                &recordpayment_selectaccts
51
                &WriteOffFee
52
	);
53
}
54
55
=head1 NAME
56
57
C4::Accounts - Functions for dealing with Koha accounts
58
59
=head1 SYNOPSIS
60
61
use C4::Accounts;
62
63
=head1 DESCRIPTION
64
65
The functions in this module deal with the monetary aspect of Koha,
66
including looking up and modifying the amount of money owed by a
67
patron.
68
69
=head1 FUNCTIONS
70
71
=head2 recordpayment
72
73
  &recordpayment($borrowernumber, $payment);
74
75
Record payment by a patron. C<$borrowernumber> is the patron's
76
borrower number. C<$payment> is a floating-point number, giving the
77
amount that was paid.
78
79
Amounts owed are paid off oldest first. That is, if the patron has a
80
$1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
81
of $1.50, then the oldest fine will be paid off in full, and $0.50
82
will be credited to the next one.
83
84
=cut
85
86
#'
87
sub recordpayment {
88
89
    #here we update the account lines
90
    my ( $borrowernumber, $data ) = @_;
91
    my $dbh        = C4::Context->dbh;
92
    my $newamtos   = 0;
93
    my $accdata    = "";
94
    my $branch     = C4::Context->userenv->{'branch'};
95
    my $amountleft = $data;
96
    my $manager_id = 0;
97
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
98
99
    # begin transaction
100
    my $nextaccntno = getnextacctno($borrowernumber);
101
102
    # get lines with outstanding amounts to offset
103
    my $sth = $dbh->prepare(
104
        "SELECT * FROM accountlines
105
  WHERE (borrowernumber = ?) AND (amountoutstanding<>0)
106
  ORDER BY date"
107
    );
108
    $sth->execute($borrowernumber);
109
110
    # offset transactions
111
    my @ids;
112
    while ( ( $accdata = $sth->fetchrow_hashref ) and ( $amountleft > 0 ) ) {
113
        if ( $accdata->{'amountoutstanding'} < $amountleft ) {
114
            $newamtos = 0;
115
            $amountleft -= $accdata->{'amountoutstanding'};
116
        }
117
        else {
118
            $newamtos   = $accdata->{'amountoutstanding'} - $amountleft;
119
            $amountleft = 0;
120
        }
121
        my $thisacct = $accdata->{accountlines_id};
122
        my $usth     = $dbh->prepare(
123
            "UPDATE accountlines SET amountoutstanding= ?
124
     WHERE (accountlines_id = ?)"
125
        );
126
        $usth->execute( $newamtos, $thisacct );
127
128
        if ( C4::Context->preference("FinesLog") ) {
129
            $accdata->{'amountoutstanding_new'} = $newamtos;
130
            logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
131
                action                => 'fee_payment',
132
                borrowernumber        => $accdata->{'borrowernumber'},
133
                old_amountoutstanding => $accdata->{'amountoutstanding'},
134
                new_amountoutstanding => $newamtos,
135
                amount_paid           => $accdata->{'amountoutstanding'} - $newamtos,
136
                accountlines_id       => $accdata->{'accountlines_id'},
137
                accountno             => $accdata->{'accountno'},
138
                manager_id            => $manager_id,
139
            }));
140
            push( @ids, $accdata->{'accountlines_id'} );
141
        }
142
    }
143
144
    # create new line
145
    my $usth = $dbh->prepare(
146
        "INSERT INTO accountlines
147
  (borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding,manager_id)
148
  VALUES (?,?,now(),?,'Payment,thanks','Pay',?,?)"
149
    );
150
    $usth->execute( $borrowernumber, $nextaccntno, 0 - $data, 0 - $amountleft, $manager_id );
151
152
    UpdateStats( $branch, 'payment', $data, '', '', '', $borrowernumber, $nextaccntno );
153
154
    if ( C4::Context->preference("FinesLog") ) {
155
        $accdata->{'amountoutstanding_new'} = $newamtos;
156
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
157
            action            => 'create_payment',
158
            borrowernumber    => $borrowernumber,
159
            accountno         => $nextaccntno,
160
            amount            => $data * -1,
161
            amountoutstanding => $amountleft * -1,
162
            accounttype       => 'Pay',
163
            accountlines_paid => \@ids,
164
            manager_id        => $manager_id,
165
        }));
166
    }
167
168
}
169
170
=head2 makepayment
171
172
  &makepayment($accountlines_id, $borrowernumber, $acctnumber, $amount, $branchcode);
173
174
Records the fact that a patron has paid off the entire amount he or
175
she owes.
176
177
C<$borrowernumber> is the patron's borrower number. C<$acctnumber> is
178
the account that was credited. C<$amount> is the amount paid (this is
179
only used to record the payment. It is assumed to be equal to the
180
amount owed). C<$branchcode> is the code of the branch where payment
181
was made.
182
183
=cut
184
185
#'
186
# FIXME - I'm not at all sure about the above, because I don't
187
# understand what the acct* tables in the Koha database are for.
188
sub makepayment {
189
190
    #here we update both the accountoffsets and the account lines
191
    #updated to check, if they are paying off a lost item, we return the item
192
    # from their card, and put a note on the item record
193
    my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
194
    my $dbh = C4::Context->dbh;
195
    my $manager_id = 0;
196
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; 
197
198
    # begin transaction
199
    my $nextaccntno = getnextacctno($borrowernumber);
200
    my $newamtos    = 0;
201
    my $sth         = $dbh->prepare("SELECT * FROM accountlines WHERE accountlines_id=?");
202
    $sth->execute( $accountlines_id );
203
    my $data = $sth->fetchrow_hashref;
204
205
    my $payment;
206
    if ( $data->{'accounttype'} eq "Pay" ){
207
        my $udp = 		
208
            $dbh->prepare(
209
                "UPDATE accountlines
210
                    SET amountoutstanding = 0, description = 'Payment,thanks'
211
                    WHERE accountlines_id = ?
212
                "
213
            );
214
        $udp->execute($accountlines_id);
215
    }else{
216
        my $udp = 		
217
            $dbh->prepare(
218
                "UPDATE accountlines
219
                    SET amountoutstanding = 0
220
                    WHERE accountlines_id = ?
221
                "
222
            );
223
        $udp->execute($accountlines_id);
224
225
         # create new line
226
        my $payment = 0 - $amount;
227
        $payment_note //= "";
228
        
229
        my $ins = 
230
            $dbh->prepare( 
231
                "INSERT 
232
                    INTO accountlines (borrowernumber, accountno, date, amount, itemnumber, description, accounttype, amountoutstanding, manager_id, note)
233
                    VALUES ( ?, ?, now(), ?, ?, 'Payment,thanks', 'Pay', 0, ?, ?)"
234
            );
235
        $ins->execute($borrowernumber, $nextaccntno, $payment, $data->{'itemnumber'}, $manager_id, $payment_note);
236
    }
237
238
    if ( C4::Context->preference("FinesLog") ) {
239
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
240
            action                => 'fee_payment',
241
            borrowernumber        => $borrowernumber,
242
            old_amountoutstanding => $data->{'amountoutstanding'},
243
            new_amountoutstanding => 0,
244
            amount_paid           => $data->{'amountoutstanding'},
245
            accountlines_id       => $data->{'accountlines_id'},
246
            accountno             => $data->{'accountno'},
247
            manager_id            => $manager_id,
248
        }));
249
250
251
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
252
            action            => 'create_payment',
253
            borrowernumber    => $borrowernumber,
254
            accountno         => $nextaccntno,
255
            amount            => $payment,
256
            amountoutstanding => 0,,
257
            accounttype       => 'Pay',
258
            accountlines_paid => [$data->{'accountlines_id'}],
259
            manager_id        => $manager_id,
260
        }));
261
    }
262
263
264
    # FIXME - The second argument to &UpdateStats is supposed to be the
265
    # branch code.
266
    # UpdateStats is now being passed $accountno too. MTJ
267
    UpdateStats( $user, 'payment', $amount, '', '', '', $borrowernumber,
268
        $accountno );
269
270
    #check to see what accounttype
271
    if ( $data->{'accounttype'} eq 'Rep' || $data->{'accounttype'} eq 'L' ) {
272
        C4::Circulation::ReturnLostItem( $borrowernumber, $data->{'itemnumber'} );
273
    }
274
    my $sthr = $dbh->prepare("SELECT max(accountlines_id) AS lastinsertid FROM accountlines");
275
    $sthr->execute();
276
    my $datalastinsertid = $sthr->fetchrow_hashref;
277
    return $datalastinsertid->{'lastinsertid'};
278
}
279
280
=head2 getnextacctno
281
282
  $nextacct = &getnextacctno($borrowernumber);
283
284
Returns the next unused account number for the patron with the given
285
borrower number.
286
287
=cut
288
289
#'
290
# FIXME - Okay, so what does the above actually _mean_?
291
sub getnextacctno {
292
    my ($borrowernumber) = shift or return;
293
    my $sth = C4::Context->dbh->prepare(
294
        "SELECT accountno+1 FROM accountlines
295
            WHERE    (borrowernumber = ?)
296
            ORDER BY accountno DESC
297
            LIMIT 1"
298
    );
299
    $sth->execute($borrowernumber);
300
    return ($sth->fetchrow || 1);
301
}
302
303
=head2 fixaccounts (removed)
304
305
  &fixaccounts($accountlines_id, $borrowernumber, $accountnumber, $amount);
306
307
#'
308
# FIXME - I don't understand what this function does.
309
sub fixaccounts {
310
    my ( $accountlines_id, $borrowernumber, $accountno, $amount ) = @_;
311
    my $dbh = C4::Context->dbh;
312
    my $sth = $dbh->prepare(
313
        "SELECT * FROM accountlines WHERE accountlines_id=?"
314
    );
315
    $sth->execute( $accountlines_id );
316
    my $data = $sth->fetchrow_hashref;
317
318
    # FIXME - Error-checking
319
    my $diff        = $amount - $data->{'amount'};
320
    my $outstanding = $data->{'amountoutstanding'} + $diff;
321
    $sth->finish;
322
323
    $dbh->do(<<EOT);
324
        UPDATE  accountlines
325
        SET     amount = '$amount',
326
                amountoutstanding = '$outstanding'
327
        WHERE   accountlines_id = $accountlines_id
328
EOT
329
	# FIXME: exceedingly bad form.  Use prepare with placholders ("?") in query and execute args.
330
}
331
332
=cut
333
334
sub chargelostitem{
335
# lost ==1 Lost, lost==2 longoverdue, lost==3 lost and paid for
336
# FIXME: itemlost should be set to 3 after payment is made, should be a warning to the interface that
337
# a charge has been added
338
# FIXME : if no replacement price, borrower just doesn't get charged?
339
    my $dbh = C4::Context->dbh();
340
    my ($borrowernumber, $itemnumber, $amount, $description) = @_;
341
342
    # first make sure the borrower hasn't already been charged for this item
343
    my $sth1=$dbh->prepare("SELECT * from accountlines
344
    WHERE borrowernumber=? AND itemnumber=? and accounttype='L'");
345
    $sth1->execute($borrowernumber,$itemnumber);
346
    my $existing_charge_hashref=$sth1->fetchrow_hashref();
347
348
    # OK, they haven't
349
    unless ($existing_charge_hashref) {
350
        my $manager_id = 0;
351
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
352
        # This item is on issue ... add replacement cost to the borrower's record and mark it returned
353
        #  Note that we add this to the account even if there's no replacement price, allowing some other
354
        #  process (or person) to update it, since we don't handle any defaults for replacement prices.
355
        my $accountno = getnextacctno($borrowernumber);
356
        my $sth2=$dbh->prepare("INSERT INTO accountlines
357
        (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding,itemnumber,manager_id)
358
        VALUES (?,?,now(),?,?,'L',?,?,?)");
359
        $sth2->execute($borrowernumber,$accountno,$amount,
360
        $description,$amount,$itemnumber,$manager_id);
361
362
        if ( C4::Context->preference("FinesLog") ) {
363
            logaction("FINES", 'CREATE', $borrowernumber, Dumper({
364
                action            => 'create_fee',
365
                borrowernumber    => $borrowernumber,
366
                accountno         => $accountno,
367
                amount            => $amount,
368
                amountoutstanding => $amount,
369
                description       => $description,
370
                accounttype       => 'L',
371
                itemnumber        => $itemnumber,
372
                manager_id        => $manager_id,
373
            }));
374
        }
375
376
    }
377
}
378
379
=head2 manualinvoice
380
381
  &manualinvoice($borrowernumber, $itemnumber, $description, $type,
382
                 $amount, $note);
383
384
C<$borrowernumber> is the patron's borrower number.
385
C<$description> is a description of the transaction.
386
C<$type> may be one of C<CS>, C<CB>, C<CW>, C<CF>, C<CL>, C<N>, C<L>,
387
or C<REF>.
388
C<$itemnumber> is the item involved, if pertinent; otherwise, it
389
should be the empty string.
390
391
=cut
392
393
#'
394
# FIXME: In Koha 3.0 , the only account adjustment 'types' passed to this function
395
# are :  
396
# 		'C' = CREDIT
397
# 		'FOR' = FORGIVEN  (Formerly 'F', but 'F' is taken to mean 'FINE' elsewhere)
398
# 		'N' = New Card fee
399
# 		'F' = Fine
400
# 		'A' = Account Management fee
401
# 		'M' = Sundry
402
# 		'L' = Lost Item
403
#
404
405
sub manualinvoice {
406
    my ( $borrowernumber, $itemnum, $desc, $type, $amount, $note ) = @_;
407
    my $manager_id = 0;
408
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
409
    my $dbh      = C4::Context->dbh;
410
    my $notifyid = 0;
411
    my $insert;
412
    my $accountno  = getnextacctno($borrowernumber);
413
    my $amountleft = $amount;
414
415
    if ( $type eq 'N' ) {
416
        $desc .= " New Card";
417
    }
418
    if ( $type eq 'F' ) {
419
        $desc .= " Fine";
420
    }
421
    if ( $type eq 'A' ) {
422
        $desc .= " Account Management fee";
423
    }
424
    if ( $type eq 'M' ) {
425
        $desc .= " Sundry";
426
    }
427
428
    if ( $type eq 'L' && $desc eq '' ) {
429
430
        $desc = " Lost Item";
431
    }
432
    if (   ( $type eq 'L' )
433
        or ( $type eq 'F' )
434
        or ( $type eq 'A' )
435
        or ( $type eq 'N' )
436
        or ( $type eq 'M' ) )
437
    {
438
        $notifyid = 1;
439
    }
440
441
    if ( $itemnum ) {
442
        $desc .= ' ' . $itemnum;
443
        my $sth = $dbh->prepare(
444
            'INSERT INTO  accountlines
445
                        (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber,notify_id, note, manager_id)
446
        VALUES (?, ?, now(), ?,?, ?,?,?,?,?,?)');
447
     $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $itemnum,$notifyid, $note, $manager_id) || return $sth->errstr;
448
  } else {
449
    my $sth=$dbh->prepare("INSERT INTO  accountlines
450
            (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding,notify_id, note, manager_id)
451
            VALUES (?, ?, now(), ?, ?, ?, ?,?,?,?)"
452
        );
453
        $sth->execute( $borrowernumber, $accountno, $amount, $desc, $type,
454
            $amountleft, $notifyid, $note, $manager_id );
455
    }
456
457
    if ( C4::Context->preference("FinesLog") ) {
458
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
459
            action            => 'create_fee',
460
            borrowernumber    => $borrowernumber,
461
            accountno         => $accountno,
462
            amount            => $amount,
463
            description       => $desc,
464
            accounttype       => $type,
465
            amountoutstanding => $amountleft,
466
            notify_id         => $notifyid,
467
            note              => $note,
468
            itemnumber        => $itemnum,
469
            manager_id        => $manager_id,
470
        }));
471
    }
472
473
    return 0;
474
}
475
476
sub getcharges {
477
	my ( $borrowerno, $timestamp, $accountno ) = @_;
478
	my $dbh        = C4::Context->dbh;
479
	my $timestamp2 = $timestamp - 1;
480
	my $query      = "";
481
	my $sth = $dbh->prepare(
482
			"SELECT * FROM accountlines WHERE borrowernumber=? AND accountno = ?"
483
          );
484
	$sth->execute( $borrowerno, $accountno );
485
	
486
    my @results;
487
    while ( my $data = $sth->fetchrow_hashref ) {
488
		push @results,$data;
489
	}
490
    return (@results);
491
}
492
493
sub ModNote {
494
    my ( $accountlines_id, $note ) = @_;
495
    my $dbh = C4::Context->dbh;
496
    my $sth = $dbh->prepare('UPDATE accountlines SET note = ? WHERE accountlines_id = ?');
497
    $sth->execute( $note, $accountlines_id );
498
}
499
500
sub getcredits {
501
	my ( $date, $date2 ) = @_;
502
	my $dbh = C4::Context->dbh;
503
	my $sth = $dbh->prepare(
504
			        "SELECT * FROM accountlines,borrowers
505
      WHERE amount < 0 AND accounttype <> 'Pay' AND accountlines.borrowernumber = borrowers.borrowernumber
506
	  AND timestamp >=TIMESTAMP(?) AND timestamp < TIMESTAMP(?)"
507
      );  
508
509
    $sth->execute( $date, $date2 );                                                                                                              
510
    my @results;          
511
    while ( my $data = $sth->fetchrow_hashref ) {
512
		$data->{'date'} = $data->{'timestamp'};
513
		push @results,$data;
514
	}
515
    return (@results);
516
} 
517
518
519
sub getrefunds {
520
	my ( $date, $date2 ) = @_;
521
	my $dbh = C4::Context->dbh;
522
	
523
	my $sth = $dbh->prepare(
524
			        "SELECT *,timestamp AS datetime                                                                                      
525
                  FROM accountlines,borrowers
526
                  WHERE (accounttype = 'REF'
527
					  AND accountlines.borrowernumber = borrowers.borrowernumber
528
					                  AND date  >=?  AND date  <?)"
529
    );
530
531
    $sth->execute( $date, $date2 );
532
533
    my @results;
534
    while ( my $data = $sth->fetchrow_hashref ) {
535
		push @results,$data;
536
		
537
	}
538
    return (@results);
539
}
540
541
sub ReversePayment {
542
    my ( $accountlines_id ) = @_;
543
    my $dbh = C4::Context->dbh;
544
545
    my $sth = $dbh->prepare('SELECT * FROM accountlines WHERE accountlines_id = ?');
546
    $sth->execute( $accountlines_id );
547
    my $row = $sth->fetchrow_hashref();
548
    my $amount_outstanding = $row->{'amountoutstanding'};
549
550
    if ( $amount_outstanding <= 0 ) {
551
        $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = amount * -1, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
552
        $sth->execute( $accountlines_id );
553
    } else {
554
        $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = 0, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
555
        $sth->execute( $accountlines_id );
556
    }
557
558
    if ( C4::Context->preference("FinesLog") ) {
559
        my $manager_id = 0;
560
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
561
562
        if ( $amount_outstanding <= 0 ) {
563
            $row->{'amountoutstanding'} *= -1;
564
        } else {
565
            $row->{'amountoutstanding'} = '0';
566
        }
567
        $row->{'description'} .= ' Reversed -';
568
        logaction("FINES", 'MODIFY', $row->{'borrowernumber'}, Dumper({
569
            action                => 'reverse_fee_payment',
570
            borrowernumber        => $row->{'borrowernumber'},
571
            old_amountoutstanding => $row->{'amountoutstanding'},
572
            new_amountoutstanding => 0 - $amount_outstanding,,
573
            accountlines_id       => $row->{'accountlines_id'},
574
            accountno             => $row->{'accountno'},
575
            manager_id            => $manager_id,
576
        }));
577
578
    }
579
580
}
581
582
=head2 recordpayment_selectaccts
583
584
  recordpayment_selectaccts($borrowernumber, $payment,$accts);
585
586
Record payment by a patron. C<$borrowernumber> is the patron's
587
borrower number. C<$payment> is a floating-point number, giving the
588
amount that was paid. C<$accts> is an array ref to a list of
589
accountnos which the payment can be recorded against
590
591
Amounts owed are paid off oldest first. That is, if the patron has a
592
$1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
593
of $1.50, then the oldest fine will be paid off in full, and $0.50
594
will be credited to the next one.
595
596
=cut
597
598
sub recordpayment_selectaccts {
599
    my ( $borrowernumber, $amount, $accts, $note ) = @_;
600
601
    my $dbh        = C4::Context->dbh;
602
    my $newamtos   = 0;
603
    my $accdata    = q{};
604
    my $branch     = C4::Context->userenv->{branch};
605
    my $amountleft = $amount;
606
    my $manager_id = 0;
607
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
608
    my $sql = 'SELECT * FROM accountlines WHERE (borrowernumber = ?) ' .
609
    'AND (amountoutstanding<>0) ';
610
    if (@{$accts} ) {
611
        $sql .= ' AND accountno IN ( ' .  join ',', @{$accts};
612
        $sql .= ' ) ';
613
    }
614
    $sql .= ' ORDER BY date';
615
    # begin transaction
616
    my $nextaccntno = getnextacctno($borrowernumber);
617
618
    # get lines with outstanding amounts to offset
619
    my $rows = $dbh->selectall_arrayref($sql, { Slice => {} }, $borrowernumber);
620
621
    # offset transactions
622
    my $sth     = $dbh->prepare('UPDATE accountlines SET amountoutstanding= ? ' .
623
        'WHERE accountlines_id=?');
624
625
    my @ids;
626
    for my $accdata ( @{$rows} ) {
627
        if ($amountleft == 0) {
628
            last;
629
        }
630
        if ( $accdata->{amountoutstanding} < $amountleft ) {
631
            $newamtos = 0;
632
            $amountleft -= $accdata->{amountoutstanding};
633
        }
634
        else {
635
            $newamtos   = $accdata->{amountoutstanding} - $amountleft;
636
            $amountleft = 0;
637
        }
638
        my $thisacct = $accdata->{accountlines_id};
639
        $sth->execute( $newamtos, $thisacct );
640
641
        if ( C4::Context->preference("FinesLog") ) {
642
            logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
643
                action                => 'fee_payment',
644
                borrowernumber        => $borrowernumber,
645
                old_amountoutstanding => $accdata->{'amountoutstanding'},
646
                new_amountoutstanding => $newamtos,
647
                amount_paid           => $accdata->{'amountoutstanding'} - $newamtos,
648
                accountlines_id       => $accdata->{'accountlines_id'},
649
                accountno             => $accdata->{'accountno'},
650
                manager_id            => $manager_id,
651
            }));
652
            push( @ids, $accdata->{'accountlines_id'} );
653
        }
654
655
    }
656
657
    # create new line
658
    $sql = 'INSERT INTO accountlines ' .
659
    '(borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding,manager_id,note) ' .
660
    q|VALUES (?,?,now(),?,'Payment,thanks','Pay',?,?,?)|;
661
    $dbh->do($sql,{},$borrowernumber, $nextaccntno, 0 - $amount, 0 - $amountleft, $manager_id, $note );
662
    UpdateStats( $branch, 'payment', $amount, '', '', '', $borrowernumber, $nextaccntno );
663
664
    if ( C4::Context->preference("FinesLog") ) {
665
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
666
            action            => 'create_payment',
667
            borrowernumber    => $borrowernumber,
668
            accountno         => $nextaccntno,
669
            amount            => 0 - $amount,
670
            amountoutstanding => 0 - $amountleft,
671
            accounttype       => 'Pay',
672
            accountlines_paid => \@ids,
673
            manager_id        => $manager_id,
674
        }));
675
    }
676
677
    return;
678
}
679
680
# makepayment needs to be fixed to handle partials till then this separate subroutine
681
# fills in
682
sub makepartialpayment {
683
    my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
684
    my $manager_id = 0;
685
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
686
    if (!$amount || $amount < 0) {
687
        return;
688
    }
689
    $payment_note //= "";
690
    my $dbh = C4::Context->dbh;
691
692
    my $nextaccntno = getnextacctno($borrowernumber);
693
    my $newamtos    = 0;
694
695
    my $data = $dbh->selectrow_hashref(
696
        'SELECT * FROM accountlines WHERE  accountlines_id=?',undef,$accountlines_id);
697
    my $new_outstanding = $data->{amountoutstanding} - $amount;
698
699
    my $update = 'UPDATE  accountlines SET amountoutstanding = ?  WHERE   accountlines_id = ? ';
700
    $dbh->do( $update, undef, $new_outstanding, $accountlines_id);
701
702
    if ( C4::Context->preference("FinesLog") ) {
703
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
704
            action                => 'fee_payment',
705
            borrowernumber        => $borrowernumber,
706
            old_amountoutstanding => $data->{'amountoutstanding'},
707
            new_amountoutstanding => $new_outstanding,
708
            amount_paid           => $data->{'amountoutstanding'} - $new_outstanding,
709
            accountlines_id       => $data->{'accountlines_id'},
710
            accountno             => $data->{'accountno'},
711
            manager_id            => $manager_id,
712
        }));
713
    }
714
715
    # create new line
716
    my $insert = 'INSERT INTO accountlines (borrowernumber, accountno, date, amount, '
717
    .  'description, accounttype, amountoutstanding, itemnumber, manager_id, note) '
718
    . ' VALUES (?, ?, now(), ?, ?, ?, 0, ?, ?, ?)';
719
720
    $dbh->do(  $insert, undef, $borrowernumber, $nextaccntno, $amount,
721
        "Payment, thanks - $user", 'Pay', $data->{'itemnumber'}, $manager_id, $payment_note);
722
723
    UpdateStats( $user, 'payment', $amount, '', '', '', $borrowernumber, $accountno );
724
725
    if ( C4::Context->preference("FinesLog") ) {
726
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
727
            action            => 'create_payment',
728
            borrowernumber    => $user,
729
            accountno         => $nextaccntno,
730
            amount            => 0 - $amount,
731
            accounttype       => 'Pay',
732
            itemnumber        => $data->{'itemnumber'},
733
            accountlines_paid => [ $data->{'accountlines_id'} ],
734
            manager_id        => $manager_id,
735
        }));
736
    }
737
738
    return;
739
}
740
741
=head2 WriteOffFee
742
743
  WriteOffFee( $borrowernumber, $accountline_id, $itemnum, $accounttype, $amount, $branch, $payment_note );
744
745
Write off a fine for a patron.
746
C<$borrowernumber> is the patron's borrower number.
747
C<$accountline_id> is the accountline_id of the fee to write off.
748
C<$itemnum> is the itemnumber of of item whose fine is being written off.
749
C<$accounttype> is the account type of the fine being written off.
750
C<$amount> is a floating-point number, giving the amount that is being written off.
751
C<$branch> is the branchcode of the library where the writeoff occurred.
752
C<$payment_note> is the note to attach to this payment
753
754
=cut
755
756
sub WriteOffFee {
757
    my ( $borrowernumber, $accountlines_id, $itemnum, $accounttype, $amount, $branch, $payment_note ) = @_;
758
    $payment_note //= "";
759
    $branch ||= C4::Context->userenv->{branch};
760
    my $manager_id = 0;
761
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
762
763
    # if no item is attached to fine, make sure to store it as a NULL
764
    $itemnum ||= undef;
765
766
    my ( $sth, $query );
767
    my $dbh = C4::Context->dbh();
768
769
    $query = "
770
        UPDATE accountlines SET amountoutstanding = 0
771
        WHERE accountlines_id = ? AND borrowernumber = ?
772
    ";
773
    $sth = $dbh->prepare( $query );
774
    $sth->execute( $accountlines_id, $borrowernumber );
775
776
    if ( C4::Context->preference("FinesLog") ) {
777
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
778
            action                => 'fee_writeoff',
779
            borrowernumber        => $borrowernumber,
780
            accountlines_id       => $accountlines_id,
781
            manager_id            => $manager_id,
782
        }));
783
    }
784
785
    $query ="
786
        INSERT INTO accountlines
787
        ( borrowernumber, accountno, itemnumber, date, amount, description, accounttype, manager_id, note )
788
        VALUES ( ?, ?, ?, NOW(), ?, 'Writeoff', 'W', ?, ? )
789
    ";
790
    $sth = $dbh->prepare( $query );
791
    my $acct = getnextacctno($borrowernumber);
792
    $sth->execute( $borrowernumber, $acct, $itemnum, $amount, $manager_id, $payment_note );
793
794
    if ( C4::Context->preference("FinesLog") ) {
795
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
796
            action            => 'create_writeoff',
797
            borrowernumber    => $borrowernumber,
798
            accountno         => $acct,
799
            amount            => 0 - $amount,
800
            accounttype       => 'W',
801
            itemnumber        => $itemnum,
802
            accountlines_paid => [ $accountlines_id ],
803
            manager_id        => $manager_id,
804
        }));
805
    }
806
807
    UpdateStats( $branch, 'writeoff', $amount, q{}, q{}, q{}, $borrowernumber );
808
809
}
810
811
END { }    # module clean-up code here (global destructor)
812
813
1;
814
__END__
815
816
=head1 SEE ALSO
817
818
DBI(3)
819
820
=cut
821
(-)a/C4/Circulation.pm (-166 / +145 lines)
Lines 30-36 use C4::Items; Link Here
30
use C4::Members;
30
use C4::Members;
31
use C4::Dates;
31
use C4::Dates;
32
use C4::Dates qw(format_date);
32
use C4::Dates qw(format_date);
33
use C4::Accounts;
33
use Koha::Accounts;
34
use C4::ItemCirculationAlertPreference;
34
use C4::ItemCirculationAlertPreference;
35
use C4::Message;
35
use C4::Message;
36
use C4::Debug;
36
use C4::Debug;
Lines 48-53 use Data::Dumper; Link Here
48
use Koha::DateUtils;
48
use Koha::DateUtils;
49
use Koha::Calendar;
49
use Koha::Calendar;
50
use Koha::Borrower::Debarments;
50
use Koha::Borrower::Debarments;
51
use Koha::Database;
51
use Carp;
52
use Carp;
52
use Date::Calc qw(
53
use Date::Calc qw(
53
  Today
54
  Today
Lines 1275-1281 sub AddIssue { Link Here
1275
        ## If item was lost, it has now been found, reverse any list item charges if neccessary.
1276
        ## If item was lost, it has now been found, reverse any list item charges if neccessary.
1276
        if ( $item->{'itemlost'} ) {
1277
        if ( $item->{'itemlost'} ) {
1277
            if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) {
1278
            if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) {
1278
                _FixAccountForLostAndReturned( $item->{'itemnumber'}, undef, $item->{'barcode'} );
1279
                _FixAccountForLostAndReturned( $item->{'itemnumber'} );
1279
            }
1280
            }
1280
        }
1281
        }
1281
1282
Lines 1812-1820 sub AddReturn { Link Here
1812
                if ( $amount > 0
1813
                if ( $amount > 0
1813
                    && C4::Context->preference('finesMode') eq 'production' )
1814
                    && C4::Context->preference('finesMode') eq 'production' )
1814
                {
1815
                {
1815
                    C4::Overdues::UpdateFine( $issue->{itemnumber},
1816
                    C4::Overdues::UpdateFine(
1816
                        $issue->{borrowernumber},
1817
                        {
1817
                        $amount, $type, output_pref($datedue) );
1818
                            itemnumber     => $issue->{itemnumber},
1819
                            borrowernumber => $issue->{borrowernumber},
1820
                            amount         => $amount,
1821
                            due            => output_pref($datedue),
1822
                            issue_id       => $issue->{issue_id}
1823
                        }
1824
                    );
1818
                }
1825
                }
1819
            }
1826
            }
1820
1827
Lines 1864-1881 sub AddReturn { Link Here
1864
        $messages->{'WasLost'} = 1;
1871
        $messages->{'WasLost'} = 1;
1865
1872
1866
        if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) {
1873
        if ( C4::Context->preference('RefundLostItemFeeOnReturn' ) ) {
1867
            _FixAccountForLostAndReturned($item->{'itemnumber'}, $borrowernumber, $barcode);    # can tolerate undef $borrowernumber
1874
            _FixAccountForLostAndReturned( $item->{'itemnumber'} );
1868
            $messages->{'LostItemFeeRefunded'} = 1;
1875
            $messages->{'LostItemFeeRefunded'} = 1;
1869
        }
1876
        }
1870
    }
1877
    }
1871
1878
1872
    # fix up the overdues in accounts...
1879
    # fix up the overdues in accounts...
1873
    if ($borrowernumber) {
1880
    if ($borrowernumber) {
1874
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
1881
        _FixOverduesOnReturn(
1875
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
1882
            {
1883
                exempt_fine => $exemptfine,
1884
                dropbox     => $dropbox,
1885
                issue       => $issue,
1886
            }
1887
        );
1876
        
1888
        
1877
        if ( $issue->{overdue} && $issue->{date_due} ) {
1889
        if ( $issue->{overdue} && $issue->{date_due} ) {
1878
# fix fine days
1890
            # fix fine days
1879
            my $debardate =
1891
            my $debardate =
1880
              _debar_user_on_return( $borrower, $item, $issue->{date_due}, $today );
1892
              _debar_user_on_return( $borrower, $item, $issue->{date_due}, $today );
1881
            $messages->{Debarred} = $debardate if ($debardate);
1893
            $messages->{Debarred} = $debardate if ($debardate);
Lines 2093-2231 Internal function, called only by AddReturn Link Here
2093
=cut
2105
=cut
2094
2106
2095
sub _FixOverduesOnReturn {
2107
sub _FixOverduesOnReturn {
2096
    my ($borrowernumber, $item);
2108
    my ( $params ) = @_;
2097
    unless ($borrowernumber = shift) {
2109
2098
        warn "_FixOverduesOnReturn() not supplied valid borrowernumber";
2110
    my $exemptfine = $params->{exempt_fine};
2099
        return;
2111
    my $dropbox    = $params->{dropbox};
2100
    }
2112
    my $issue      = $params->{issue};
2101
    unless ($item = shift) {
2113
2102
        warn "_FixOverduesOnReturn() not supplied valid itemnumber";
2103
        return;
2104
    }
2105
    my ($exemptfine, $dropbox) = @_;
2106
    my $dbh = C4::Context->dbh;
2114
    my $dbh = C4::Context->dbh;
2107
2115
2108
    # check for overdue fine
2116
    my $schema = Koha::Database->new()->schema;
2109
    my $sth = $dbh->prepare(
2117
    my $fine =
2110
"SELECT * FROM accountlines WHERE (borrowernumber = ?) AND (itemnumber = ?) AND (accounttype='FU' OR accounttype='O')"
2118
      $schema->resultset('AccountDebit')
2111
    );
2119
      ->single( { issue_id => $issue->issue_id(), type => Koha::Accounts::DebitTypes::Fine() } );
2112
    $sth->execute( $borrowernumber, $item );
2113
2120
2114
    # alter fine to show that the book has been returned
2121
    return unless ( $fine );
2115
    my $data = $sth->fetchrow_hashref;
2122
2116
    return 0 unless $data;    # no warning, there's just nothing to fix
2123
    $fine->accruing(0);
2117
2124
2118
    my $uquery;
2119
    my @bind = ($data->{'accountlines_id'});
2120
    if ($exemptfine) {
2125
    if ($exemptfine) {
2121
        $uquery = "update accountlines set accounttype='FFOR', amountoutstanding=0";
2126
        AddCredit(
2122
        if (C4::Context->preference("FinesLog")) {
2127
            {
2123
            &logaction("FINES", 'MODIFY',$borrowernumber,"Overdue forgiven: item $item");
2128
                borrower => $fine->borrowernumber(),
2124
        }
2129
                amount   => $fine->amount_original(),
2125
    } elsif ($dropbox && $data->{lastincrement}) {
2130
                debit_id => $fine->debit_id(),
2126
        my $outstanding = $data->{amountoutstanding} - $data->{lastincrement} ;
2131
                type     => Koha::Accounts::CreditTypes::Forgiven(),
2127
        my $amt = $data->{amount} - $data->{lastincrement} ;
2132
            }
2133
        );
2128
        if (C4::Context->preference("FinesLog")) {
2134
        if (C4::Context->preference("FinesLog")) {
2129
            &logaction("FINES", 'MODIFY',$borrowernumber,"Dropbox adjustment $amt, item $item");
2135
            &logaction(
2136
                "FINES", 'MODIFY',
2137
                $issue->borrowernumber(),
2138
                "Overdue forgiven: item " . $issue->itemnumber()
2139
            );
2130
        }
2140
        }
2131
         $uquery = "update accountlines set accounttype='F' ";
2141
    } elsif ($dropbox && $fine->amount_last_increment() != $fine->amount_original() ) {
2132
         if($outstanding  >= 0 && $amt >=0) {
2142
        if ( C4::Context->preference("FinesLog") ) {
2133
            $uquery .= ", amount = ? , amountoutstanding=? ";
2143
            &logaction( "FINES", 'MODIFY', $issue->borrowernumber(),
2134
            unshift @bind, ($amt, $outstanding) ;
2144
                    "Dropbox adjustment "
2145
                  . $fine->amount_last_increment()
2146
                  . ", item " . $issue->itemnumber() );
2135
        }
2147
        }
2136
    } else {
2148
        $fine->amount_original(
2137
        $uquery = "update accountlines set accounttype='F' ";
2149
            $fine->amount_original() - $fine->amount_last_increment() );
2150
        $fine->amount_outstanding(
2151
            $fine->amount_outstanding - $fine->amount_last_increment() );
2152
        $schema->resultset('AccountOffset')->create(
2153
            {
2154
                debit_id => $fine->debit_id(),
2155
                type     => Koha::Accounts::OffsetTypes::Dropbox(),
2156
                amount   => $fine->amount_last_increment() * -1,
2157
            }
2158
        );
2138
    }
2159
    }
2139
    $uquery .= " where (accountlines_id = ?)";
2160
2140
    my $usth = $dbh->prepare($uquery);
2161
    return $fine->update();
2141
    return $usth->execute(@bind);
2142
}
2162
}
2143
2163
2144
=head2 _FixAccountForLostAndReturned
2164
=head2 _FixAccountForLostAndReturned
2145
2165
2146
  &_FixAccountForLostAndReturned($itemnumber, [$borrowernumber, $barcode]);
2166
  &_FixAccountForLostAndReturned($itemnumber);
2147
2148
Calculates the charge for a book lost and returned.
2149
2167
2150
Internal function, not exported, called only by AddReturn.
2168
  Refunds a lost item fee in necessary
2151
2152
FIXME: This function reflects how inscrutable fines logic is.  Fix both.
2153
FIXME: Give a positive return value on success.  It might be the $borrowernumber who received credit, or the amount forgiven.
2154
2169
2155
=cut
2170
=cut
2156
2171
2157
sub _FixAccountForLostAndReturned {
2172
sub _FixAccountForLostAndReturned {
2158
    my $itemnumber     = shift or return;
2173
    my ( $itemnumber ) = @_;
2159
    my $borrowernumber = @_ ? shift : undef;
2174
2160
    my $item_id        = @_ ? shift : $itemnumber;  # Send the barcode if you want that logged in the description
2175
    my $schema = Koha::Database->new()->schema;
2161
    my $dbh = C4::Context->dbh;
2176
2162
    # check for charge made for lost book
2177
    # Find the last issue for this item
2163
    my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE itemnumber = ? AND accounttype IN ('L', 'Rep', 'W') ORDER BY date DESC, accountno DESC");
2178
    my $issue =
2164
    $sth->execute($itemnumber);
2179
      $schema->resultset('Issue')->single( { itemnumber => $itemnumber } );
2165
    my $data = $sth->fetchrow_hashref;
2180
    $issue ||=
2166
    $data or return;    # bail if there is nothing to do
2181
      $schema->resultset('OldIssue')->single( { itemnumber => $itemnumber } );
2167
    $data->{accounttype} eq 'W' and return;    # Written off
2182
2168
2183
    return unless $issue;
2169
    # writeoff this amount
2184
2170
    my $offset;
2185
    # Find a lost fee for this issue
2171
    my $amount = $data->{'amount'};
2186
    my $debit = $schema->resultset('AccountDebit')->single(
2172
    my $acctno = $data->{'accountno'};
2187
        {
2173
    my $amountleft;                                             # Starts off undef/zero.
2188
            issue_id => $issue->issue_id(),
2174
    if ($data->{'amountoutstanding'} == $amount) {
2189
            type     => Koha::Accounts::DebitTypes::Lost()
2175
        $offset     = $data->{'amount'};
2176
        $amountleft = 0;                                        # Hey, it's zero here, too.
2177
    } else {
2178
        $offset     = $amount - $data->{'amountoutstanding'};   # Um, isn't this the same as ZERO?  We just tested those two things are ==
2179
        $amountleft = $data->{'amountoutstanding'} - $amount;   # Um, isn't this the same as ZERO?  We just tested those two things are ==
2180
    }
2181
    my $usth = $dbh->prepare("UPDATE accountlines SET accounttype = 'LR',amountoutstanding='0'
2182
        WHERE (accountlines_id = ?)");
2183
    $usth->execute($data->{'accountlines_id'});      # We might be adjusting an account for some OTHER borrowernumber now.  Not the one we passed in.
2184
    #check if any credit is left if so writeoff other accounts
2185
    my $nextaccntno = getnextacctno($data->{'borrowernumber'});
2186
    $amountleft *= -1 if ($amountleft < 0);
2187
    if ($amountleft > 0) {
2188
        my $msth = $dbh->prepare("SELECT * FROM accountlines WHERE (borrowernumber = ?)
2189
                            AND (amountoutstanding >0) ORDER BY date");     # might want to order by amountoustanding ASC (pay smallest first)
2190
        $msth->execute($data->{'borrowernumber'});
2191
        # offset transactions
2192
        my $newamtos;
2193
        my $accdata;
2194
        while (($accdata=$msth->fetchrow_hashref) and ($amountleft>0)){
2195
            if ($accdata->{'amountoutstanding'} < $amountleft) {
2196
                $newamtos = 0;
2197
                $amountleft -= $accdata->{'amountoutstanding'};
2198
            }  else {
2199
                $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
2200
                $amountleft = 0;
2201
            }
2202
            my $thisacct = $accdata->{'accountlines_id'};
2203
            # FIXME: move prepares outside while loop!
2204
            my $usth = $dbh->prepare("UPDATE accountlines SET amountoutstanding= ?
2205
                    WHERE (accountlines_id = ?)");
2206
            $usth->execute($newamtos,$thisacct);
2207
            $usth = $dbh->prepare("INSERT INTO accountoffsets
2208
                (borrowernumber, accountno, offsetaccount,  offsetamount)
2209
                VALUES
2210
                (?,?,?,?)");
2211
            $usth->execute($data->{'borrowernumber'},$accdata->{'accountno'},$nextaccntno,$newamtos);
2212
        }
2190
        }
2213
    }
2191
    );
2214
    $amountleft *= -1 if ($amountleft > 0);
2192
2215
    my $desc = "Item Returned " . $item_id;
2193
    return unless $debit;
2216
    $usth = $dbh->prepare("INSERT INTO accountlines
2194
2217
        (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
2195
    # Check for an existing found credit for this debit, if there is one, the fee has already been refunded and we do nothing
2218
        VALUES (?,?,now(),?,?,'CR',?)");
2196
    my @credits = $debit->account_offsets->search_related('credit', { 'credit.type' => Koha::Accounts::CreditTypes::Found() });
2219
    $usth->execute($data->{'borrowernumber'},$nextaccntno,0-$amount,$desc,$amountleft);
2197
2220
    if ($borrowernumber) {
2198
    return if @credits;
2221
        # FIXME: same as query above.  use 1 sth for both
2199
2222
        $usth = $dbh->prepare("INSERT INTO accountoffsets
2200
    # Ok, so we know we have an unrefunded lost item fee, let's refund it
2223
            (borrowernumber, accountno, offsetaccount,  offsetamount)
2201
    CreditLostItem(
2224
            VALUES (?,?,?,?)");
2202
        {
2225
        $usth->execute($borrowernumber, $data->{'accountno'}, $nextaccntno, $offset);
2203
            borrower => $issue->borrower(),
2226
    }
2204
            debit    => $debit
2205
        }
2206
    );
2207
2227
    ModItem({ paidfor => '' }, undef, $itemnumber);
2208
    ModItem({ paidfor => '' }, undef, $itemnumber);
2228
    return;
2229
}
2209
}
2230
2210
2231
=head2 _GetCircControlBranch
2211
=head2 _GetCircControlBranch
Lines 2584-2602 sub AddRenewal { Link Here
2584
    # Charge a new rental fee, if applicable?
2564
    # Charge a new rental fee, if applicable?
2585
    my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
2565
    my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
2586
    if ( $charge > 0 ) {
2566
    if ( $charge > 0 ) {
2587
        my $accountno = getnextacctno( $borrowernumber );
2588
        my $item = GetBiblioFromItemNumber($itemnumber);
2567
        my $item = GetBiblioFromItemNumber($itemnumber);
2589
        my $manager_id = 0;
2568
2590
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; 
2569
        my $borrower =
2591
        $sth = $dbh->prepare(
2570
          Koha::Database->new()->schema->resultset('Borrower')
2592
                "INSERT INTO accountlines
2571
          ->find($borrowernumber);
2593
                    (date, borrowernumber, accountno, amount, manager_id,
2572
2594
                    description,accounttype, amountoutstanding, itemnumber)
2573
        AddDebit(
2595
                    VALUES (now(),?,?,?,?,?,?,?,?)"
2574
            {
2575
                borrower   => $borrower,
2576
                itemnumber => $itemnumber,
2577
                amount     => $charge,
2578
                type       => Koha::Accounts::DebitTypes::Rental(),
2579
                description =>
2580
                  "Renewal of Rental Item $item->{'title'} $item->{'barcode'}"
2581
            }
2596
        );
2582
        );
2597
        $sth->execute( $borrowernumber, $accountno, $charge, $manager_id,
2598
            "Renewal of Rental Item $item->{'title'} $item->{'barcode'}",
2599
            'Rent', $charge, $itemnumber );
2600
    }
2583
    }
2601
2584
2602
    # Send a renewal slip according to checkout alert preferencei
2585
    # Send a renewal slip according to checkout alert preferencei
Lines 2767-2791 sub _get_discount_from_rule { Link Here
2767
2750
2768
=head2 AddIssuingCharge
2751
=head2 AddIssuingCharge
2769
2752
2770
  &AddIssuingCharge( $itemno, $borrowernumber, $charge )
2753
  &AddIssuingCharge( $itemnumber, $borrowernumber, $amount )
2771
2754
2772
=cut
2755
=cut
2773
2756
2774
sub AddIssuingCharge {
2757
sub AddIssuingCharge {
2775
    my ( $itemnumber, $borrowernumber, $charge ) = @_;
2758
    my ( $itemnumber, $borrowernumber, $amount ) = @_;
2776
    my $dbh = C4::Context->dbh;
2759
2777
    my $nextaccntno = getnextacctno( $borrowernumber );
2760
    return AddDebit(
2778
    my $manager_id = 0;
2761
        {
2779
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
2762
            borrower       => Koha::Database->new()->schema->resultset('Borrower')->find($borrowernumber),
2780
    my $query ="
2763
            itemnumber     => $itemnumber,
2781
        INSERT INTO accountlines
2764
            amount         => $amount,
2782
            (borrowernumber, itemnumber, accountno,
2765
            type           => Koha::Accounts::DebitTypes::Rental(),
2783
            date, amount, description, accounttype,
2766
        }
2784
            amountoutstanding, manager_id)
2767
    );
2785
        VALUES (?, ?, ?,now(), ?, 'Rental', 'Rent',?,?)
2786
    ";
2787
    my $sth = $dbh->prepare($query);
2788
    $sth->execute( $borrowernumber, $itemnumber, $nextaccntno, $charge, $charge, $manager_id );
2789
}
2768
}
2790
2769
2791
=head2 GetTransfers
2770
=head2 GetTransfers
Lines 3304-3333 sub ReturnLostItem{ Link Here
3304
sub LostItem{
3283
sub LostItem{
3305
    my ($itemnumber, $mark_returned) = @_;
3284
    my ($itemnumber, $mark_returned) = @_;
3306
3285
3307
    my $dbh = C4::Context->dbh();
3286
    my $schema = Koha::Database->new()->schema;
3308
    my $sth=$dbh->prepare("SELECT issues.*,items.*,biblio.title 
3309
                           FROM issues 
3310
                           JOIN items USING (itemnumber) 
3311
                           JOIN biblio USING (biblionumber)
3312
                           WHERE issues.itemnumber=?");
3313
    $sth->execute($itemnumber);
3314
    my $issues=$sth->fetchrow_hashref();
3315
3287
3316
    # If a borrower lost the item, add a replacement cost to the their record
3288
    my $issue =
3317
    if ( my $borrowernumber = $issues->{borrowernumber} ){
3289
      $schema->resultset('Issue')->single( { itemnumber => $itemnumber } );
3318
        my $borrower = C4::Members::GetMemberDetails( $borrowernumber );
3319
3290
3291
    my $borrower = $issue->borrower();
3292
    my $item     = $issue->item();
3293
3294
    # If a borrower lost the item, add a replacement cost to the their record
3295
    if ( $borrower ){
3320
        if (C4::Context->preference('WhenLostForgiveFine')){
3296
        if (C4::Context->preference('WhenLostForgiveFine')){
3321
            my $fix = _FixOverduesOnReturn($borrowernumber, $itemnumber, 1, 0); # 1, 0 = exemptfine, no-dropbox
3297
            _FixOverduesOnReturn(
3322
            defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $itemnumber...) failed!";  # zero is OK, check defined
3298
                {
3299
                    exempt_fine => 1,
3300
                    dropbox     => 0,
3301
                    issue       => $issue,
3302
                }
3303
            );
3323
        }
3304
        }
3324
        if (C4::Context->preference('WhenLostChargeReplacementFee')){
3305
        if ( C4::Context->preference('WhenLostChargeReplacementFee') ) {
3325
            C4::Accounts::chargelostitem($borrowernumber, $itemnumber, $issues->{'replacementprice'}, "Lost Item $issues->{'title'} $issues->{'barcode'}");
3306
            DebitLostItem( { borrower => $borrower, issue => $issue } );
3326
            #FIXME : Should probably have a way to distinguish this from an item that really was returned.
3327
            #warn " $issues->{'borrowernumber'}  /  $itemnumber ";
3328
        }
3307
        }
3329
3308
3330
        MarkIssueReturned($borrowernumber,$itemnumber,undef,undef,$borrower->{'privacy'}) if $mark_returned;
3309
        MarkIssueReturned( $borrower->borrowernumber(), $item->itemnumber(), undef, undef, $borrower->privacy() ) if $mark_returned;
3331
    }
3310
    }
3332
}
3311
}
3333
3312
(-)a/C4/Koha.pm (+2 lines)
Lines 1029-1034 C<$opac> If set to a true value, displays OPAC descriptions rather than normal o Link Here
1029
1029
1030
sub GetAuthorisedValues {
1030
sub GetAuthorisedValues {
1031
    my ( $category, $selected, $opac ) = @_;
1031
    my ( $category, $selected, $opac ) = @_;
1032
    warn "GetAuthorisedValues( $category, $selected, $opac )";
1032
    my $branch_limit = C4::Context->userenv ? C4::Context->userenv->{"branch"} : "";
1033
    my $branch_limit = C4::Context->userenv ? C4::Context->userenv->{"branch"} : "";
1033
    my @results;
1034
    my @results;
1034
    my $dbh      = C4::Context->dbh;
1035
    my $dbh      = C4::Context->dbh;
Lines 1075-1080 sub GetAuthorisedValues { Link Here
1075
        push @results, $data;
1076
        push @results, $data;
1076
    }
1077
    }
1077
    $sth->finish;
1078
    $sth->finish;
1079
    warn "RET: " . Data::Dumper::Dumper( \@results );
1078
    return \@results;
1080
    return \@results;
1079
}
1081
}
1080
1082
(-)a/C4/Members.pm (-118 / +38 lines)
Lines 29-35 use Date::Calc qw/Today Add_Delta_YM check_date Date_to_Days/; Link Here
29
use C4::Log; # logaction
29
use C4::Log; # logaction
30
use C4::Overdues;
30
use C4::Overdues;
31
use C4::Reserves;
31
use C4::Reserves;
32
use C4::Accounts;
33
use C4::Biblio;
32
use C4::Biblio;
34
use C4::Letters;
33
use C4::Letters;
35
use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable);
34
use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable);
Lines 41-46 use Koha::DateUtils; Link Here
41
use Koha::Borrower::Debarments qw(IsDebarred);
40
use Koha::Borrower::Debarments qw(IsDebarred);
42
use Text::Unaccent qw( unac_string );
41
use Text::Unaccent qw( unac_string );
43
use Koha::AuthUtils qw(hash_password);
42
use Koha::AuthUtils qw(hash_password);
43
use Koha::Accounts::DebitTypes;
44
44
45
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
45
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
46
46
Lines 83-90 BEGIN { Link Here
83
        &GetHideLostItemsPreference
83
        &GetHideLostItemsPreference
84
84
85
        &IsMemberBlocked
85
        &IsMemberBlocked
86
        &GetMemberAccountRecords
87
        &GetBorNotifyAcctRecord
88
86
89
        &GetborCatFromCatType
87
        &GetborCatFromCatType
90
        &GetBorrowercategory
88
        &GetBorrowercategory
Lines 338-346 sub GetMemberDetails { Link Here
338
        return;
336
        return;
339
    }
337
    }
340
    my $borrower = $sth->fetchrow_hashref;
338
    my $borrower = $sth->fetchrow_hashref;
341
    my ($amount) = GetMemberAccountRecords( $borrowernumber);
342
    $borrower->{'amountoutstanding'} = $amount;
343
    # FIXME - patronflags calls GetMemberAccountRecords... just have patronflags return $amount
344
    my $flags = patronflags( $borrower);
339
    my $flags = patronflags( $borrower);
345
    my $accessflagshash;
340
    my $accessflagshash;
346
341
Lines 432-454 The "message" field that comes from the DB is OK. Link Here
432
# FIXME rename this function.
427
# FIXME rename this function.
433
sub patronflags {
428
sub patronflags {
434
    my %flags;
429
    my %flags;
435
    my ( $patroninformation) = @_;
430
    my ($patroninformation) = @_;
436
    my $dbh=C4::Context->dbh;
431
    my $dbh = C4::Context->dbh;
437
    my ($balance, $owing) = GetMemberAccountBalance( $patroninformation->{'borrowernumber'});
432
    if ( $patroninformation->{account_balance} > 0 ) {
438
    if ( $owing > 0 ) {
439
        my %flaginfo;
433
        my %flaginfo;
440
        my $noissuescharge = C4::Context->preference("noissuescharge") || 5;
434
        my $noissuescharge = C4::Context->preference("noissuescharge") || 5;
441
        $flaginfo{'message'} = sprintf 'Patron owes %.02f', $owing;
435
        $flaginfo{'amount'}  = $patroninformation->{account_balance};
442
        $flaginfo{'amount'}  = sprintf "%.02f", $owing;
436
        if (  $patroninformation->{account_balance} > $noissuescharge && !C4::Context->preference("AllowFineOverride") ) {
443
        if ( $owing > $noissuescharge && !C4::Context->preference("AllowFineOverride") ) {
444
            $flaginfo{'noissues'} = 1;
437
            $flaginfo{'noissues'} = 1;
445
        }
438
        }
446
        $flags{'CHARGES'} = \%flaginfo;
439
        $flags{'CHARGES'} = \%flaginfo;
447
    }
440
    }
448
    elsif ( $balance < 0 ) {
441
    elsif ( $patroninformation->{account_balance} < 0 ) {
449
        my %flaginfo;
442
        my %flaginfo;
450
        $flaginfo{'message'} = sprintf 'Patron has credit of %.02f', -$balance;
443
        $flaginfo{'amount'}  = $patroninformation->{account_balance};
451
        $flaginfo{'amount'}  = sprintf "%.02f", $balance;
452
        $flags{'CREDITS'} = \%flaginfo;
444
        $flags{'CREDITS'} = \%flaginfo;
453
    }
445
    }
454
    if (   $patroninformation->{'gonenoaddress'}
446
    if (   $patroninformation->{'gonenoaddress'}
Lines 691-697 sub GetMemberIssuesAndFines { Link Here
691
    $sth->execute($borrowernumber);
683
    $sth->execute($borrowernumber);
692
    my $overdue_count = $sth->fetchrow_arrayref->[0];
684
    my $overdue_count = $sth->fetchrow_arrayref->[0];
693
685
694
    $sth = $dbh->prepare("SELECT SUM(amountoutstanding) FROM accountlines WHERE borrowernumber = ?");
686
    $sth = $dbh->prepare("SELECT account_balance FROM borrowers WHERE borrowernumber = ?");
695
    $sth->execute($borrowernumber);
687
    $sth->execute($borrowernumber);
696
    my $total_fines = $sth->fetchrow_arrayref->[0];
688
    my $total_fines = $sth->fetchrow_arrayref->[0];
697
689
Lines 1167-1223 sub GetAllIssues { Link Here
1167
}
1159
}
1168
1160
1169
1161
1170
=head2 GetMemberAccountRecords
1171
1172
  ($total, $acctlines, $count) = &GetMemberAccountRecords($borrowernumber);
1173
1174
Looks up accounting data for the patron with the given borrowernumber.
1175
1176
C<&GetMemberAccountRecords> returns a three-element array. C<$acctlines> is a
1177
reference-to-array, where each element is a reference-to-hash; the
1178
keys are the fields of the C<accountlines> table in the Koha database.
1179
C<$count> is the number of elements in C<$acctlines>. C<$total> is the
1180
total amount outstanding for all of the account lines.
1181
1182
=cut
1183
1184
sub GetMemberAccountRecords {
1185
    my ($borrowernumber) = @_;
1186
    my $dbh = C4::Context->dbh;
1187
    my @acctlines;
1188
    my $numlines = 0;
1189
    my $strsth      = qq(
1190
                        SELECT * 
1191
                        FROM accountlines 
1192
                        WHERE borrowernumber=?);
1193
    $strsth.=" ORDER BY date desc,timestamp DESC";
1194
    my $sth= $dbh->prepare( $strsth );
1195
    $sth->execute( $borrowernumber );
1196
1197
    my $total = 0;
1198
    while ( my $data = $sth->fetchrow_hashref ) {
1199
        if ( $data->{itemnumber} ) {
1200
            my $biblio = GetBiblioFromItemNumber( $data->{itemnumber} );
1201
            $data->{biblionumber} = $biblio->{biblionumber};
1202
            $data->{title}        = $biblio->{title};
1203
        }
1204
        $acctlines[$numlines] = $data;
1205
        $numlines++;
1206
        $total += int(1000 * $data->{'amountoutstanding'}); # convert float to integer to avoid round-off errors
1207
    }
1208
    $total /= 1000;
1209
    return ( $total, \@acctlines,$numlines);
1210
}
1211
1212
=head2 GetMemberAccountBalance
1162
=head2 GetMemberAccountBalance
1213
1163
1214
  ($total_balance, $non_issue_balance, $other_charges) = &GetMemberAccountBalance($borrowernumber);
1164
  ($total_balance, $non_issue_balance, $other_charges) = &GetMemberAccountBalance($borrowernumber);
1215
1165
1216
Calculates amount immediately owing by the patron - non-issue charges.
1166
Calculates amount immediately owing by the patron - non-issue charges.
1217
Based on GetMemberAccountRecords.
1218
Charges exempt from non-issue are:
1167
Charges exempt from non-issue are:
1219
* Res (reserves)
1168
* HOLD fees (reserves)
1220
* Rent (rental) if RentalsInNoissuesCharge syspref is set to false
1169
* RENTAL if RentalsInNoissuesCharge syspref is set to false
1221
* Manual invoices if ManInvInNoissuesCharge syspref is set to false
1170
* Manual invoices if ManInvInNoissuesCharge syspref is set to false
1222
1171
1223
=cut
1172
=cut
Lines 1225-1294 Charges exempt from non-issue are: Link Here
1225
sub GetMemberAccountBalance {
1174
sub GetMemberAccountBalance {
1226
    my ($borrowernumber) = @_;
1175
    my ($borrowernumber) = @_;
1227
1176
1228
    my $ACCOUNT_TYPE_LENGTH = 5; # this is plain ridiculous...
1177
    my $borrower =
1178
      Koha::Database->new()->schema->resultset('Borrower')
1179
      ->find($borrowernumber);
1229
1180
1230
    my @not_fines = ('Res');
1181
    my @not_fines;
1231
    push @not_fines, 'Rent' unless C4::Context->preference('RentalsInNoissuesCharge');
1232
    unless ( C4::Context->preference('ManInvInNoissuesCharge') ) {
1233
        my $dbh = C4::Context->dbh;
1234
        my $man_inv_types = $dbh->selectcol_arrayref(qq{SELECT authorised_value FROM authorised_values WHERE category = 'MANUAL_INV'});
1235
        push @not_fines, map substr($_, 0, $ACCOUNT_TYPE_LENGTH), @$man_inv_types;
1236
    }
1237
    my %not_fine = map {$_ => 1} @not_fines;
1238
1182
1239
    my ($total, $acctlines) = GetMemberAccountRecords($borrowernumber);
1183
    push( @not_fines, Koha::Accounts::DebitTypes::Hold() );
1240
    my $other_charges = 0;
1241
    foreach (@$acctlines) {
1242
        $other_charges += $_->{amountoutstanding} if $not_fine{ substr($_->{accounttype}, 0, $ACCOUNT_TYPE_LENGTH) };
1243
    }
1244
1245
    return ( $total, $total - $other_charges, $other_charges);
1246
}
1247
1248
=head2 GetBorNotifyAcctRecord
1249
1250
  ($total, $acctlines, $count) = &GetBorNotifyAcctRecord($params,$notifyid);
1251
1184
1252
Looks up accounting data for the patron with the given borrowernumber per file number.
1185
    push( @not_fines, Koha::Accounts::DebitTypes::Rental() )
1186
      unless C4::Context->preference('RentalsInNoissuesCharge');
1253
1187
1254
C<&GetBorNotifyAcctRecord> returns a three-element array. C<$acctlines> is a
1188
    unless ( C4::Context->preference('ManInvInNoissuesCharge') ) {
1255
reference-to-array, where each element is a reference-to-hash; the
1189
        my $dbh           = C4::Context->dbh;
1256
keys are the fields of the C<accountlines> table in the Koha database.
1190
        my $man_inv_types = $dbh->selectcol_arrayref(
1257
C<$count> is the number of elements in C<$acctlines>. C<$total> is the
1191
            qq{SELECT authorised_value FROM authorised_values WHERE category = 'MANUAL_INV'}
1258
total amount outstanding for all of the account lines.
1192
        );
1259
1193
        push( @not_fines, @$man_inv_types );
1260
=cut
1194
    }
1261
1195
1262
sub GetBorNotifyAcctRecord {
1196
    my $other_charges =
1263
    my ( $borrowernumber, $notifyid ) = @_;
1197
      Koha::Database->new()->schema->resultset('AccountDebit')->search(
1264
    my $dbh = C4::Context->dbh;
1198
        {
1265
    my @acctlines;
1199
            borrowernumber => $borrowernumber,
1266
    my $numlines = 0;
1200
            type           => { -not_in => \@not_fines }
1267
    my $sth = $dbh->prepare(
1268
            "SELECT * 
1269
                FROM accountlines 
1270
                WHERE borrowernumber=? 
1271
                    AND notify_id=? 
1272
                    AND amountoutstanding != '0' 
1273
                ORDER BY notify_id,accounttype
1274
                ");
1275
1276
    $sth->execute( $borrowernumber, $notifyid );
1277
    my $total = 0;
1278
    while ( my $data = $sth->fetchrow_hashref ) {
1279
        if ( $data->{itemnumber} ) {
1280
            my $biblio = GetBiblioFromItemNumber( $data->{itemnumber} );
1281
            $data->{biblionumber} = $biblio->{biblionumber};
1282
            $data->{title}        = $biblio->{title};
1283
        }
1201
        }
1284
        $acctlines[$numlines] = $data;
1202
      )->get_column('amount_outstanding')->sum();
1285
        $numlines++;
1203
1286
        $total += int(100 * $data->{'amountoutstanding'});
1204
    return (
1287
    }
1205
        $borrower->account_balance(),
1288
    $total /= 100;
1206
        $borrower->account_balance() - $other_charges,
1289
    return ( $total, \@acctlines, $numlines );
1207
        $other_charges
1208
    );
1290
}
1209
}
1291
1210
1211
1292
=head2 checkuniquemember (OUEST-PROVENCE)
1212
=head2 checkuniquemember (OUEST-PROVENCE)
1293
1213
1294
  ($result,$categorycode)  = &checkuniquemember($collectivity,$surname,$firstname,$dateofbirth);
1214
  ($result,$categorycode)  = &checkuniquemember($collectivity,$surname,$firstname,$dateofbirth);
(-)a/C4/Overdues.pm (-231 / +109 lines)
Lines 25-33 use Date::Calc qw/Today Date_to_Days/; Link Here
25
use Date::Manip qw/UnixDate/;
25
use Date::Manip qw/UnixDate/;
26
use C4::Circulation;
26
use C4::Circulation;
27
use C4::Context;
27
use C4::Context;
28
use C4::Accounts;
29
use C4::Log; # logaction
28
use C4::Log; # logaction
30
use C4::Debug;
29
use C4::Debug;
30
use Koha::Database;
31
use Koha::DateUtils;
31
32
32
use vars qw($VERSION @ISA @EXPORT);
33
use vars qw($VERSION @ISA @EXPORT);
33
34
Lines 41-52 BEGIN { Link Here
41
        &CalcFine
42
        &CalcFine
42
        &Getoverdues
43
        &Getoverdues
43
        &checkoverdues
44
        &checkoverdues
44
        &NumberNotifyId
45
        &AmountNotify
46
        &UpdateFine
45
        &UpdateFine
47
        &GetFine
46
        &GetFine
48
        
47
        
49
        &CheckItemNotify
50
        &GetOverduesForBranch
48
        &GetOverduesForBranch
51
        &RemoveNotifyLine
49
        &RemoveNotifyLine
52
        &AddNotifyLine
50
        &AddNotifyLine
Lines 456-609 sub GetIssuesIteminfo { Link Here
456
454
457
=head2 UpdateFine
455
=head2 UpdateFine
458
456
459
    &UpdateFine($itemnumber, $borrowernumber, $amount, $type, $description);
457
    UpdateFine(
458
        {
459
            itemnumber     => $itemnumber,
460
            borrowernumber => $borrowernumber,
461
            amount         => $amount,
462
            due            => $due,
463
            issue_id       => $issue_id
464
        }
465
    );
460
466
461
(Note: the following is mostly conjecture and guesswork.)
467
Updates the fine owed on an overdue item.
462
468
463
Updates the fine owed on an overdue book.
469
C<$itemnumber> is the items's id.
464
470
465
C<$itemnumber> is the book's item number.
471
C<$borrowernumber> is the id of the patron who currently
472
has the item on loan.
466
473
467
C<$borrowernumber> is the borrower number of the patron who currently
474
C<$amount> is the total amount of the fine owed by the patron.
468
has the book on loan.
469
475
470
C<$amount> is the current amount owed by the patron.
476
C<&UpdateFine> updates the amount owed for a given fine if an issue_id
477
is passed to it. Otherwise, a new fine will be created.
471
478
472
C<$type> will be used in the description of the fine.
479
=cut
473
480
474
C<$description> is a string that must be present in the description of
481
sub UpdateFine {
475
the fine. I think this is expected to be a date in DD/MM/YYYY format.
482
    my ($params) = @_;
476
483
477
C<&UpdateFine> looks up the amount currently owed on the given item
484
    my $itemnumber     = $params->{itemnumber};
478
and sets it to C<$amount>, creating, if necessary, a new entry in the
485
    my $borrowernumber = $params->{borrowernumber};
479
accountlines table of the Koha database.
486
    my $amount         = $params->{amount};
487
    my $due            = $params->{due};
488
    my $issue_id       = $params->{issue_id};
480
489
481
=cut
490
    my $schema = Koha::Database->new()->schema;
482
491
483
#
492
    my $borrower = $schema->resultset('Borrower')->find($borrowernumber);
484
# Question: Why should the caller have to
485
# specify both the item number and the borrower number? A book can't
486
# be on loan to two different people, so the item number should be
487
# sufficient.
488
#
489
# Possible Answer: You might update a fine for a damaged item, *after* it is returned.
490
#
491
sub UpdateFine {
492
    my ( $itemnum, $borrowernumber, $amount, $type, $due ) = @_;
493
	$debug and warn "UpdateFine($itemnum, $borrowernumber, $amount, " . ($type||'""') . ", $due) called";
494
    my $dbh = C4::Context->dbh;
495
    # FIXME - What exactly is this query supposed to do? It looks up an
496
    # entry in accountlines that matches the given item and borrower
497
    # numbers, where the description contains $due, and where the
498
    # account type has one of several values, but what does this _mean_?
499
    # Does it look up existing fines for this item?
500
    # FIXME - What are these various account types? ("FU", "O", "F", "M")
501
	#	"L"   is LOST item
502
	#   "A"   is Account Management Fee
503
	#   "N"   is New Card
504
	#   "M"   is Sundry
505
	#   "O"   is Overdue ??
506
	#   "F"   is Fine ??
507
	#   "FU"  is Fine UPDATE??
508
	#	"Pay" is Payment
509
	#   "REF" is Cash Refund
510
    my $sth = $dbh->prepare(
511
        "SELECT * FROM accountlines
512
        WHERE borrowernumber=?
513
        AND   accounttype IN ('FU','O','F','M')"
514
    );
515
    $sth->execute( $borrowernumber );
516
    my $data;
517
    my $total_amount_other = 0.00;
518
    my $due_qr = qr/$due/;
519
    # Cycle through the fines and
520
    # - find line that relates to the requested $itemnum
521
    # - accumulate fines for other items
522
    # so we can update $itemnum fine taking in account fine caps
523
    while (my $rec = $sth->fetchrow_hashref) {
524
        if ($rec->{itemnumber} == $itemnum && $rec->{description} =~ /$due_qr/) {
525
            if ($data) {
526
                warn "Not a unique accountlines record for item $itemnum borrower $borrowernumber";
527
            } else {
528
                $data = $rec;
529
                next;
530
            }
531
        }
532
        $total_amount_other += $rec->{'amountoutstanding'};
533
    }
534
493
535
    if (my $maxfine = C4::Context->preference('MaxFine')) {
494
    if ( my $maxfine = C4::Context->preference('MaxFine') ) {
536
        if ($total_amount_other + $amount > $maxfine) {
495
        if ( $borrower->account_balance() + $amount > $maxfine ) {
537
            my $new_amount = $maxfine - $total_amount_other;
496
            my $new_amount = $maxfine - $borrower->account_balance();
538
            return if $new_amount <= 0.00;
497
            warn "Reducing fine for item $itemnumber borrower $borrowernumber from $amount to $new_amount - MaxFine reached";
539
            warn "Reducing fine for item $itemnum borrower $borrowernumber from $amount to $new_amount - MaxFine reached";
498
            if ( $new_amount <= 0 ) {
499
                warn "Fine reduced to a non-positive ammount. Fine not created.";
500
                return;
501
            }
540
            $amount = $new_amount;
502
            $amount = $new_amount;
541
        }
503
        }
542
    }
504
    }
543
505
544
    if ( $data ) {
506
    my $timestamp = get_timestamp();
545
507
546
		# we're updating an existing fine.  Only modify if amount changed
508
    my $fine =
547
        # Note that in the current implementation, you cannot pay against an accruing fine
509
      $schema->resultset('AccountDebit')->single( { issue_id => $issue_id } );
548
        # (i.e. , of accounttype 'FU').  Doing so will break accrual.
510
549
    	if ( $data->{'amount'} != $amount ) {
511
    my $offset = 0;
550
            my $diff = $amount - $data->{'amount'};
512
    if ($fine) {
551
	    #3341: diff could be positive or negative!
513
        if (
552
            my $out  = $data->{'amountoutstanding'} + $diff;
514
            sprintf( "%.6f", $fine->amount_original() )
553
            my $query = "
515
            ne
554
                UPDATE accountlines
516
            sprintf( "%.6f", $amount ) )
555
				SET date=now(), amount=?, amountoutstanding=?,
517
        {
556
					lastincrement=?, accounttype='FU'
518
            my $difference = $amount - $fine->amount_original();
557
	  			WHERE borrowernumber=?
519
558
				AND   itemnumber=?
520
            $fine->amount_original( $fine->amount_original() + $difference );
559
				AND   accounttype IN ('FU','O')
521
            $fine->amount_outstanding( $fine->amount_outstanding() + $difference );
560
				AND   description LIKE ?
522
            $fine->amount_last_increment($difference);
561
				LIMIT 1 ";
523
            $fine->updated_on($timestamp);
562
            my $sth2 = $dbh->prepare($query);
524
            $fine->update();
563
			# FIXME: BOGUS query cannot ensure uniqueness w/ LIKE %x% !!!
525
564
			# 		LIMIT 1 added to prevent multiple affected lines
526
            $offset = 1;
565
			# FIXME: accountlines table needs unique key!! Possibly a combo of borrowernumber and accountline.  
566
			# 		But actually, we should just have a regular autoincrementing PK and forget accountline,
567
			# 		including the bogus getnextaccountno function (doesn't prevent conflict on simultaneous ops).
568
			# FIXME: Why only 2 account types here?
569
			$debug and print STDERR "UpdateFine query: $query\n" .
570
				"w/ args: $amount, $out, $diff, $data->{'borrowernumber'}, $data->{'itemnumber'}, \"\%$due\%\"\n";
571
            $sth2->execute($amount, $out, $diff, $data->{'borrowernumber'}, $data->{'itemnumber'}, "%$due%");
572
        } else {
573
            #      print "no update needed $data->{'amount'}"
574
        }
527
        }
575
    } else {
528
    }
576
        my $sth4 = $dbh->prepare(
529
    else {
577
            "SELECT title FROM biblio LEFT JOIN items ON biblio.biblionumber=items.biblionumber WHERE items.itemnumber=?"
530
        my $item = $schema->resultset('Item')->find($itemnumber);
531
532
        $fine = $schema->resultset('AccountDebit')->create(
533
            {
534
                borrowernumber        => $borrowernumber,
535
                itemnumber            => $itemnumber,
536
                issue_id              => $issue_id,
537
                type                  => Koha::Accounts::DebitTypes::Fine(),
538
                accruing              => 1,
539
                amount_original       => $amount,
540
                amount_outstanding    => $amount,
541
                amount_last_increment => $amount,
542
                description           => $item->biblio()->title() . " / Due:$due",
543
                created_on            => $timestamp,
544
            }
578
        );
545
        );
579
        $sth4->execute($itemnum);
546
580
        my $title = $sth4->fetchrow;
547
        $offset = 1;
581
582
#         #   print "not in account";
583
#         my $sth3 = $dbh->prepare("Select max(accountno) from accountlines");
584
#         $sth3->execute;
585
# 
586
#         # FIXME - Make $accountno a scalar.
587
#         my @accountno = $sth3->fetchrow_array;
588
#         $sth3->finish;
589
#         $accountno[0]++;
590
# begin transaction
591
		my $nextaccntno = C4::Accounts::getnextacctno($borrowernumber);
592
		my $desc = ($type ? "$type " : '') . "$title $due";	# FIXEDME, avoid whitespace prefix on empty $type
593
		my $query = "INSERT INTO accountlines
594
		    (borrowernumber,itemnumber,date,amount,description,accounttype,amountoutstanding,lastincrement,accountno)
595
			    VALUES (?,?,now(),?,?,'FU',?,?,?)";
596
		my $sth2 = $dbh->prepare($query);
597
		$debug and print STDERR "UpdateFine query: $query\nw/ args: $borrowernumber, $itemnum, $amount, $desc, $amount, $amount, $nextaccntno\n";
598
        $sth2->execute($borrowernumber, $itemnum, $amount, $desc, $amount, $amount, $nextaccntno);
599
    }
548
    }
600
    # logging action
549
601
    &logaction(
550
    $schema->resultset('AccountOffset')->create(
602
        "FINES",
551
        {
603
        $type,
552
            debit_id   => $fine->debit_id(),
553
            amount     => $fine->amount_last_increment(),
554
            created_on => $timestamp,
555
            type       => Koha::Accounts::OffsetTypes::Fine(),
556
        }
557
    ) if $offset;
558
559
    logaction( "FINES", Koha::Accounts::DebitTypes::Fine(),
604
        $borrowernumber,
560
        $borrowernumber,
605
        "due=".$due."  amount=".$amount." itemnumber=".$itemnum
561
        "due=" . $due . "  amount=" . $amount . " itemnumber=" . $itemnumber )
606
        ) if C4::Context->preference("FinesLog");
562
      if C4::Context->preference("FinesLog");
607
}
563
}
608
564
609
=head2 BorType
565
=head2 BorType
Lines 644-713 C<$borrowernumber> is the borrowernumber Link Here
644
=cut 
600
=cut 
645
601
646
sub GetFine {
602
sub GetFine {
647
    my ( $itemnum, $borrowernumber ) = @_;
603
    my ( $itemnumber, $borrowernumber ) = @_;
648
    my $dbh   = C4::Context->dbh();
649
    my $query = q|SELECT sum(amountoutstanding) as fineamount FROM accountlines
650
    where accounttype like 'F%'
651
  AND amountoutstanding > 0 AND itemnumber = ? AND borrowernumber=?|;
652
    my $sth = $dbh->prepare($query);
653
    $sth->execute( $itemnum, $borrowernumber );
654
    my $fine = $sth->fetchrow_hashref();
655
    if ($fine->{fineamount}) {
656
        return $fine->{fineamount};
657
    }
658
    return 0;
659
}
660
661
=head2 NumberNotifyId
662
604
663
    (@notify) = &NumberNotifyId($borrowernumber);
605
    my $schema = Koha::Database->new()->schema;
664
606
665
Returns amount for all file per borrowers
607
    my $amount_outstanding = $schema->resultset('AccountDebit')->search(
666
C<@notify> array contains all file per borrowers
608
        {
609
            itemnumber     => $itemnumber,
610
            borrowernumber => $borrowernumber,
611
            type           => Koha::Accounts::DebitTypes::Fine(),
612
        },
613
    )->get_column('amount_outstanding')->sum();
667
614
668
C<$notify_id> contains the file number for the borrower number nad item number
615
    return $amount_outstanding;
669
670
=cut
671
672
sub NumberNotifyId{
673
    my ($borrowernumber)=@_;
674
    my $dbh = C4::Context->dbh;
675
    my $query=qq|    SELECT distinct(notify_id)
676
            FROM accountlines
677
            WHERE borrowernumber=?|;
678
    my @notify;
679
    my $sth = $dbh->prepare($query);
680
    $sth->execute($borrowernumber);
681
    while ( my ($numberofnotify) = $sth->fetchrow ) {
682
        push( @notify, $numberofnotify );
683
    }
684
    return (@notify);
685
}
686
687
=head2 AmountNotify
688
689
    ($totalnotify) = &AmountNotify($notifyid);
690
691
Returns amount for all file per borrowers
692
C<$notifyid> is the file number
693
694
C<$totalnotify> contains amount of a file
695
696
C<$notify_id> contains the file number for the borrower number and item number
697
698
=cut
699
700
sub AmountNotify{
701
    my ($notifyid,$borrowernumber)=@_;
702
    my $dbh = C4::Context->dbh;
703
    my $query=qq|    SELECT sum(amountoutstanding)
704
            FROM accountlines
705
            WHERE notify_id=? AND borrowernumber = ?|;
706
    my $sth=$dbh->prepare($query);
707
	$sth->execute($notifyid,$borrowernumber);
708
	my $totalnotify=$sth->fetchrow;
709
    $sth->finish;
710
    return ($totalnotify);
711
}
616
}
712
617
713
=head2 GetItems
618
=head2 GetItems
Lines 759-785 sub GetBranchcodesWithOverdueRules { Link Here
759
    return @branches;
664
    return @branches;
760
}
665
}
761
666
762
=head2 CheckItemNotify
763
764
Sql request to check if the document has alreday been notified
765
this function is not exported, only used with GetOverduesForBranch
766
767
=cut
768
769
sub CheckItemNotify {
770
    my ($notify_id,$notify_level,$itemnumber) = @_;
771
    my $dbh = C4::Context->dbh;
772
    my $sth = $dbh->prepare("
773
    SELECT COUNT(*)
774
     FROM notifys
775
    WHERE notify_id    = ?
776
     AND  notify_level = ? 
777
     AND  itemnumber   = ? ");
778
    $sth->execute($notify_id,$notify_level,$itemnumber);
779
    my $notified = $sth->fetchrow;
780
    return ($notified);
781
}
782
783
=head2 GetOverduesForBranch
667
=head2 GetOverduesForBranch
784
668
785
Sql request for display all information for branchoverdues.pl
669
Sql request for display all information for branchoverdues.pl
Lines 804-809 sub GetOverduesForBranch { Link Here
804
               biblio.title,
688
               biblio.title,
805
               biblio.author,
689
               biblio.author,
806
               biblio.biblionumber,
690
               biblio.biblionumber,
691
               issues.issue_id,
807
               issues.date_due,
692
               issues.date_due,
808
               issues.returndate,
693
               issues.returndate,
809
               issues.branchcode,
694
               issues.branchcode,
Lines 814-838 sub GetOverduesForBranch { Link Here
814
                items.location,
699
                items.location,
815
                items.itemnumber,
700
                items.itemnumber,
816
            itemtypes.description,
701
            itemtypes.description,
817
         accountlines.notify_id,
702
            account_debits.amount_outstanding
818
         accountlines.notify_level,
703
    FROM  account_debits
819
         accountlines.amountoutstanding
704
    LEFT JOIN issues      ON    issues.itemnumber     = account_debits.itemnumber
820
    FROM  accountlines
705
                          AND   issues.borrowernumber = account_debits.borrowernumber
821
    LEFT JOIN issues      ON    issues.itemnumber     = accountlines.itemnumber
706
    LEFT JOIN borrowers   ON borrowers.borrowernumber = account_debits.borrowernumber
822
                          AND   issues.borrowernumber = accountlines.borrowernumber
823
    LEFT JOIN borrowers   ON borrowers.borrowernumber = accountlines.borrowernumber
824
    LEFT JOIN items       ON     items.itemnumber     = issues.itemnumber
707
    LEFT JOIN items       ON     items.itemnumber     = issues.itemnumber
825
    LEFT JOIN biblio      ON      biblio.biblionumber =  items.biblionumber
708
    LEFT JOIN biblio      ON      biblio.biblionumber =  items.biblionumber
826
    LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
709
    LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
827
    LEFT JOIN itemtypes   ON itemtypes.itemtype       = $itype_link
710
    LEFT JOIN itemtypes   ON itemtypes.itemtype       = $itype_link
828
    LEFT JOIN branches    ON  branches.branchcode     = issues.branchcode
711
    LEFT JOIN branches    ON  branches.branchcode     = issues.branchcode
829
    WHERE (accountlines.amountoutstanding  != '0.000000')
712
    WHERE (account_debits.amount_outstanding  != '0.000000')
830
      AND (accountlines.accounttype         = 'FU'      )
713
      AND (account_debits.type = 'FINE')
714
      AND (account_debits.accruing = 1 )
831
      AND (issues.branchcode =  ?   )
715
      AND (issues.branchcode =  ?   )
832
      AND (issues.date_due  < NOW())
716
      AND (issues.date_due  < NOW())
833
    ";
717
    ";
834
    my @getoverdues;
718
    my @getoverdues;
835
    my $i = 0;
836
    my $sth;
719
    my $sth;
837
    if ($location) {
720
    if ($location) {
838
        $sth = $dbh->prepare("$select AND items.location = ? ORDER BY borrowers.surname, borrowers.firstname");
721
        $sth = $dbh->prepare("$select AND items.location = ? ORDER BY borrowers.surname, borrowers.firstname");
Lines 842-853 sub GetOverduesForBranch { Link Here
842
        $sth->execute($branch);
725
        $sth->execute($branch);
843
    }
726
    }
844
    while ( my $data = $sth->fetchrow_hashref ) {
727
    while ( my $data = $sth->fetchrow_hashref ) {
845
    #check if the document has already been notified
728
        push( @getoverdues, $data );
846
        my $countnotify = CheckItemNotify($data->{'notify_id'}, $data->{'notify_level'}, $data->{'itemnumber'});
847
        if ($countnotify eq '0') {
848
            $getoverdues[$i] = $data;
849
            $i++;
850
        }
851
    }
729
    }
852
    return (@getoverdues);
730
    return (@getoverdues);
853
}
731
}
(-)a/C4/Reports/Guided.pm (-10 / +19 lines)
Lines 92-109 my %table_areas = ( Link Here
92
    CAT  => [ 'items', 'biblioitems', 'biblio' ],
92
    CAT  => [ 'items', 'biblioitems', 'biblio' ],
93
    PAT  => ['borrowers'],
93
    PAT  => ['borrowers'],
94
    ACQ  => [ 'aqorders', 'biblio', 'items' ],
94
    ACQ  => [ 'aqorders', 'biblio', 'items' ],
95
    ACC  => [ 'borrowers', 'accountlines' ],
95
    ACC  => [ 'borrowers', 'account_credits', 'account_debits' ],
96
);
96
);
97
my %keys = (
97
my %keys = (
98
    CIRC => [ 'statistics.borrowernumber=borrowers.borrowernumber',
98
    CIRC => [
99
              'items.itemnumber = statistics.itemnumber',
99
        'statistics.borrowernumber=borrowers.borrowernumber',
100
              'biblioitems.biblioitemnumber = items.biblioitemnumber' ],
100
        'items.itemnumber = statistics.itemnumber',
101
    CAT  => [ 'items.biblioitemnumber=biblioitems.biblioitemnumber',
101
        'biblioitems.biblioitemnumber = items.biblioitemnumber'
102
              'biblioitems.biblionumber=biblio.biblionumber' ],
102
    ],
103
    PAT  => [],
103
    CAT => [
104
    ACQ  => [ 'aqorders.biblionumber=biblio.biblionumber',
104
        'items.biblioitemnumber=biblioitems.biblioitemnumber',
105
              'biblio.biblionumber=items.biblionumber' ],
105
        'biblioitems.biblionumber=biblio.biblionumber'
106
    ACC  => ['borrowers.borrowernumber=accountlines.borrowernumber'],
106
    ],
107
    PAT => [],
108
    ACQ => [
109
        'aqorders.biblionumber=biblio.biblionumber',
110
        'biblio.biblionumber=items.biblionumber'
111
    ],
112
    ACC => [
113
        'borrowers.borrowernumber=account_credits.borrowernumber',
114
        'borrowers.borrowernumber=account_debits.borrowernumber'
115
    ],
107
);
116
);
108
117
109
# have to do someting here to know if its dropdown, free text, date etc
118
# have to do someting here to know if its dropdown, free text, date etc
(-)a/C4/Reserves.pm (-13 / +10 lines)
Lines 28-34 use C4::Biblio; Link Here
28
use C4::Members;
28
use C4::Members;
29
use C4::Items;
29
use C4::Items;
30
use C4::Circulation;
30
use C4::Circulation;
31
use C4::Accounts;
32
31
33
# for _koha_notify_reserve
32
# for _koha_notify_reserve
34
use C4::Members::Messaging;
33
use C4::Members::Messaging;
Lines 172-190 sub AddReserve { Link Here
172
        $waitingdate = $resdate;
171
        $waitingdate = $resdate;
173
    }
172
    }
174
173
175
    #eval {
176
    # updates take place here
177
    if ( $fee > 0 ) {
174
    if ( $fee > 0 ) {
178
        my $nextacctno = &getnextacctno( $borrowernumber );
175
        AddDebit(
179
        my $query      = qq/
176
            {
180
        INSERT INTO accountlines
177
                borrowernumber => $borrowernumber,
181
            (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)
178
                itemnumber     => $checkitem,
182
        VALUES
179
                amount         => $fee,
183
            (?,?,now(),?,?,'Res',?)
180
                type           => Koha::Accounts::DebitTypes::Hold(),
184
    /;
181
                description    => "Hold fee - $title",
185
        my $usth = $dbh->prepare($query);
182
                notes          => "Record ID: $biblionumber",
186
        $usth->execute( $borrowernumber, $nextacctno, $fee,
183
            }
187
            "Reserve Charge - $title", $fee );
184
        );
188
    }
185
    }
189
186
190
    #if ($const eq 'a'){
187
    #if ($const eq 'a'){
(-)a/C4/SIP/ILS/Patron.pm (-1 / +1 lines)
Lines 85-91 sub new { Link Here
85
        hold_ok         => ( !$debarred && !$expired ),
85
        hold_ok         => ( !$debarred && !$expired ),
86
        card_lost       => ( $kp->{lost} || $kp->{gonenoaddress} || $flags->{LOST} ),
86
        card_lost       => ( $kp->{lost} || $kp->{gonenoaddress} || $flags->{LOST} ),
87
        claims_returned => 0,
87
        claims_returned => 0,
88
        fines           => $fines_amount, # GetMemberAccountRecords($kp->{borrowernumber})
88
        fines           => $fines_amount,
89
        fees            => 0,             # currently not distinct from fines
89
        fees            => 0,             # currently not distinct from fines
90
        recall_overdue  => 0,
90
        recall_overdue  => 0,
91
        items_billed    => 0,
91
        items_billed    => 0,
(-)a/Koha/Accounts.pm (+535 lines)
Line 0 Link Here
1
package Koha::Accounts;
2
3
# Copyright 2013 ByWater Solutions
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 2 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, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use Carp;
23
use Data::Dumper qw(Dumper);
24
25
use C4::Context;
26
use C4::Log qw(logaction);
27
use Koha::DateUtils qw(get_timestamp);
28
29
use Koha::Accounts::CreditTypes;
30
use Koha::Accounts::DebitTypes;
31
32
use vars qw($VERSION @ISA @EXPORT);
33
34
BEGIN {
35
    require Exporter;
36
    @ISA    = qw(Exporter);
37
    @EXPORT = qw(
38
      AddDebit
39
      AddCredit
40
41
      NormalizeBalances
42
43
      RecalculateAccountBalance
44
45
      DebitLostItem
46
      CreditLostItem
47
    );
48
}
49
50
=head1 NAME
51
52
Koha::Accounts - Functions for dealing with Koha accounts
53
54
=head1 SYNOPSIS
55
56
use Koha::Accounts;
57
58
=head1 DESCRIPTION
59
60
The functions in this module deal with the monetary aspect of Koha,
61
including looking up and modifying the amount of money owed by a
62
patron.
63
64
=head1 FUNCTIONS
65
66
=head2 AddDebit
67
68
my $debit = AddDebit({
69
    borrower       => $borrower,
70
    amount         => $amount,
71
    [ type         => $type,        ]
72
    [ itemnumber   => $itemnumber,  ]
73
    [ issue_id     => $issue_id,    ]
74
    [ description  => $description, ]
75
    [ notes        => $notes,       ]
76
    [ branchcode   => $branchcode,  ]
77
    [ manager_id   => $manager_id,  ]
78
    [ accruing     => $accruing,    ] # Default 0 if not accruing, 1 if accruing
79
});
80
81
Create a new debit for a given borrower. To standardize nomenclature, any charge
82
against a borrower ( e.g. a fine, a new card charge, the cost of losing an item )
83
will be referred to as a 'debit'.
84
85
=cut
86
87
sub AddDebit {
88
    my ($params) = @_;
89
90
    my $borrower = $params->{borrower};
91
    my $amount   = $params->{amount};
92
93
    my $type        = $params->{type};
94
    my $itemnumber  = $params->{itemnumber};
95
    my $issue_id    = $params->{issue_id};
96
    my $description = $params->{description};
97
    my $notes       = $params->{notes};
98
99
    my $branchcode = $params->{branchcode};
100
    $branchcode ||=
101
      defined( C4::Context->userenv )
102
      ? C4::Context->userenv->{branch}
103
      : undef;
104
105
    my $manager_id = $params->{manager_id};
106
    $manager_id ||=
107
      defined( C4::Context->userenv )
108
      ? C4::Context->userenv->{manager_id}
109
      : undef;
110
111
    my $accruing = $params->{accruing} || 0;
112
113
    croak("Required parameter 'borrower' not passed in.")
114
      unless ($borrower);
115
    croak("Required parameter 'amount' not passed in.")
116
      unless ($amount);
117
    croak("Invalid debit type: '$type'!")
118
      unless ( Koha::Accounts::DebitTypes::IsValid($type) );
119
    croak("No issue id passed in for accruing debit!")
120
      if ( $accruing && !$issue_id );
121
122
    my $debit =
123
      Koha::Database->new()->schema->resultset('AccountDebit')->create(
124
        {
125
            borrowernumber        => $borrower->borrowernumber(),
126
            itemnumber            => $itemnumber,
127
            issue_id              => $issue_id,
128
            type                  => $type,
129
            accruing              => $accruing,
130
            amount_original       => $amount,
131
            amount_outstanding    => $amount,
132
            amount_last_increment => $amount,
133
            description           => $description,
134
            notes                 => $notes,
135
            manager_id            => $manager_id,
136
            created_on            => get_timestamp(),
137
        }
138
      );
139
140
    if ($debit) {
141
        $borrower->account_balance( $borrower->account_balance() + $amount );
142
        $borrower->update();
143
144
        NormalizeBalances( { borrower => $borrower } );
145
146
        if ( C4::Context->preference("FinesLog") ) {
147
            logaction( "FINES", "CREATE_FEE", $debit->id,
148
                Dumper( $debit->get_columns() ) );
149
        }
150
    }
151
    else {
152
        carp("Something went wrong! Debit not created!");
153
    }
154
155
    return $debit;
156
}
157
158
=head2 DebitLostItem
159
160
my $debit = DebitLostItem({
161
    borrower       => $borrower,
162
    issue          => $issue,
163
});
164
165
DebitLostItem adds a replacement fee charge for the item
166
of the given issue.
167
168
=cut
169
170
sub DebitLostItem {
171
    my ($params) = @_;
172
173
    my $borrower = $params->{borrower};
174
    my $issue    = $params->{issue};
175
176
    croak("Required param 'borrower' not passed in!") unless ($borrower);
177
    croak("Required param 'issue' not passed in!")    unless ($issue);
178
179
# Don't add lost debit if borrower has already been charged for this lost item before,
180
# for this issue. It seems reasonable that a borrower could lose an item, find and return it,
181
# check it out again, and lose it again, so we should do this based on issue_id, not itemnumber.
182
    unless (
183
        Koha::Database->new()->schema->resultset('AccountDebit')->search(
184
            {
185
                borrowernumber => $borrower->borrowernumber(),
186
                issue_id       => $issue->issue_id(),
187
                type           => Koha::Accounts::DebitTypes::Lost
188
            }
189
        )->count()
190
      )
191
    {
192
        my $item = $issue->item();
193
194
        $params->{accruing}   = 0;
195
        $params->{type}       = Koha::Accounts::DebitTypes::Lost;
196
        $params->{amount}     = $item->replacementprice();
197
        $params->{itemnumber} = $item->itemnumber();
198
        $params->{issue_id}   = $issue->issue_id();
199
200
        #TODO: Shouldn't we have a default replacement price as a syspref?
201
        if ( $params->{amount} ) {
202
            return AddDebit($params);
203
        }
204
        else {
205
            carp("Cannot add lost debit! Item has no replacement price!");
206
        }
207
    }
208
}
209
210
=head2 CreditLostItem
211
212
my $debit = CreditLostItem(
213
    {
214
        borrower => $borrower,
215
        debit    => $debit,
216
    }
217
);
218
219
CreditLostItem creates a payment in the amount equal
220
to the replacement price charge created by DebitLostItem.
221
222
=cut
223
224
sub CreditLostItem {
225
    my ($params) = @_;
226
227
    my $borrower = $params->{borrower};
228
    my $debit    = $params->{debit};
229
230
    croak("Required param 'borrower' not passed in!") unless ($borrower);
231
    croak("Required param 'debit' not passed in!")
232
      unless ($debit);
233
234
    my $item =
235
      Koha::Database->new()->schema->resultset('Item')
236
      ->find( $debit->itemnumber() );
237
    carp("No item found!") unless $item;
238
239
    $params->{type}     = Koha::Accounts::CreditTypes::Found;
240
    $params->{amount}   = $debit->amount_original();
241
    $params->{debit_id} = $debit->debit_id();
242
    $params->{notes}    = "Lost item found: " . $item->barcode();
243
244
    return AddCredit($params);
245
}
246
247
=head2 AddCredit
248
249
AddCredit({
250
    borrower       => $borrower,
251
    amount         => $amount,
252
    [ branchcode   => $branchcode, ]
253
    [ manager_id   => $manager_id, ]
254
    [ debit_id     => $debit_id, ] # The primary debit to be paid
255
    [ notes        => $notes, ]
256
});
257
258
Record credit by a patron. C<$borrowernumber> is the patron's
259
borrower number. C<$credit> is a floating-point number, giving the
260
amount that was paid.
261
262
Amounts owed are paid off oldest first. That is, if the patron has a
263
$1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a credit
264
of $1.50, then the oldest fine will be paid off in full, and $0.50
265
will be credited to the next one.
266
267
debit_id can be passed as a scalar or an array ref to make the passed
268
in debit or debits the first to be credited.
269
270
=cut
271
272
sub AddCredit {
273
    my ($params) = @_;
274
275
    my $type            = $params->{type};
276
    my $borrower        = $params->{borrower};
277
    my $amount          = $params->{amount};
278
    my $amount_received = $params->{amount_received};
279
    my $debit_id        = $params->{debit_id};
280
    my $notes           = $params->{notes};
281
    my $branchcode      = $params->{branchcode};
282
    my $manager_id      = $params->{manager_id};
283
284
    my $userenv = C4::Context->userenv;
285
286
    unless ( $manager_id || $userenv ) {
287
        $manager_id = $userenv->{number};
288
    }
289
290
    unless ( $branchcode || $userenv ) {
291
        $branchcode = $userenv->{branch};
292
    }
293
294
    unless ($borrower) {
295
        croak("Required parameter 'borrower' not passed in");
296
    }
297
    unless ($amount) {
298
        croak("Required parameter amount not passed in");
299
    }
300
301
    unless ( Koha::Accounts::CreditTypes::IsValid($type) ) {
302
        carp("Invalid credit type! Returning without creating credit.");
303
        return;
304
    }
305
306
    unless ($type) {
307
        carp("No type passed in, assuming Payment");
308
        $type = Koha::Accounts::CreditTypes::Payment;
309
    }
310
311
    my $debit =
312
      Koha::Database->new()->schema->resultset('AccountDebit')->find($debit_id);
313
314
    # First, we make the credit. We'll worry about what we paid later on
315
    my $credit =
316
      Koha::Database->new()->schema->resultset('AccountCredit')->create(
317
        {
318
            borrowernumber   => $borrower->borrowernumber(),
319
            type             => $type,
320
            amount_received  => $amount_received,
321
            amount_paid      => $amount,
322
            amount_remaining => $amount,
323
            notes            => $notes,
324
            manager_id       => $manager_id,
325
            created_on       => get_timestamp(),
326
        }
327
      );
328
329
    if ( C4::Context->preference("FinesLog") ) {
330
        logaction( "FINES", "CREATE_PAYMENT", $credit->id,
331
            Dumper( $credit->get_columns() ) );
332
    }
333
334
    $borrower->account_balance( $borrower->account_balance() - $amount );
335
    $borrower->update();
336
337
    # If we are given specific debits, pay those ones first.
338
    if ($debit_id) {
339
        my @debit_ids = ref($debit_id) eq "ARRAY" ? @$debit_id : $debit_id;
340
        foreach my $debit_id (@debit_ids) {
341
            my $debit =
342
              Koha::Database->new()->schema->resultset('AccountDebit')
343
              ->find($debit_id);
344
345
            if ($debit) {
346
                CreditDebit( { credit => $credit, debit => $debit } );
347
            }
348
            else {
349
                carp("Invalid debit_id passed in!");
350
            }
351
        }
352
    }
353
354
    # We still have leftover money, or we weren't given a specific debit to pay
355
    if ( $credit->amount_remaining() > 0 ) {
356
        my @debits =
357
          Koha::Database->new()->schema->resultset('AccountDebit')->search(
358
            {
359
                borrowernumber     => $borrower->borrowernumber(),
360
                amount_outstanding => { '>' => '0' }
361
            }
362
          );
363
364
        foreach my $debit (@debits) {
365
            if ( $credit->amount_remaining() > 0 ) {
366
                CreditDebit(
367
                    {
368
                        credit   => $credit,
369
                        debit    => $debit,
370
                        borrower => $borrower,
371
                        type     => $type,
372
                    }
373
                );
374
            }
375
        }
376
    }
377
378
    return $credit;
379
}
380
381
=head2 CreditDebit
382
383
$account_offset = CreditDebit({
384
    credit => $credit,
385
    debit => $debit,
386
});
387
388
Given a credit and a debit, this subroutine
389
will pay the appropriate amount of the debit,
390
update the debit's amount outstanding, the credit's
391
amout remaining, and create the appropriate account
392
offset.
393
394
=cut
395
396
sub CreditDebit {
397
    my ($params) = @_;
398
399
    my $credit = $params->{credit};
400
    my $debit  = $params->{debit};
401
402
    croak("Required parameter 'credit' not passed in!")
403
      unless $credit;
404
    croak("Required parameter 'debit' not passed in!") unless $debit;
405
406
    my $amount_to_pay =
407
      ( $debit->amount_outstanding() > $credit->amount_remaining() )
408
      ? $credit->amount_remaining()
409
      : $debit->amount_outstanding();
410
411
    if ( $amount_to_pay > 0 ) {
412
        $debit->amount_outstanding(
413
            $debit->amount_outstanding() - $amount_to_pay );
414
        $debit->update();
415
416
        $credit->amount_remaining(
417
            $credit->amount_remaining() - $amount_to_pay );
418
        $credit->update();
419
420
        my $offset =
421
          Koha::Database->new()->schema->resultset('AccountOffset')->create(
422
            {
423
                amount     => $amount_to_pay * -1,
424
                debit_id   => $debit->id(),
425
                credit_id  => $credit->id(),
426
                created_on => get_timestamp(),
427
            }
428
          );
429
430
        if ( C4::Context->preference("FinesLog") ) {
431
            logaction( "FINES", "MODIFY", $offset->id,
432
                Dumper( $offset->get_columns() ) );
433
        }
434
435
        return $offset;
436
    }
437
}
438
439
=head2 RecalculateAccountBalance
440
441
$account_balance = RecalculateAccountBalance({
442
    borrower => $borrower
443
});
444
445
Recalculates a borrower's balance based on the
446
sum of the amount outstanding for the borrower's
447
debits minus the sum of the amount remaining for
448
the borrowers credits.
449
450
TODO: Would it be better to use af.amount_original - ap.amount_paid for any reason?
451
      Or, perhaps calculate both and compare the two, for error checking purposes.
452
=cut
453
454
sub RecalculateAccountBalance {
455
    my ($params) = @_;
456
457
    my $borrower = $params->{borrower};
458
    croak("Requred paramter 'borrower' not passed in!")
459
      unless ($borrower);
460
461
    my $debits =
462
      Koha::Database->new()->schema->resultset('AccountDebit')
463
      ->search( { borrowernumber => $borrower->borrowernumber() } );
464
    my $amount_outstanding = $debits->get_column('amount_outstanding')->sum();
465
466
    my $credits =
467
      Koha::Database->new()->schema->resultset('AccountCredit')
468
      ->search( { borrowernumber => $borrower->borrowernumber() } );
469
    my $amount_remaining = $credits->get_column('amount_remaining')->sum();
470
471
    my $account_balance = $amount_outstanding - $amount_remaining;
472
    $borrower->account_balance($account_balance);
473
    $borrower->update();
474
475
    return $account_balance;
476
}
477
478
=head2 NormalizeBalances
479
480
    $account_balance = NormalizeBalances({ borrower => $borrower });
481
482
    For a given borrower, this subroutine will find all debits
483
    with an outstanding balance and all credits with an unused
484
    amount remaining and will pay those debits with those credits.
485
486
=cut
487
488
sub NormalizeBalances {
489
    my ($params) = @_;
490
491
    my $borrower = $params->{borrower};
492
493
    croak("Required param 'borrower' not passed in!") unless $borrower;
494
495
    my @credits =
496
      Koha::Database->new()->schema->resultset('AccountCredit')->search(
497
        {
498
            borrowernumber   => $borrower->borrowernumber(),
499
            amount_remaining => { '>' => '0' }
500
        }
501
      );
502
503
    return unless @credits;
504
505
    my @debits =
506
      Koha::Database->new()->schema->resultset('AccountDebit')->search(
507
        {
508
            borrowernumber     => $borrower->borrowernumber(),
509
            amount_outstanding => { '>' => '0' }
510
        }
511
      );
512
513
    return unless @debits;
514
515
    foreach my $credit (@credits) {
516
        foreach my $debit (@debits) {
517
            if (   $credit->amount_remaining()
518
                && $debit->amount_outstanding() )
519
            {
520
                CreditDebit( { credit => $credit, debit => $debit } );
521
            }
522
        }
523
    }
524
525
    return RecalculateAccountBalance( { borrower => $borrower } );
526
}
527
528
1;
529
__END__
530
531
=head1 AUTHOR
532
533
Kyle M Hall <kyle@bywatersolutions.com>
534
535
=cut
(-)a/Koha/Accounts/CreditTypes.pm (+117 lines)
Line 0 Link Here
1
package Koha::Accounts::CreditTypes;
2
3
# Copyright 2013 ByWater Solutions
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 2 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, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
=head1 NAME
23
24
Koha::AccountsCreditTypes - Module representing the enumerated data types for account fees
25
26
=head1 SYNOPSIS
27
28
use Koha::Accounts::CreditTypes;
29
30
my $type = Koha::Accounts::CreditTypes::Payment;
31
32
=head1 DESCRIPTION
33
34
The subroutines in this modules act as enumerated data types for the
35
different credit types in Koha ( i.e. payments, writeoffs, etc. )
36
37
=head1 FUNCTIONS
38
39
=head2 IsValid
40
41
This subroutine takes a given string and returns 1 if
42
the string matches one of the data types, and 0 if not.
43
44
FIXME: Perhaps we should use Class::Inspector instead of hard
45
coding the subs? It seems like it would be a major trade off
46
of speed just so we don't update something in two separate places
47
in the same file.
48
49
=cut
50
51
sub IsValid {
52
    my ($string) = @_;
53
54
    my $is_valid =
55
      (      $string eq Koha::Accounts::CreditTypes::Payment()
56
          || $string eq Koha::Accounts::CreditTypes::WriteOff()
57
          || $string eq Koha::Accounts::CreditTypes::Found()
58
          || $string eq Koha::Accounts::CreditTypes::Credit()
59
          || $string eq Koha::Accounts::CreditTypes::Forgiven() );
60
61
    unless ($is_valid) {
62
        $is_valid =
63
          Koha::Database->new()->schema->resultset('AuthorisedValue')
64
          ->count(
65
            { category => 'ACCOUNT_CREDIT', authorised_value => $string } );
66
    }
67
68
    return $is_valid;
69
}
70
71
=head2 Credit
72
73
=cut
74
75
sub Credit {
76
    return 'CREDIT';
77
}
78
79
=head2 Payment
80
81
=cut
82
83
sub Payment {
84
    return 'PAYMENT';
85
}
86
87
=head2 Writeoff
88
89
=cut
90
91
sub WriteOff {
92
    return 'WRITEOFF';
93
}
94
95
=head2 Writeoff
96
97
=cut
98
99
sub Found {
100
    return 'FOUND';
101
}
102
103
=head2 Forgiven
104
105
=cut
106
107
sub Forgiven {
108
    return 'FORGIVEN';
109
}
110
111
1;
112
113
=head1 AUTHOR
114
115
Kyle M Hall <kyle@bywatersolutions.com>
116
117
=cut
(-)a/Koha/Accounts/DebitTypes.pm (+160 lines)
Line 0 Link Here
1
package Koha::Accounts::DebitTypes;
2
3
# Copyright 2013 ByWater Solutions
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 2 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, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
=head1 NAME
23
24
Koha::Accounts::DebitTypes - Module representing an enumerated data type for account fees
25
26
=head1 SYNOPSIS
27
28
use Koha::Accounts::DebitTypes;
29
30
my $type = Koha::Accounts::DebitTypes::Fine;
31
32
=head1 DESCRIPTION
33
34
The subroutines in this modules act as an enumerated data type
35
for debit types ( stored in account_debits.type ) in Koha.
36
37
=head1 FUNCTIONS
38
39
=head2 IsValid
40
41
This subroutine takes a given string and returns 1 if
42
the string matches one of the data types, and 0 if not.
43
44
=cut
45
46
sub IsValid {
47
    my ($string) = @_;
48
49
    my $is_valid =
50
      (      $string eq Koha::Accounts::DebitTypes::Fine()
51
          || $string eq Koha::Accounts::DebitTypes::AccountManagementFee()
52
          || $string eq Koha::Accounts::DebitTypes::Sundry()
53
          || $string eq Koha::Accounts::DebitTypes::Lost()
54
          || $string eq Koha::Accounts::DebitTypes::Hold()
55
          || $string eq Koha::Accounts::DebitTypes::Rental()
56
          || $string eq Koha::Accounts::DebitTypes::NewCard() );
57
58
    unless ($is_valid) {
59
        $is_valid =
60
          Koha::Database->new()->schema->resultset('AuthorisedValue')
61
          ->count( { category => 'MANUAL_INV', authorised_value => $string } );
62
    }
63
64
    return $is_valid;
65
}
66
67
=head2 Fine
68
69
This data type represents a standard fine within Koha.
70
71
A fine still accruing no longer needs to be differiated by type
72
from a fine done accuring. Instead, that differentication is made
73
by which table the fine exists in, account_fees_accruing vs account_fees_accrued.
74
75
In addition, fines can be checked for correctness based on the issue_id
76
they have. A fine in account_fees_accruing should always have a matching
77
issue_id in the issues table. A fine done accruing will almost always have
78
a matching issue_id in the old_issues table. However, in the case of an overdue
79
item with fines that has been renewed, and becomes overdue again, you may have
80
a case where a given issue may have a matching fine in account_fees_accruing and
81
one or more matching fines in account_fees_accrued ( one for each for the first
82
checkout and one each for any subsequent renewals )
83
84
=cut
85
86
sub Fine {
87
    return 'FINE';
88
}
89
90
=head2 AccountManagementFee
91
92
This fee type is usually reserved for payments for library cards,
93
in cases where a library must charge a patron for the ability to
94
check out items.
95
96
=cut
97
98
sub AccountManagementFee {
99
    return 'ACCOUNT_MANAGEMENT_FEE';
100
}
101
102
=head2 Sundry
103
104
This fee type is basically a 'misc' type, and should be used
105
when no other fee type is more appropriate.
106
107
=cut
108
109
sub Sundry {
110
    return 'SUNDRY';
111
}
112
113
=head2 Lost
114
115
This fee type is used when a library charges for lost items.
116
117
=cut
118
119
sub Lost {
120
    return 'LOST';
121
}
122
123
=head2 Hold
124
125
This fee type is used when a library charges for holds.
126
127
=cut
128
129
sub Hold {
130
    return 'HOLD';
131
}
132
133
=head2 Rental
134
135
This fee type is used when a library charges a rental fee for the item type.
136
137
=cut
138
139
sub Rental {
140
    return 'RENTAL';
141
}
142
143
=head2 NewCard
144
145
This fee type is used when a library charges for replacement
146
library cards.
147
148
=cut
149
150
sub NewCard {
151
    return 'NEW_CARD';
152
}
153
154
1;
155
156
=head1 AUTHOR
157
158
Kyle M Hall <kyle@bywatersolutions.com>
159
160
=cut
(-)a/Koha/Accounts/OffsetTypes.pm (+72 lines)
Line 0 Link Here
1
package Koha::Accounts::OffsetTypes;
2
3
# Copyright 2013 ByWater Solutions
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 2 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, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
=head1 NAME
23
24
Koha::AccountsOffsetTypes - Module representing the enumerated data types for account fees
25
26
=head1 SYNOPSIS
27
28
use Koha::Accounts::OffsetTypes;
29
30
my $type = Koha::Accounts::OffsetTypes::Dropbox;
31
32
=head1 DESCRIPTION
33
34
The subroutines in this modules act as enumerated data types for the
35
different automatic offset types in Koha ( i.e. forgiveness, dropbox mode, etc )
36
37
These types are used for account offsets that have no corrosponding account credit,
38
e.g. automatic fine increments, dropbox mode, etc.
39
40
=head1 FUNCTIONS
41
42
=cut
43
44
=head2 Dropbox
45
46
Offset type for automatic fine reductions
47
via dropbox mode.
48
49
=cut
50
51
sub Dropbox {
52
    return 'DROPBOX';
53
}
54
55
=head2 Fine
56
57
Indicates this offset was an automatically
58
generated fine increment/decrement.
59
60
=cut
61
62
sub Fine {
63
    return 'FINE';
64
}
65
66
1;
67
68
=head1 AUTHOR
69
70
Kyle M Hall <kyle@bywatersolutions.com>
71
72
=cut
(-)a/Koha/DateUtils.pm (-1 / +6 lines)
Lines 21-33 use warnings; Link Here
21
use 5.010;
21
use 5.010;
22
use DateTime;
22
use DateTime;
23
use DateTime::Format::DateParse;
23
use DateTime::Format::DateParse;
24
use DateTime::Format::MySQL;
24
use C4::Context;
25
use C4::Context;
25
26
26
use base 'Exporter';
27
use base 'Exporter';
27
use version; our $VERSION = qv('1.0.0');
28
use version; our $VERSION = qv('1.0.0');
28
29
29
our @EXPORT = (
30
our @EXPORT = (
30
    qw( dt_from_string output_pref format_sqldatetime output_pref_due format_sqlduedatetime)
31
    qw( dt_from_string output_pref format_sqldatetime output_pref_due format_sqlduedatetime get_timestamp )
31
);
32
);
32
33
33
=head1 DateUtils
34
=head1 DateUtils
Lines 239-242 sub format_sqlduedatetime { Link Here
239
    return q{};
240
    return q{};
240
}
241
}
241
242
243
sub get_timestamp {
244
    return DateTime::Format::MySQL->format_datetime( dt_from_string() );
245
}
246
242
1;
247
1;
(-)a/Koha/Schema/Result/AccountCredit.pm (+148 lines)
Line 0 Link Here
1
package Koha::Schema::Result::AccountCredit;
2
3
# Created by DBIx::Class::Schema::Loader
4
# DO NOT MODIFY THE FIRST PART OF THIS FILE
5
6
use strict;
7
use warnings;
8
9
use base 'DBIx::Class::Core';
10
11
12
=head1 NAME
13
14
Koha::Schema::Result::AccountCredit
15
16
=cut
17
18
__PACKAGE__->table("account_credits");
19
20
=head1 ACCESSORS
21
22
=head2 credit_id
23
24
  data_type: 'integer'
25
  is_auto_increment: 1
26
  is_nullable: 0
27
28
=head2 borrowernumber
29
30
  data_type: 'integer'
31
  is_foreign_key: 1
32
  is_nullable: 0
33
34
=head2 type
35
36
  data_type: 'varchar'
37
  is_nullable: 0
38
  size: 255
39
40
=head2 amount_received
41
42
  data_type: 'decimal'
43
  is_nullable: 1
44
  size: [28,6]
45
46
=head2 amount_paid
47
48
  data_type: 'decimal'
49
  is_nullable: 0
50
  size: [28,6]
51
52
=head2 amount_remaining
53
54
  data_type: 'decimal'
55
  is_nullable: 0
56
  size: [28,6]
57
58
=head2 notes
59
60
  data_type: 'text'
61
  is_nullable: 1
62
63
=head2 manager_id
64
65
  data_type: 'integer'
66
  is_nullable: 1
67
68
=head2 created_on
69
70
  data_type: 'timestamp'
71
  is_nullable: 1
72
73
=head2 updated_on
74
75
  data_type: 'timestamp'
76
  is_nullable: 1
77
78
=cut
79
80
__PACKAGE__->add_columns(
81
  "credit_id",
82
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
83
  "borrowernumber",
84
  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
85
  "type",
86
  { data_type => "varchar", is_nullable => 0, size => 255 },
87
  "amount_received",
88
  { data_type => "decimal", is_nullable => 1, size => [28, 6] },
89
  "amount_paid",
90
  { data_type => "decimal", is_nullable => 0, size => [28, 6] },
91
  "amount_remaining",
92
  { data_type => "decimal", is_nullable => 0, size => [28, 6] },
93
  "notes",
94
  { data_type => "text", is_nullable => 1 },
95
  "manager_id",
96
  { data_type => "integer", is_nullable => 1 },
97
  "created_on",
98
  { data_type => "timestamp", is_nullable => 1 },
99
  "updated_on",
100
  { data_type => "timestamp", is_nullable => 1 },
101
);
102
__PACKAGE__->set_primary_key("credit_id");
103
104
=head1 RELATIONS
105
106
=head2 borrowernumber
107
108
Type: belongs_to
109
110
Related object: L<Koha::Schema::Result::Borrower>
111
112
=cut
113
114
__PACKAGE__->belongs_to(
115
  "borrowernumber",
116
  "Koha::Schema::Result::Borrower",
117
  { borrowernumber => "borrowernumber" },
118
  { on_delete => "CASCADE", on_update => "CASCADE" },
119
);
120
121
=head2 account_offsets
122
123
Type: has_many
124
125
Related object: L<Koha::Schema::Result::AccountOffset>
126
127
=cut
128
129
__PACKAGE__->has_many(
130
  "account_offsets",
131
  "Koha::Schema::Result::AccountOffset",
132
  { "foreign.credit_id" => "self.credit_id" },
133
  { cascade_copy => 0, cascade_delete => 0 },
134
);
135
136
137
# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-11-25 14:00:11
138
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:UA9pxIe/9NzHIESDZqCpVw
139
140
__PACKAGE__->belongs_to(
141
  "borrower",
142
  "Koha::Schema::Result::Borrower",
143
  { borrowernumber => "borrowernumber" },
144
);
145
146
147
# You can replace this text with custom content, and it will be preserved on regeneration
148
1;
(-)a/Koha/Schema/Result/AccountDebit.pm (+207 lines)
Line 0 Link Here
1
package Koha::Schema::Result::AccountDebit;
2
3
# Created by DBIx::Class::Schema::Loader
4
# DO NOT MODIFY THE FIRST PART OF THIS FILE
5
6
use strict;
7
use warnings;
8
9
use base 'DBIx::Class::Core';
10
11
12
=head1 NAME
13
14
Koha::Schema::Result::AccountDebit
15
16
=cut
17
18
__PACKAGE__->table("account_debits");
19
20
=head1 ACCESSORS
21
22
=head2 debit_id
23
24
  data_type: 'integer'
25
  is_auto_increment: 1
26
  is_nullable: 0
27
28
=head2 borrowernumber
29
30
  data_type: 'integer'
31
  default_value: 0
32
  is_foreign_key: 1
33
  is_nullable: 0
34
35
=head2 itemnumber
36
37
  data_type: 'integer'
38
  is_nullable: 1
39
40
=head2 issue_id
41
42
  data_type: 'integer'
43
  is_nullable: 1
44
45
=head2 type
46
47
  data_type: 'varchar'
48
  is_nullable: 0
49
  size: 255
50
51
=head2 accruing
52
53
  data_type: 'tinyint'
54
  default_value: 0
55
  is_nullable: 0
56
57
=head2 amount_original
58
59
  data_type: 'decimal'
60
  is_nullable: 1
61
  size: [28,6]
62
63
=head2 amount_outstanding
64
65
  data_type: 'decimal'
66
  is_nullable: 1
67
  size: [28,6]
68
69
=head2 amount_last_increment
70
71
  data_type: 'decimal'
72
  is_nullable: 1
73
  size: [28,6]
74
75
=head2 description
76
77
  data_type: 'mediumtext'
78
  is_nullable: 1
79
80
=head2 notes
81
82
  data_type: 'text'
83
  is_nullable: 1
84
85
=head2 manager_id
86
87
  data_type: 'integer'
88
  is_nullable: 1
89
90
=head2 created_on
91
92
  data_type: 'timestamp'
93
  is_nullable: 1
94
95
=head2 updated_on
96
97
  data_type: 'timestamp'
98
  is_nullable: 1
99
100
=cut
101
102
__PACKAGE__->add_columns(
103
  "debit_id",
104
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
105
  "borrowernumber",
106
  {
107
    data_type      => "integer",
108
    default_value  => 0,
109
    is_foreign_key => 1,
110
    is_nullable    => 0,
111
  },
112
  "itemnumber",
113
  { data_type => "integer", is_nullable => 1 },
114
  "issue_id",
115
  { data_type => "integer", is_nullable => 1 },
116
  "type",
117
  { data_type => "varchar", is_nullable => 0, size => 255 },
118
  "accruing",
119
  { data_type => "tinyint", default_value => 0, is_nullable => 0 },
120
  "amount_original",
121
  { data_type => "decimal", is_nullable => 1, size => [28, 6] },
122
  "amount_outstanding",
123
  { data_type => "decimal", is_nullable => 1, size => [28, 6] },
124
  "amount_last_increment",
125
  { data_type => "decimal", is_nullable => 1, size => [28, 6] },
126
  "description",
127
  { data_type => "mediumtext", is_nullable => 1 },
128
  "notes",
129
  { data_type => "text", is_nullable => 1 },
130
  "manager_id",
131
  { data_type => "integer", is_nullable => 1 },
132
  "created_on",
133
  { data_type => "timestamp", is_nullable => 1 },
134
  "updated_on",
135
  { data_type => "timestamp", is_nullable => 1 },
136
);
137
__PACKAGE__->set_primary_key("debit_id");
138
139
=head1 RELATIONS
140
141
=head2 borrowernumber
142
143
Type: belongs_to
144
145
Related object: L<Koha::Schema::Result::Borrower>
146
147
=cut
148
149
__PACKAGE__->belongs_to(
150
  "borrowernumber",
151
  "Koha::Schema::Result::Borrower",
152
  { borrowernumber => "borrowernumber" },
153
  { on_delete => "CASCADE", on_update => "CASCADE" },
154
);
155
156
=head2 account_offsets
157
158
Type: has_many
159
160
Related object: L<Koha::Schema::Result::AccountOffset>
161
162
=cut
163
164
__PACKAGE__->has_many(
165
  "account_offsets",
166
  "Koha::Schema::Result::AccountOffset",
167
  { "foreign.debit_id" => "self.debit_id" },
168
  { cascade_copy => 0, cascade_delete => 0 },
169
);
170
171
172
# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-11-05 08:09:09
173
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ulQStZJSzcD4hvrPbtew4g
174
175
__PACKAGE__->belongs_to(
176
  "item",
177
  "Koha::Schema::Result::Item",
178
  { itemnumber => "itemnumber" }
179
);
180
181
__PACKAGE__->belongs_to(
182
  "deleted_item",
183
  "Koha::Schema::Result::Deleteditem",
184
  { itemnumber => "itemnumber" }
185
);
186
187
__PACKAGE__->belongs_to(
188
  "issue",
189
  "Koha::Schema::Result::Issue",
190
  { issue_id => "issue_id" }
191
);
192
193
__PACKAGE__->belongs_to(
194
  "old_issue",
195
  "Koha::Schema::Result::OldIssue",
196
  { issue_id => "issue_id" }
197
);
198
199
__PACKAGE__->belongs_to(
200
  "borrower",
201
  "Koha::Schema::Result::Borrower",
202
  { borrowernumber => "borrowernumber" },
203
  { on_delete => "CASCADE", on_update => "CASCADE" },
204
);
205
206
# You can replace this text with custom content, and it will be preserved on regeneration
207
1;
(-)a/Koha/Schema/Result/AccountOffset.pm (+118 lines)
Line 0 Link Here
1
package Koha::Schema::Result::AccountOffset;
2
3
# Created by DBIx::Class::Schema::Loader
4
# DO NOT MODIFY THE FIRST PART OF THIS FILE
5
6
use strict;
7
use warnings;
8
9
use base 'DBIx::Class::Core';
10
11
12
=head1 NAME
13
14
Koha::Schema::Result::AccountOffset
15
16
=cut
17
18
__PACKAGE__->table("account_offsets");
19
20
=head1 ACCESSORS
21
22
=head2 offset_id
23
24
  data_type: 'integer'
25
  is_auto_increment: 1
26
  is_nullable: 0
27
28
=head2 debit_id
29
30
  data_type: 'integer'
31
  is_foreign_key: 1
32
  is_nullable: 1
33
34
=head2 credit_id
35
36
  data_type: 'integer'
37
  is_foreign_key: 1
38
  is_nullable: 1
39
40
=head2 type
41
42
  data_type: 'varchar'
43
  is_nullable: 1
44
  size: 255
45
46
=head2 amount
47
48
  data_type: 'decimal'
49
  is_nullable: 0
50
  size: [28,6]
51
52
=head2 created_on
53
54
  data_type: 'timestamp'
55
  default_value: current_timestamp
56
  is_nullable: 0
57
58
=cut
59
60
__PACKAGE__->add_columns(
61
  "offset_id",
62
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
63
  "debit_id",
64
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
65
  "credit_id",
66
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
67
  "type",
68
  { data_type => "varchar", is_nullable => 1, size => 255 },
69
  "amount",
70
  { data_type => "decimal", is_nullable => 0, size => [28, 6] },
71
  "created_on",
72
  {
73
    data_type     => "timestamp",
74
    default_value => \"current_timestamp",
75
    is_nullable   => 0,
76
  },
77
);
78
__PACKAGE__->set_primary_key("offset_id");
79
80
=head1 RELATIONS
81
82
=head2 debit
83
84
Type: belongs_to
85
86
Related object: L<Koha::Schema::Result::AccountDebit>
87
88
=cut
89
90
__PACKAGE__->belongs_to(
91
  "debit",
92
  "Koha::Schema::Result::AccountDebit",
93
  { debit_id => "debit_id" },
94
  { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" },
95
);
96
97
=head2 credit
98
99
Type: belongs_to
100
101
Related object: L<Koha::Schema::Result::AccountCredit>
102
103
=cut
104
105
__PACKAGE__->belongs_to(
106
  "credit",
107
  "Koha::Schema::Result::AccountCredit",
108
  { credit_id => "credit_id" },
109
  { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" },
110
);
111
112
113
# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-11-05 08:47:10
114
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BLjpL8skXmzxOQ/J0jzdvw
115
116
117
# You can replace this text with custom content, and it will be preserved on regeneration
118
1;
(-)a/Koha/Schema/Result/Accountline.pm (-222 lines)
Lines 1-222 Link Here
1
use utf8;
2
package Koha::Schema::Result::Accountline;
3
4
# Created by DBIx::Class::Schema::Loader
5
# DO NOT MODIFY THE FIRST PART OF THIS FILE
6
7
=head1 NAME
8
9
Koha::Schema::Result::Accountline
10
11
=cut
12
13
use strict;
14
use warnings;
15
16
use base 'DBIx::Class::Core';
17
18
=head1 TABLE: C<accountlines>
19
20
=cut
21
22
__PACKAGE__->table("accountlines");
23
24
=head1 ACCESSORS
25
26
=head2 accountlines_id
27
28
  data_type: 'integer'
29
  is_auto_increment: 1
30
  is_nullable: 0
31
32
=head2 borrowernumber
33
34
  data_type: 'integer'
35
  default_value: 0
36
  is_foreign_key: 1
37
  is_nullable: 0
38
39
=head2 accountno
40
41
  data_type: 'smallint'
42
  default_value: 0
43
  is_nullable: 0
44
45
=head2 itemnumber
46
47
  data_type: 'integer'
48
  is_foreign_key: 1
49
  is_nullable: 1
50
51
=head2 date
52
53
  data_type: 'date'
54
  datetime_undef_if_invalid: 1
55
  is_nullable: 1
56
57
=head2 amount
58
59
  data_type: 'decimal'
60
  is_nullable: 1
61
  size: [28,6]
62
63
=head2 description
64
65
  data_type: 'mediumtext'
66
  is_nullable: 1
67
68
=head2 dispute
69
70
  data_type: 'mediumtext'
71
  is_nullable: 1
72
73
=head2 accounttype
74
75
  data_type: 'varchar'
76
  is_nullable: 1
77
  size: 5
78
79
=head2 amountoutstanding
80
81
  data_type: 'decimal'
82
  is_nullable: 1
83
  size: [28,6]
84
85
=head2 lastincrement
86
87
  data_type: 'decimal'
88
  is_nullable: 1
89
  size: [28,6]
90
91
=head2 timestamp
92
93
  data_type: 'timestamp'
94
  datetime_undef_if_invalid: 1
95
  default_value: current_timestamp
96
  is_nullable: 0
97
98
=head2 notify_id
99
100
  data_type: 'integer'
101
  default_value: 0
102
  is_nullable: 0
103
104
=head2 notify_level
105
106
  data_type: 'integer'
107
  default_value: 0
108
  is_nullable: 0
109
110
=head2 note
111
112
  data_type: 'text'
113
  is_nullable: 1
114
115
=head2 manager_id
116
117
  data_type: 'integer'
118
  is_nullable: 1
119
120
=cut
121
122
__PACKAGE__->add_columns(
123
  "accountlines_id",
124
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
125
  "borrowernumber",
126
  {
127
    data_type      => "integer",
128
    default_value  => 0,
129
    is_foreign_key => 1,
130
    is_nullable    => 0,
131
  },
132
  "accountno",
133
  { data_type => "smallint", default_value => 0, is_nullable => 0 },
134
  "itemnumber",
135
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
136
  "date",
137
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
138
  "amount",
139
  { data_type => "decimal", is_nullable => 1, size => [28, 6] },
140
  "description",
141
  { data_type => "mediumtext", is_nullable => 1 },
142
  "dispute",
143
  { data_type => "mediumtext", is_nullable => 1 },
144
  "accounttype",
145
  { data_type => "varchar", is_nullable => 1, size => 5 },
146
  "amountoutstanding",
147
  { data_type => "decimal", is_nullable => 1, size => [28, 6] },
148
  "lastincrement",
149
  { data_type => "decimal", is_nullable => 1, size => [28, 6] },
150
  "timestamp",
151
  {
152
    data_type => "timestamp",
153
    datetime_undef_if_invalid => 1,
154
    default_value => \"current_timestamp",
155
    is_nullable => 0,
156
  },
157
  "notify_id",
158
  { data_type => "integer", default_value => 0, is_nullable => 0 },
159
  "notify_level",
160
  { data_type => "integer", default_value => 0, is_nullable => 0 },
161
  "note",
162
  { data_type => "text", is_nullable => 1 },
163
  "manager_id",
164
  { data_type => "integer", is_nullable => 1 },
165
);
166
167
=head1 PRIMARY KEY
168
169
=over 4
170
171
=item * L</accountlines_id>
172
173
=back
174
175
=cut
176
177
__PACKAGE__->set_primary_key("accountlines_id");
178
179
=head1 RELATIONS
180
181
=head2 borrowernumber
182
183
Type: belongs_to
184
185
Related object: L<Koha::Schema::Result::Borrower>
186
187
=cut
188
189
__PACKAGE__->belongs_to(
190
  "borrowernumber",
191
  "Koha::Schema::Result::Borrower",
192
  { borrowernumber => "borrowernumber" },
193
  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
194
);
195
196
=head2 itemnumber
197
198
Type: belongs_to
199
200
Related object: L<Koha::Schema::Result::Item>
201
202
=cut
203
204
__PACKAGE__->belongs_to(
205
  "itemnumber",
206
  "Koha::Schema::Result::Item",
207
  { itemnumber => "itemnumber" },
208
  {
209
    is_deferrable => 1,
210
    join_type     => "LEFT",
211
    on_delete     => "CASCADE",
212
    on_update     => "CASCADE",
213
  },
214
);
215
216
217
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21
218
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:VLEuOBmnS+xgk7LXAqxtLw
219
220
221
# You can replace this text with custom content, and it will be preserved on regeneration
222
1;
(-)a/Koha/Schema/Result/Accountoffset.pm (-106 lines)
Lines 1-106 Link Here
1
use utf8;
2
package Koha::Schema::Result::Accountoffset;
3
4
# Created by DBIx::Class::Schema::Loader
5
# DO NOT MODIFY THE FIRST PART OF THIS FILE
6
7
=head1 NAME
8
9
Koha::Schema::Result::Accountoffset
10
11
=cut
12
13
use strict;
14
use warnings;
15
16
use base 'DBIx::Class::Core';
17
18
=head1 TABLE: C<accountoffsets>
19
20
=cut
21
22
__PACKAGE__->table("accountoffsets");
23
24
=head1 ACCESSORS
25
26
=head2 borrowernumber
27
28
  data_type: 'integer'
29
  default_value: 0
30
  is_foreign_key: 1
31
  is_nullable: 0
32
33
=head2 accountno
34
35
  data_type: 'smallint'
36
  default_value: 0
37
  is_nullable: 0
38
39
=head2 offsetaccount
40
41
  data_type: 'smallint'
42
  default_value: 0
43
  is_nullable: 0
44
45
=head2 offsetamount
46
47
  data_type: 'decimal'
48
  is_nullable: 1
49
  size: [28,6]
50
51
=head2 timestamp
52
53
  data_type: 'timestamp'
54
  datetime_undef_if_invalid: 1
55
  default_value: current_timestamp
56
  is_nullable: 0
57
58
=cut
59
60
__PACKAGE__->add_columns(
61
  "borrowernumber",
62
  {
63
    data_type      => "integer",
64
    default_value  => 0,
65
    is_foreign_key => 1,
66
    is_nullable    => 0,
67
  },
68
  "accountno",
69
  { data_type => "smallint", default_value => 0, is_nullable => 0 },
70
  "offsetaccount",
71
  { data_type => "smallint", default_value => 0, is_nullable => 0 },
72
  "offsetamount",
73
  { data_type => "decimal", is_nullable => 1, size => [28, 6] },
74
  "timestamp",
75
  {
76
    data_type => "timestamp",
77
    datetime_undef_if_invalid => 1,
78
    default_value => \"current_timestamp",
79
    is_nullable => 0,
80
  },
81
);
82
83
=head1 RELATIONS
84
85
=head2 borrowernumber
86
87
Type: belongs_to
88
89
Related object: L<Koha::Schema::Result::Borrower>
90
91
=cut
92
93
__PACKAGE__->belongs_to(
94
  "borrowernumber",
95
  "Koha::Schema::Result::Borrower",
96
  { borrowernumber => "borrowernumber" },
97
  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
98
);
99
100
101
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21
102
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:OTfcUiJCPb5aU/gjqAb/bA
103
104
105
# You can replace this text with custom content, and it will be preserved on regeneration
106
1;
(-)a/Koha/Schema/Result/Borrower.pm (-75 / +62 lines)
Lines 1-21 Link Here
1
use utf8;
2
package Koha::Schema::Result::Borrower;
1
package Koha::Schema::Result::Borrower;
3
2
4
# Created by DBIx::Class::Schema::Loader
3
# Created by DBIx::Class::Schema::Loader
5
# DO NOT MODIFY THE FIRST PART OF THIS FILE
4
# DO NOT MODIFY THE FIRST PART OF THIS FILE
6
5
7
=head1 NAME
8
9
Koha::Schema::Result::Borrower
10
11
=cut
12
13
use strict;
6
use strict;
14
use warnings;
7
use warnings;
15
8
16
use base 'DBIx::Class::Core';
9
use base 'DBIx::Class::Core';
17
10
18
=head1 TABLE: C<borrowers>
11
12
=head1 NAME
13
14
Koha::Schema::Result::Borrower
19
15
20
=cut
16
=cut
21
17
Lines 191-197 __PACKAGE__->table("borrowers"); Link Here
191
=head2 dateofbirth
187
=head2 dateofbirth
192
188
193
  data_type: 'date'
189
  data_type: 'date'
194
  datetime_undef_if_invalid: 1
195
  is_nullable: 1
190
  is_nullable: 1
196
191
197
=head2 branchcode
192
=head2 branchcode
Lines 213-225 __PACKAGE__->table("borrowers"); Link Here
213
=head2 dateenrolled
208
=head2 dateenrolled
214
209
215
  data_type: 'date'
210
  data_type: 'date'
216
  datetime_undef_if_invalid: 1
217
  is_nullable: 1
211
  is_nullable: 1
218
212
219
=head2 dateexpiry
213
=head2 dateexpiry
220
214
221
  data_type: 'date'
215
  data_type: 'date'
222
  datetime_undef_if_invalid: 1
223
  is_nullable: 1
216
  is_nullable: 1
224
217
225
=head2 gonenoaddress
218
=head2 gonenoaddress
Lines 235-241 __PACKAGE__->table("borrowers"); Link Here
235
=head2 debarred
228
=head2 debarred
236
229
237
  data_type: 'date'
230
  data_type: 'date'
238
  datetime_undef_if_invalid: 1
239
  is_nullable: 1
231
  is_nullable: 1
240
232
241
=head2 debarredcomment
233
=head2 debarredcomment
Lines 397-402 __PACKAGE__->table("borrowers"); Link Here
397
  default_value: 1
389
  default_value: 1
398
  is_nullable: 0
390
  is_nullable: 0
399
391
392
=head2 account_balance
393
394
  data_type: 'decimal'
395
  default_value: 0.000000
396
  is_nullable: 0
397
  size: [28,6]
398
400
=cut
399
=cut
401
400
402
__PACKAGE__->add_columns(
401
__PACKAGE__->add_columns(
Lines 463-469 __PACKAGE__->add_columns( Link Here
463
  "b_phone",
462
  "b_phone",
464
  { data_type => "mediumtext", is_nullable => 1 },
463
  { data_type => "mediumtext", is_nullable => 1 },
465
  "dateofbirth",
464
  "dateofbirth",
466
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
465
  { data_type => "date", is_nullable => 1 },
467
  "branchcode",
466
  "branchcode",
468
  {
467
  {
469
    data_type => "varchar",
468
    data_type => "varchar",
Lines 481-495 __PACKAGE__->add_columns( Link Here
481
    size => 10,
480
    size => 10,
482
  },
481
  },
483
  "dateenrolled",
482
  "dateenrolled",
484
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
483
  { data_type => "date", is_nullable => 1 },
485
  "dateexpiry",
484
  "dateexpiry",
486
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
485
  { data_type => "date", is_nullable => 1 },
487
  "gonenoaddress",
486
  "gonenoaddress",
488
  { data_type => "tinyint", is_nullable => 1 },
487
  { data_type => "tinyint", is_nullable => 1 },
489
  "lost",
488
  "lost",
490
  { data_type => "tinyint", is_nullable => 1 },
489
  { data_type => "tinyint", is_nullable => 1 },
491
  "debarred",
490
  "debarred",
492
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
491
  { data_type => "date", is_nullable => 1 },
493
  "debarredcomment",
492
  "debarredcomment",
494
  { data_type => "varchar", is_nullable => 1, size => 255 },
493
  { data_type => "varchar", is_nullable => 1, size => 255 },
495
  "contactname",
494
  "contactname",
Lines 546-580 __PACKAGE__->add_columns( Link Here
546
  { data_type => "varchar", is_nullable => 1, size => 50 },
545
  { data_type => "varchar", is_nullable => 1, size => 50 },
547
  "privacy",
546
  "privacy",
548
  { data_type => "integer", default_value => 1, is_nullable => 0 },
547
  { data_type => "integer", default_value => 1, is_nullable => 0 },
548
  "account_balance",
549
  {
550
    data_type => "decimal",
551
    default_value => "0.000000",
552
    is_nullable => 0,
553
    size => [28, 6],
554
  },
549
);
555
);
556
__PACKAGE__->set_primary_key("borrowernumber");
557
__PACKAGE__->add_unique_constraint("cardnumber", ["cardnumber"]);
550
558
551
=head1 PRIMARY KEY
559
=head1 RELATIONS
552
560
553
=over 4
561
=head2 account_credits
554
562
555
=item * L</borrowernumber>
563
Type: has_many
556
564
557
=back
565
Related object: L<Koha::Schema::Result::AccountCredit>
558
566
559
=cut
567
=cut
560
568
561
__PACKAGE__->set_primary_key("borrowernumber");
569
__PACKAGE__->has_many(
562
570
  "account_credits",
563
=head1 UNIQUE CONSTRAINTS
571
  "Koha::Schema::Result::AccountCredit",
564
572
  { "foreign.borrowernumber" => "self.borrowernumber" },
565
=head2 C<cardnumber>
573
  { cascade_copy => 0, cascade_delete => 0 },
574
);
566
575
567
=over 4
576
=head2 account_debits
568
577
569
=item * L</cardnumber>
578
Type: has_many
570
579
571
=back
580
Related object: L<Koha::Schema::Result::AccountDebit>
572
581
573
=cut
582
=cut
574
583
575
__PACKAGE__->add_unique_constraint("cardnumber", ["cardnumber"]);
584
__PACKAGE__->has_many(
576
585
  "account_debits",
577
=head1 RELATIONS
586
  "Koha::Schema::Result::AccountDebit",
587
  { "foreign.borrowernumber" => "self.borrowernumber" },
588
  { cascade_copy => 0, cascade_delete => 0 },
589
);
578
590
579
=head2 accountlines
591
=head2 accountlines
580
592
Lines 696-729 __PACKAGE__->has_many( Link Here
696
  { cascade_copy => 0, cascade_delete => 0 },
708
  { cascade_copy => 0, cascade_delete => 0 },
697
);
709
);
698
710
699
=head2 branchcode
711
=head2 categorycode
700
712
701
Type: belongs_to
713
Type: belongs_to
702
714
703
Related object: L<Koha::Schema::Result::Branch>
715
Related object: L<Koha::Schema::Result::Category>
704
716
705
=cut
717
=cut
706
718
707
__PACKAGE__->belongs_to(
719
__PACKAGE__->belongs_to(
708
  "branchcode",
720
  "categorycode",
709
  "Koha::Schema::Result::Branch",
721
  "Koha::Schema::Result::Category",
710
  { branchcode => "branchcode" },
722
  { categorycode => "categorycode" },
711
  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
723
  { on_delete => "CASCADE", on_update => "CASCADE" },
712
);
724
);
713
725
714
=head2 categorycode
726
=head2 branchcode
715
727
716
Type: belongs_to
728
Type: belongs_to
717
729
718
Related object: L<Koha::Schema::Result::Category>
730
Related object: L<Koha::Schema::Result::Branch>
719
731
720
=cut
732
=cut
721
733
722
__PACKAGE__->belongs_to(
734
__PACKAGE__->belongs_to(
723
  "categorycode",
735
  "branchcode",
724
  "Koha::Schema::Result::Category",
736
  "Koha::Schema::Result::Branch",
725
  { categorycode => "categorycode" },
737
  { branchcode => "branchcode" },
726
  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
738
  { on_delete => "CASCADE", on_update => "CASCADE" },
727
);
739
);
728
740
729
=head2 course_instructors
741
=head2 course_instructors
Lines 1041-1080 __PACKAGE__->has_many( Link Here
1041
  { cascade_copy => 0, cascade_delete => 0 },
1053
  { cascade_copy => 0, cascade_delete => 0 },
1042
);
1054
);
1043
1055
1044
=head2 basketnoes
1045
1046
Type: many_to_many
1047
1048
Composing rels: L</aqbasketusers> -> basketno
1049
1050
=cut
1051
1052
__PACKAGE__->many_to_many("basketnoes", "aqbasketusers", "basketno");
1053
1054
=head2 budgets
1055
1056
Type: many_to_many
1057
1058
Composing rels: L</aqbudgetborrowers> -> budget
1059
1060
=cut
1061
1062
__PACKAGE__->many_to_many("budgets", "aqbudgetborrowers", "budget");
1063
1064
=head2 courses
1065
1066
Type: many_to_many
1067
1056
1068
Composing rels: L</course_instructors> -> course
1057
# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-11-12 08:27:25
1069
1058
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:CcXsGi7pVHQtO+YH3pY/1A
1070
=cut
1071
1072
__PACKAGE__->many_to_many("courses", "course_instructors", "course");
1073
1074
1075
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-31 16:31:19
1076
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:z4kW3xYX1CyrwvGdZu32nA
1077
1059
1060
__PACKAGE__->belongs_to(
1061
  "branch",
1062
  "Koha::Schema::Result::Branch",
1063
  { branchcode => "branchcode" },
1064
);
1078
1065
1079
# You can replace this text with custom content, and it will be preserved on regeneration
1066
# You can replace this text with custom content, and it will be preserved on regeneration
1080
1;
1067
1;
(-)a/Koha/Schema/Result/Deleteditem.pm (+11 lines)
Lines 366-371 __PACKAGE__->set_primary_key("itemnumber"); Link Here
366
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-11-27 17:52:57
366
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-11-27 17:52:57
367
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:VssrrcYczPsiDBrtbsipIw
367
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:VssrrcYczPsiDBrtbsipIw
368
368
369
__PACKAGE__->belongs_to(
370
  "biblio",
371
  "Koha::Schema::Result::Biblio",
372
  { biblionumber => "biblionumber" }
373
);
374
375
__PACKAGE__->belongs_to(
376
  "deleted_biblio",
377
  "Koha::Schema::Result::Deletedbiblio",
378
  { biblionumber => "biblionumber" }
379
);
369
380
370
# You can replace this text with custom content, and it will be preserved on regeneration
381
# You can replace this text with custom content, and it will be preserved on regeneration
371
1;
382
1;
(-)a/Koha/Schema/Result/Issue.pm (-51 / +31 lines)
Lines 1-21 Link Here
1
use utf8;
2
package Koha::Schema::Result::Issue;
1
package Koha::Schema::Result::Issue;
3
2
4
# Created by DBIx::Class::Schema::Loader
3
# Created by DBIx::Class::Schema::Loader
5
# DO NOT MODIFY THE FIRST PART OF THIS FILE
4
# DO NOT MODIFY THE FIRST PART OF THIS FILE
6
5
7
=head1 NAME
8
9
Koha::Schema::Result::Issue
10
11
=cut
12
13
use strict;
6
use strict;
14
use warnings;
7
use warnings;
15
8
16
use base 'DBIx::Class::Core';
9
use base 'DBIx::Class::Core';
17
10
18
=head1 TABLE: C<issues>
11
12
=head1 NAME
13
14
Koha::Schema::Result::Issue
19
15
20
=cut
16
=cut
21
17
Lines 23-28 __PACKAGE__->table("issues"); Link Here
23
19
24
=head1 ACCESSORS
20
=head1 ACCESSORS
25
21
22
=head2 issue_id
23
24
  data_type: 'integer'
25
  is_auto_increment: 1
26
  is_nullable: 0
27
26
=head2 borrowernumber
28
=head2 borrowernumber
27
29
28
  data_type: 'integer'
30
  data_type: 'integer'
Lines 38-44 __PACKAGE__->table("issues"); Link Here
38
=head2 date_due
40
=head2 date_due
39
41
40
  data_type: 'datetime'
42
  data_type: 'datetime'
41
  datetime_undef_if_invalid: 1
42
  is_nullable: 1
43
  is_nullable: 1
43
44
44
=head2 branchcode
45
=head2 branchcode
Lines 56-68 __PACKAGE__->table("issues"); Link Here
56
=head2 returndate
57
=head2 returndate
57
58
58
  data_type: 'datetime'
59
  data_type: 'datetime'
59
  datetime_undef_if_invalid: 1
60
  is_nullable: 1
60
  is_nullable: 1
61
61
62
=head2 lastreneweddate
62
=head2 lastreneweddate
63
63
64
  data_type: 'datetime'
64
  data_type: 'datetime'
65
  datetime_undef_if_invalid: 1
66
  is_nullable: 1
65
  is_nullable: 1
67
66
68
=head2 return
67
=head2 return
Lines 79-141 __PACKAGE__->table("issues"); Link Here
79
=head2 timestamp
78
=head2 timestamp
80
79
81
  data_type: 'timestamp'
80
  data_type: 'timestamp'
82
  datetime_undef_if_invalid: 1
83
  default_value: current_timestamp
81
  default_value: current_timestamp
84
  is_nullable: 0
82
  is_nullable: 0
85
83
86
=head2 issuedate
84
=head2 issuedate
87
85
88
  data_type: 'datetime'
86
  data_type: 'datetime'
89
  datetime_undef_if_invalid: 1
90
  is_nullable: 1
87
  is_nullable: 1
91
88
92
=cut
89
=cut
93
90
94
__PACKAGE__->add_columns(
91
__PACKAGE__->add_columns(
92
  "issue_id",
93
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
95
  "borrowernumber",
94
  "borrowernumber",
96
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
95
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
97
  "itemnumber",
96
  "itemnumber",
98
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
97
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
99
  "date_due",
98
  "date_due",
100
  {
99
  { data_type => "datetime", is_nullable => 1 },
101
    data_type => "datetime",
102
    datetime_undef_if_invalid => 1,
103
    is_nullable => 1,
104
  },
105
  "branchcode",
100
  "branchcode",
106
  { data_type => "varchar", is_nullable => 1, size => 10 },
101
  { data_type => "varchar", is_nullable => 1, size => 10 },
107
  "issuingbranch",
102
  "issuingbranch",
108
  { data_type => "varchar", is_nullable => 1, size => 18 },
103
  { data_type => "varchar", is_nullable => 1, size => 18 },
109
  "returndate",
104
  "returndate",
110
  {
105
  { data_type => "datetime", is_nullable => 1 },
111
    data_type => "datetime",
112
    datetime_undef_if_invalid => 1,
113
    is_nullable => 1,
114
  },
115
  "lastreneweddate",
106
  "lastreneweddate",
116
  {
107
  { data_type => "datetime", is_nullable => 1 },
117
    data_type => "datetime",
118
    datetime_undef_if_invalid => 1,
119
    is_nullable => 1,
120
  },
121
  "return",
108
  "return",
122
  { data_type => "varchar", is_nullable => 1, size => 4 },
109
  { data_type => "varchar", is_nullable => 1, size => 4 },
123
  "renewals",
110
  "renewals",
124
  { data_type => "tinyint", is_nullable => 1 },
111
  { data_type => "tinyint", is_nullable => 1 },
125
  "timestamp",
112
  "timestamp",
126
  {
113
  {
127
    data_type => "timestamp",
114
    data_type     => "timestamp",
128
    datetime_undef_if_invalid => 1,
129
    default_value => \"current_timestamp",
115
    default_value => \"current_timestamp",
130
    is_nullable => 0,
116
    is_nullable   => 0,
131
  },
117
  },
132
  "issuedate",
118
  "issuedate",
133
  {
119
  { data_type => "datetime", is_nullable => 1 },
134
    data_type => "datetime",
135
    datetime_undef_if_invalid => 1,
136
    is_nullable => 1,
137
  },
138
);
120
);
121
__PACKAGE__->set_primary_key("issue_id");
139
122
140
=head1 RELATIONS
123
=head1 RELATIONS
141
124
Lines 151-162 __PACKAGE__->belongs_to( Link Here
151
  "borrowernumber",
134
  "borrowernumber",
152
  "Koha::Schema::Result::Borrower",
135
  "Koha::Schema::Result::Borrower",
153
  { borrowernumber => "borrowernumber" },
136
  { borrowernumber => "borrowernumber" },
154
  {
137
  { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" },
155
    is_deferrable => 1,
156
    join_type     => "LEFT",
157
    on_delete     => "CASCADE",
158
    on_update     => "CASCADE",
159
  },
160
);
138
);
161
139
162
=head2 itemnumber
140
=head2 itemnumber
Lines 171-193 __PACKAGE__->belongs_to( Link Here
171
  "itemnumber",
149
  "itemnumber",
172
  "Koha::Schema::Result::Item",
150
  "Koha::Schema::Result::Item",
173
  { itemnumber => "itemnumber" },
151
  { itemnumber => "itemnumber" },
174
  {
152
  { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" },
175
    is_deferrable => 1,
176
    join_type     => "LEFT",
177
    on_delete     => "CASCADE",
178
    on_update     => "CASCADE",
179
  },
180
);
153
);
181
154
182
155
183
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21
156
# Created by DBIx::Class::Schema::Loader v0.07000 @ 2013-11-12 09:32:52
184
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZEh31EKBmURMKxDxI+H3EA
157
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:zBewWFig+yZYtSkcIxCZpg
185
158
186
__PACKAGE__->belongs_to(
159
__PACKAGE__->belongs_to(
187
  "borrower",
160
  "borrower",
188
  "Koha::Schema::Result::Borrower",
161
  "Koha::Schema::Result::Borrower",
189
  { borrowernumber => "borrowernumber" },
162
  { borrowernumber => "borrowernumber" },
190
  { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" },
163
  { join_type => "LEFT" },
164
);
165
166
__PACKAGE__->belongs_to(
167
  "item",
168
  "Koha::Schema::Result::Item",
169
  { itemnumber => "itemnumber" },
170
  { join_type => "LEFT" },
191
);
171
);
192
172
193
1;
173
1;
(-)a/Koha/Schema/Result/OldIssue.pm (-1 / +27 lines)
Lines 183-188 __PACKAGE__->belongs_to( Link Here
183
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21
183
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21
184
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:uPOxNROoMMRZ0qZsXsxEjA
184
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:uPOxNROoMMRZ0qZsXsxEjA
185
185
186
__PACKAGE__->belongs_to(
187
  "borrower",
188
  "Koha::Schema::Result::Borrower",
189
  { borrowernumber => "borrowernumber" },
190
  { join_type => "LEFT" },
191
);
192
193
__PACKAGE__->belongs_to(
194
  "item",
195
  "Koha::Schema::Result::Item",
196
  { itemnumber => "itemnumber" },
197
  { join_type => "LEFT" },
198
);
199
200
__PACKAGE__->belongs_to(
201
  "deletedborrower",
202
  "Koha::Schema::Result::Deletedborrower",
203
  { borrowernumber => "borrowernumber" },
204
  { join_type => "LEFT" },
205
);
206
207
__PACKAGE__->belongs_to(
208
  "deleteditem",
209
  "Koha::Schema::Result::Deleteditem",
210
  { itemnumber => "itemnumber" },
211
  { join_type => "LEFT" },
212
);
186
213
187
# You can replace this text with custom content, and it will be preserved on regeneration
188
1;
214
1;
(-)a/Koha/Template/Plugin/Currency.pm (+90 lines)
Line 0 Link Here
1
package Koha::Template::Plugin::Currency;
2
3
# Copyright ByWater Solutions 2013
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 2 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, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use base qw( Template::Plugin::Filter );
23
24
use Locale::Currency::Format;
25
26
use C4::Context;
27
use Koha::DateUtils;
28
29
sub init {
30
    my $self = shift;
31
    $self->{ _DYNAMIC } = 1;
32
33
    my $active_currency = C4::Context->dbh->selectrow_hashref(
34
        'SELECT * FROM currency WHERE active = 1', {} );
35
    $self->{active_currency} = $active_currency;
36
37
    return $self;
38
}
39
40
sub filter {
41
    my ( $self, $amount, $args, $conf ) = @_;
42
43
    return $self->format( $amount, undef, $conf->{highlight} );
44
}
45
46
sub format {
47
    my ( $self, $amount, $format, $highlight ) = @_;
48
49
    my $is_negative = $amount < 0;
50
    $amount = abs( $amount ) if $highlight;
51
52
    # A negative debit is a credit and visa versa
53
    if ($highlight) {
54
        if ( $highlight eq 'debit' ) {
55
            if ($is_negative) {
56
                $highlight = 'credit';
57
            }
58
        }
59
        elsif ( $highlight eq 'credit' ) {
60
            if ($is_negative) {
61
                $highlight = 'debit';
62
            }
63
64
        }
65
        elsif ( $highlight eq 'offset' ) {
66
            $highlight = $is_negative ? 'credit' : 'debit';
67
        }
68
    }
69
70
    my $formatted = currency_format( $self->{active_currency}->{currency},
71
        $amount, $format || FMT_HTML );
72
73
    $formatted = "<span class='$highlight'>$formatted</span>" if ( $highlight && $amount );
74
75
    return $formatted;
76
}
77
78
sub format_without_symbol {
79
    my ( $self, $amount ) = @_;
80
81
    return substr( $self->format( $amount, FMT_SYMBOL ), 1 );
82
}
83
84
sub symbol {
85
    my ($self) = @_;
86
87
    return currency_symbol( $self->{active_currency}->{'currency'}, SYM_HTML );
88
}
89
90
1;
(-)a/Koha/Template/Plugin/KohaAuthorisedValues.pm (+5 lines)
Lines 47-50 sub GetByCode { Link Here
47
    return GetAuthorisedValueByCode( $category, $code, $opac );
47
    return GetAuthorisedValueByCode( $category, $code, $opac );
48
}
48
}
49
49
50
sub Get {
51
    my ( $self, $category, $selected, $opac ) = @_;
52
    return GetAuthorisedValues( $category, $selected, $opac );
53
}
54
50
1;
55
1;
(-)a/circ/branchoverdues.pl (-2 / +1 lines)
Lines 49-57 use Data::Dumper; Link Here
49
 	level 3 : only methode is possible  : - Considered Lost
49
 	level 3 : only methode is possible  : - Considered Lost
50
50
51
 	the documents displayed on this interface, are checked on three points
51
 	the documents displayed on this interface, are checked on three points
52
 	- 1) the document must be on accountlines (Type 'FU')
52
	- 1) the document must be overdue with fines
53
 	- 2) item issues is not returned
53
 	- 2) item issues is not returned
54
	- 3) this item as not been already notify
55
54
56
  FIXME: who is the author?
55
  FIXME: who is the author?
57
  FIXME: No privisions (i.e. "actions") for handling notices are implemented.
56
  FIXME: No privisions (i.e. "actions") for handling notices are implemented.
(-)a/circ/circulation.pl (-3 / +1 lines)
Lines 648-655 foreach my $flag ( sort keys %$flags ) { Link Here
648
my $amountold = $borrower->{flags}->{'CHARGES'}->{'message'} || 0;
648
my $amountold = $borrower->{flags}->{'CHARGES'}->{'message'} || 0;
649
$amountold =~ s/^.*\$//;    # remove upto the $, if any
649
$amountold =~ s/^.*\$//;    # remove upto the $, if any
650
650
651
my ( $total, $accts, $numaccts) = GetMemberAccountRecords( $borrowernumber );
652
653
if ( $borrower->{'category_type'} eq 'C') {
651
if ( $borrower->{'category_type'} eq 'C') {
654
    my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
652
    my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
655
    my $cnt = scalar(@$catcodes);
653
    my $cnt = scalar(@$catcodes);
Lines 739-745 $template->param( Link Here
739
    message           => $message,
737
    message           => $message,
740
    CGIselectborrower => $CGIselectborrower,
738
    CGIselectborrower => $CGIselectborrower,
741
    totalprice        => sprintf('%.2f', $totalprice),
739
    totalprice        => sprintf('%.2f', $totalprice),
742
    totaldue          => sprintf('%.2f', $total),
740
    totaldue          => sprintf('%.2f', $borrower->{account_balance}),
743
    todayissues       => \@todaysissues,
741
    todayissues       => \@todaysissues,
744
    previssues        => \@previousissues,
742
    previssues        => \@previousissues,
745
    relissues			=> \@relissues,
743
    relissues			=> \@relissues,
(-)a/installer/data/mysql/kohastructure.sql (-44 / +84 lines)
Lines 265-270 CREATE TABLE `borrowers` ( -- this table includes information about your patrons Link Here
265
  `altcontactphone` varchar(50) default NULL, -- the phone number for the alternate contact for the patron/borrower
265
  `altcontactphone` varchar(50) default NULL, -- the phone number for the alternate contact for the patron/borrower
266
  `smsalertnumber` varchar(50) default NULL, -- the mobile phone number where the patron/borrower would like to receive notices (if SNS turned on)
266
  `smsalertnumber` varchar(50) default NULL, -- the mobile phone number where the patron/borrower would like to receive notices (if SNS turned on)
267
  `privacy` integer(11) DEFAULT '1' NOT NULL, -- patron/borrower's privacy settings related to their reading history
267
  `privacy` integer(11) DEFAULT '1' NOT NULL, -- patron/borrower's privacy settings related to their reading history
268
  `account_balance` decimal(28,6) NOT NULL,
268
  UNIQUE KEY `cardnumber` (`cardnumber`),
269
  UNIQUE KEY `cardnumber` (`cardnumber`),
269
  PRIMARY KEY `borrowernumber` (`borrowernumber`),
270
  PRIMARY KEY `borrowernumber` (`borrowernumber`),
270
  KEY `categorycode` (`categorycode`),
271
  KEY `categorycode` (`categorycode`),
Lines 2678-2727 CREATE TABLE `messages` ( -- circulation messages left via the patron's check ou Link Here
2678
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2679
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2679
2680
2680
--
2681
--
2681
-- Table structure for table `accountlines`
2682
--
2683
2684
DROP TABLE IF EXISTS `accountlines`;
2685
CREATE TABLE `accountlines` (
2686
  `accountlines_id` int(11) NOT NULL AUTO_INCREMENT,
2687
  `borrowernumber` int(11) NOT NULL default 0,
2688
  `accountno` smallint(6) NOT NULL default 0,
2689
  `itemnumber` int(11) default NULL,
2690
  `date` date default NULL,
2691
  `amount` decimal(28,6) default NULL,
2692
  `description` mediumtext,
2693
  `dispute` mediumtext,
2694
  `accounttype` varchar(5) default NULL,
2695
  `amountoutstanding` decimal(28,6) default NULL,
2696
  `lastincrement` decimal(28,6) default NULL,
2697
  `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
2698
  `notify_id` int(11) NOT NULL default 0,
2699
  `notify_level` int(2) NOT NULL default 0,
2700
  `note` text NULL default NULL,
2701
  `manager_id` int(11) NULL,
2702
  PRIMARY KEY (`accountlines_id`),
2703
  KEY `acctsborridx` (`borrowernumber`),
2704
  KEY `timeidx` (`timestamp`),
2705
  KEY `itemnumber` (`itemnumber`),
2706
  CONSTRAINT `accountlines_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE,
2707
  CONSTRAINT `accountlines_ibfk_2` FOREIGN KEY (`itemnumber`) REFERENCES `items` (`itemnumber`) ON DELETE SET NULL ON UPDATE SET NULL
2708
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2709
2710
--
2711
-- Table structure for table `accountoffsets`
2712
--
2713
2714
DROP TABLE IF EXISTS `accountoffsets`;
2715
CREATE TABLE `accountoffsets` (
2716
  `borrowernumber` int(11) NOT NULL default 0,
2717
  `accountno` smallint(6) NOT NULL default 0,
2718
  `offsetaccount` smallint(6) NOT NULL default 0,
2719
  `offsetamount` decimal(28,6) default NULL,
2720
  `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
2721
  CONSTRAINT `accountoffsets_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE
2722
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2723
2724
--
2725
-- Table structure for table `action_logs`
2682
-- Table structure for table `action_logs`
2726
--
2683
--
2727
2684
Lines 3387-3392 CREATE TABLE IF NOT EXISTS marc_modification_template_actions ( Link Here
3387
  CONSTRAINT `mmta_ibfk_1` FOREIGN KEY (`template_id`) REFERENCES `marc_modification_templates` (`template_id`) ON DELETE CASCADE ON UPDATE CASCADE
3344
  CONSTRAINT `mmta_ibfk_1` FOREIGN KEY (`template_id`) REFERENCES `marc_modification_templates` (`template_id`) ON DELETE CASCADE ON UPDATE CASCADE
3388
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
3345
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
3389
3346
3347
--
3348
-- Table structure for table 'account_credits'
3349
--
3350
DROP TABLE IF EXISTS account_credits;
3351
CREATE TABLE IF account_credits (
3352
    credit_id int(11) NOT NULL AUTO_INCREMENT,  -- The unique id for this credit
3353
    borrowernumber int(11) NOT NULL,            -- The borrower this credit applies to
3354
    `type` varchar(255) NOT NULL,               -- The type of credit this is ( defined by Koha::Accounts::CreditTypes )
3355
    amount_received decimal(28,6) DEFAULT NULL, -- If this was a cash payment, the amount of money given
3356
    amount_paid decimal(28,6) NOT NULL,         -- The actual ammount paid, if less than amount_recieved, change was given back
3357
    amount_remaining decimal(28,6) NOT NULL,    -- The amount of this credit that has not been applied to outstanding debits
3358
    notes text,                                 -- Misc notes for this credit
3359
    manager_id int(11) DEFAULT NULL,            -- The borrowernumber of the user who created this credit ( if any )
3360
    created_on timestamp NULL DEFAULT NULL,     -- Timestamp for when this credit was created
3361
    updated_on timestamp NULL DEFAULT NULL,     -- Timestamp for when this credit was last modified
3362
    PRIMARY KEY (credit_id),
3363
    KEY borrowernumber (borrowernumber)
3364
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
3365
3366
--
3367
-- Constraints for table `account_credits`
3368
--
3369
ALTER TABLE `account_credits`
3370
  ADD CONSTRAINT account_credits_ibfk_1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE;
3371
3372
--
3373
-- Table structure for table 'account_debits'
3374
--
3375
3376
DROP TABLE IF EXISTS account_debits;
3377
CREATE TABLE account_debits (
3378
    debit_id int(11) NOT NULL AUTO_INCREMENT,           -- The unique id for this debit
3379
    borrowernumber int(11) NOT NULL DEFAULT '0',        -- The borrower this debit applies to
3380
    itemnumber int(11) DEFAULT NULL,                    -- The item related to this debit ( for fines, lost fees, etc )
3381
    issue_id int(11) DEFAULT NULL,                      -- The checkout this debit is related to ( again, for fines, lost fees, etc )
3382
    `type` varchar(255) NOT NULL,                       -- The type of debit this is ( defined by Koha::Accounts::DebitTypes )
3383
    accruing tinyint(1) NOT NULL DEFAULT '0',           -- Boolean flag, tells of if this is a fine that is still accruing
3384
    amount_original decimal(28,6) DEFAULT NULL,         -- The total amount of this debit
3385
    amount_outstanding decimal(28,6) DEFAULT NULL,      -- The amount still owed on this debit
3386
    amount_last_increment decimal(28,6) DEFAULT NULL,   -- The amount by which this debit last changed
3387
    description mediumtext,                             -- The description for this debit
3388
    notes text,                                         -- Misc notes for this debit
3389
    manager_id int(11) DEFAULT NULL,                    -- The borrowernumber of the user who created this debit ( if any )
3390
    created_on timestamp NULL DEFAULT NULL,             -- Timestamp for when this credit was created
3391
    updated_on timestamp NULL DEFAULT NULL,             -- Timestamp for when this credit was last modified
3392
    PRIMARY KEY (debit_id),
3393
    KEY acctsborridx (borrowernumber),
3394
    KEY itemnumber (itemnumber),
3395
    KEY borrowernumber (borrowernumber),
3396
    KEY issue_id (issue_id)
3397
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
3398
3399
--
3400
-- Constraints for table `account_debits`
3401
--
3402
ALTER TABLE `account_debits`
3403
    ADD CONSTRAINT account_debits_ibfk_1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE;
3404
3405
--
3406
-- Table structure for table 'account_offsets'
3407
--
3408
3409
DROP TABLE IF EXISTS account_offsets;
3410
CREATE TABLE account_offsets (
3411
    offset_id int(11) NOT NULL AUTO_INCREMENT,                                              -- Unique id for this offset
3412
    debit_id int(11) DEFAULT NULL,                                                          -- Related debit
3413
    credit_id int(11) DEFAULT NULL,                                                         -- Related credit ( if any )
3414
    `type` varchar(255) DEFAULT NULL,                                                       -- The type of this offset ( defined by Koha::Accounts::OffsetTypes ), if any
3415
    amount decimal(28,6) NOT NULL,                                                          -- The amount of the offset, positive means patron owes more, negative means patron owes less
3416
    created_on timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,    -- Timestamp for when this offset was created
3417
    PRIMARY KEY (offset_id),
3418
    KEY fee_id (debit_id),
3419
    KEY payment_id (credit_id)
3420
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
3421
3422
--
3423
-- Constraints for table `account_offsets`
3424
--
3425
ALTER TABLE `account_offsets`
3426
    ADD CONSTRAINT account_offsets_ibfk_1 FOREIGN KEY (debit_id) REFERENCES account_debits (debit_id) ON DELETE CASCADE ON UPDATE CASCADE,
3427
    ADD CONSTRAINT account_offsets_ibfk_2 FOREIGN KEY (credit_id) REFERENCES account_credits (credit_id) ON DELETE CASCADE ON UPDATE CASCADE;
3428
3429
3390
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3430
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
3391
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
3431
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
3392
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
3432
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
(-)a/installer/data/mysql/updatedatabase.pl (+177 lines)
Lines 37-42 use Getopt::Long; Link Here
37
use C4::Context;
37
use C4::Context;
38
use C4::Installer;
38
use C4::Installer;
39
use C4::Dates;
39
use C4::Dates;
40
use Koha::Database;
40
41
41
use MARC::Record;
42
use MARC::Record;
42
use MARC::File::XML ( BinaryEncoding => 'utf8' );
43
use MARC::File::XML ( BinaryEncoding => 'utf8' );
Lines 7259-7264 if ( CheckVersion($DBversion) ) { Link Here
7259
7260
7260
    $dbh->{AutoCommit} = 1;
7261
    $dbh->{AutoCommit} = 1;
7261
    $dbh->{RaiseError} = 0;
7262
    $dbh->{RaiseError} = 0;
7263
   SetVersion ($DBversion);
7262
}
7264
}
7263
7265
7264
$DBversion = "3.13.00.031";
7266
$DBversion = "3.13.00.031";
Lines 7778-7783 if(CheckVersion($DBversion)) { Link Here
7778
    SetVersion($DBversion);
7780
    SetVersion($DBversion);
7779
}
7781
}
7780
7782
7783
$DBversion = "3.15.00.XXX";
7784
if ( CheckVersion($DBversion) ) {
7785
    $dbh->do(q{
7786
        ALTER TABLE old_issues ADD issue_id INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST
7787
    });
7788
    $dbh->do(q{
7789
        ALTER TABLE issues ADD issue_id INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
7790
    });
7791
    $dbh->do(q{
7792
        UPDATE issues SET issue_id = issue_id + ( SELECT COUNT(*) FROM old_issues ) ORDER BY issue_id DESC
7793
    });
7794
7795
    $dbh->do("
7796
        CREATE TABLE IF NOT EXISTS account_credits (
7797
            credit_id int(11) NOT NULL AUTO_INCREMENT,
7798
            borrowernumber int(11) NOT NULL,
7799
            `type` varchar(255) NOT NULL,
7800
            amount_received decimal(28,6) DEFAULT NULL,
7801
            amount_paid decimal(28,6) NOT NULL,
7802
            amount_remaining decimal(28,6) NOT NULL,
7803
            notes text,
7804
            manager_id int(11) DEFAULT NULL,
7805
            created_on timestamp NULL DEFAULT NULL,
7806
            updated_on timestamp NULL DEFAULT NULL,
7807
            PRIMARY KEY (credit_id),
7808
            KEY borrowernumber (borrowernumber)
7809
        ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
7810
    ");
7811
    $dbh->do("
7812
        CREATE TABLE IF NOT EXISTS account_debits (
7813
            debit_id int(11) NOT NULL AUTO_INCREMENT,
7814
            borrowernumber int(11) NOT NULL DEFAULT '0',
7815
            itemnumber int(11) DEFAULT NULL,
7816
            issue_id int(11) DEFAULT NULL,
7817
            `type` varchar(255) NOT NULL,
7818
            accruing tinyint(1) NOT NULL DEFAULT '0',
7819
            amount_original decimal(28,6) DEFAULT NULL,
7820
            amount_outstanding decimal(28,6) DEFAULT NULL,
7821
            amount_last_increment decimal(28,6) DEFAULT NULL,
7822
            description mediumtext,
7823
            notes text,
7824
            manager_id int(11) DEFAULT NULL,
7825
            created_on timestamp NULL DEFAULT NULL,
7826
            updated_on timestamp NULL DEFAULT NULL,
7827
            PRIMARY KEY (debit_id),
7828
            KEY acctsborridx (borrowernumber),
7829
            KEY itemnumber (itemnumber),
7830
            KEY borrowernumber (borrowernumber),
7831
            KEY issue_id (issue_id)
7832
        ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
7833
    ");
7834
7835
    $dbh->do("
7836
        CREATE TABLE account_offsets (
7837
            offset_id int(11) NOT NULL AUTO_INCREMENT,
7838
            debit_id int(11) DEFAULT NULL,
7839
            credit_id int(11) DEFAULT NULL,
7840
            `type` varchar(255) DEFAULT NULL,
7841
            amount decimal(28,6) NOT NULL COMMENT 'A positive number here represents a payment, a negative is a increase in a fine.',
7842
            created_on timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
7843
            PRIMARY KEY (offset_id),
7844
            KEY fee_id (debit_id),
7845
            KEY payment_id (credit_id)
7846
        ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
7847
    ");
7848
7849
    $dbh->do("
7850
        ALTER TABLE `account_credits`
7851
          ADD CONSTRAINT account_credits_ibfk_1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE;
7852
    ");
7853
    $dbh->do("
7854
        ALTER TABLE `account_debits`
7855
          ADD CONSTRAINT account_debits_ibfk_1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE;
7856
    ");
7857
    $dbh->do("
7858
        ALTER TABLE `account_offsets`
7859
          ADD CONSTRAINT account_offsets_ibfk_1 FOREIGN KEY (debit_id) REFERENCES account_debits (debit_id) ON DELETE CASCADE ON UPDATE CASCADE,
7860
          ADD CONSTRAINT account_offsets_ibfk_2 FOREIGN KEY (credit_id) REFERENCES account_credits (credit_id) ON DELETE CASCADE ON UPDATE CASCADE;
7861
    ");
7862
7863
    $dbh->do("
7864
        ALTER TABLE borrowers ADD account_balance DECIMAL( 28, 6 ) NOT NULL;
7865
    ");
7866
7867
    my $schema = Koha::Database->new()->schema;
7868
    my $debit_rs = $schema->resultset('AccountDebit');
7869
    my $credit_rs = $schema->resultset('AccountCredit');
7870
    my $issues_rs = $schema->resultset('Issue');
7871
7872
    use Koha::Accounts::DebitTypes;
7873
    use Koha::Accounts::CreditTypes;
7874
7875
    my $debit_types_map = {
7876
        'A'    => Koha::Accounts::DebitTypes::AccountManagementFee,
7877
        'F'    => Koha::Accounts::DebitTypes::Fine,
7878
        'FU'   => Koha::Accounts::DebitTypes::Fine,
7879
        'L'    => Koha::Accounts::DebitTypes::Lost,
7880
        'M'    => Koha::Accounts::DebitTypes::Sundry,
7881
        'N'    => Koha::Accounts::DebitTypes::NewCard,
7882
        'Rent' => Koha::Accounts::DebitTypes::Rental,
7883
    };
7884
7885
    my $credit_types_map = {
7886
        'FOR' => Koha::Accounts::CreditTypes::Forgiven,
7887
        'LR'  => Koha::Accounts::CreditTypes::Found,
7888
        'Pay' => Koha::Accounts::CreditTypes::Payment,
7889
        'PAY' => Koha::Accounts::CreditTypes::Payment,
7890
        'WO'  => Koha::Accounts::CreditTypes::WriteOff,
7891
        'W'   => Koha::Accounts::CreditTypes::WriteOff,
7892
        'C'   => Koha::Accounts::CreditTypes::Credit,
7893
        'CR'  => Koha::Accounts::CreditTypes::Credit,
7894
    };
7895
7896
    my $sth = $dbh->prepare("SELECT * FROM accountlines");
7897
    $sth->execute();
7898
    while ( my $a = $sth->fetchrow_hashref() ) {
7899
        if ( $debit_types_map->{ $a->{accounttype} } ) {
7900
            $debit_rs->create(
7901
                {
7902
                    borrowernumber     => $a->{borrowernumber},
7903
                    itemnumber         => $a->{itemnumber},
7904
                    amount_original    => $a->{amount},
7905
                    amount_outstanding => $a->{amountoutstanding},
7906
                    created_on         => $a->{timestamp},
7907
                    description        => $a->{description},
7908
                    notes              => $a->{note},
7909
                    manager_id         => $a->{manager_id},
7910
                    accruing           => $a->{accounttype} eq 'FU',
7911
                    type     => $debit_types_map->{ $a->{accounttype} },
7912
                    issue_id => $a->{accounttype} eq 'FU'
7913
                    ? $issues_rs->single(
7914
                        {
7915
                            borrowernumber => $a->{borrowernumber},
7916
                            itemnumber     => $a->{itemnumber},
7917
                        }
7918
                      )->issue_id()
7919
                    : undef,
7920
                }
7921
            );
7922
        }
7923
        elsif ( $credit_types_map->{ $a->{accounttype} } ) {
7924
            $credit_rs->create(
7925
                {
7926
                    borrowernumber   => $a->{borrowernumber},
7927
                    amount_paid      => $a->{amount} * -1,
7928
                    amount_remaining => $a->{amountoutstanding} * -1,
7929
                    created_on       => $a->{timestamp},
7930
                    notes            => $a->{note},
7931
                    manager_id       => $a->{manager_id},
7932
                    type => $credit_types_map->{ $a->{accounttype} },
7933
                }
7934
            );
7935
        }
7936
        else {
7937
            # Everything else must be a MANUAL_INV
7938
            $debit_rs->create(
7939
                {
7940
                    borrowernumber     => $a->{borrowernumber},
7941
                    itemnumber         => $a->{itemnumber},
7942
                    amount_original    => $a->{amount},
7943
                    amount_outstanding => $a->{amountoutstanding},
7944
                    created_on         => $a->{timestamp},
7945
                    description        => $a->{description},
7946
                    notes              => $a->{note},
7947
                    manager_id         => $a->{manager_id},
7948
                    type               => Koha::Accounts::DebitTypes::Sundry,
7949
                }
7950
            );
7951
        }
7952
    }
7953
7954
    print "Upgrade to $DBversion done ( Bug 6427 - Rewrite of the accounts system )\n";
7955
    SetVersion ($DBversion);
7956
}
7957
7781
=head1 FUNCTIONS
7958
=head1 FUNCTIONS
7782
7959
7783
=head2 TableExists($table)
7960
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/browser-strings.inc (+27 lines)
Lines 1-7 Link Here
1
[% USE KohaAuthorisedValues %]
1
<script type="text/javascript">
2
<script type="text/javascript">
2
//<![CDATA[
3
//<![CDATA[
3
    var BROWSER_RETURN_TO_SEARCH = _("Return to results");
4
    var BROWSER_RETURN_TO_SEARCH = _("Return to results");
4
    var BROWSER_PREVIOUS = _("Previous");
5
    var BROWSER_PREVIOUS = _("Previous");
5
    var BROWSER_NEXT = _("Next");
6
    var BROWSER_NEXT = _("Next");
7
8
    var STRINGS = {
9
        "DebitTypes": {
10
            "FINE"                      : _("Fine"),
11
            "ACCOUNT_MANAGEMENT_FEE"    : _("Account management fee"),
12
            "SUNDRY"                    : _("Sundry"),
13
            "LOST"                      : _("Lost item"),
14
            "HOLD"                      : _("Hold fee"),
15
            "RENTAL"                    : _("Rental fee"),
16
            "NEW_CARD"                  : _("New card"),
17
            [% FOREACH a IN KohaAuthorisedValues.Get('MANUAL_INV') %]
18
                "[% a.authorised_value %]" : "[% a.lib %]",
19
            [% END %]
20
        },
21
22
        "CreditTypes": {
23
            "CREDIT"                    : _("Credit"),
24
            "PAYMENT"                   : _("Payment"),
25
            "WRITEOFF"                  : _("Writeoff"),
26
            "FOUND"                     : _("Lost item found"),
27
            "FORGIVEN"                  : _("Forgiven"),
28
            [% FOREACH a IN KohaAuthorisedValues.Get('MANUAL_CREDIT') %]
29
                "[% a.authorised_value %]" : "[% a.lib %]",
30
            [% END %]
31
        }
32
    }
6
//]]>
33
//]]>
7
</script>
34
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc (-1 / +1 lines)
Lines 67-73 Link Here
67
        [% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">Details</a></li>
67
        [% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">Details</a></li>
68
    [% END %]
68
    [% END %]
69
    [% IF ( CAN_user_updatecharges ) %]
69
    [% IF ( CAN_user_updatecharges ) %]
70
        [% IF ( finesview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Fines</a></li>
70
        [% IF ( accounts_view ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Fines</a></li>
71
    [% END %]
71
    [% END %]
72
    [% IF ( RoutingSerials ) %][% IF ( routinglistview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/routing-lists.pl?borrowernumber=[% borrowernumber %]">Routing lists</a></li>[% END %]
72
    [% IF ( RoutingSerials ) %][% IF ( routinglistview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/routing-lists.pl?borrowernumber=[% borrowernumber %]">Routing lists</a></li>[% END %]
73
    [% IF ( intranetreadinghistory ) %]
73
    [% IF ( intranetreadinghistory ) %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.tt (-1 / +1 lines)
Lines 70-76 in the global namespace %] Link Here
70
	[% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrower.borrowernumber %]">Details</a></li>
70
	[% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrower.borrowernumber %]">Details</a></li>
71
	[% END %]
71
	[% END %]
72
	 [% IF ( CAN_user_updatecharges ) %]
72
	 [% IF ( CAN_user_updatecharges ) %]
73
	[% IF ( finesview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrower.borrowernumber %]">Fines</a></li>
73
 [% IF ( accounts_view ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrower.borrowernumber %]">Fines</a></li>
74
	[% END %]
74
	[% END %]
75
    [% IF ( RoutingSerials ) %][% IF ( routinglistview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/routing-lists.pl?borrowernumber=[% borrower.borrowernumber %]">Routing lists</a></li>[% END %]
75
    [% IF ( RoutingSerials ) %][% IF ( routinglistview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/routing-lists.pl?borrowernumber=[% borrower.borrowernumber %]">Routing lists</a></li>[% END %]
76
    [% IF ( intranetreadinghistory ) %][% IF ( readingrecordview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/readingrec.pl?borrowernumber=[% borrower.borrowernumber %]">Circulation history</a></li>[% END %]
76
    [% IF ( intranetreadinghistory ) %][% IF ( readingrecordview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/readingrec.pl?borrowernumber=[% borrower.borrowernumber %]">Circulation history</a></li>[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/members-menu.inc (-1 / +1 lines)
Lines 4-10 Link Here
4
    [% IF ( circview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% borrowernumber %]">Check out</a></li>
4
    [% IF ( circview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/circ/circulation.pl?borrowernumber=[% borrowernumber %]">Check out</a></li>
5
    [% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">Details</a></li>
5
    [% IF ( detailview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">Details</a></li>
6
    [% IF ( CAN_user_updatecharges ) %]
6
    [% IF ( CAN_user_updatecharges ) %]
7
        [% IF ( finesview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Fines</a></li>
7
        [% IF ( finesview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Fines</a></li>
8
    [% END %]
8
    [% END %]
9
    [% IF ( intranetreadinghistory ) %]
9
    [% IF ( intranetreadinghistory ) %]
10
        [% IF ( readingrecordview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/readingrec.pl?borrowernumber=[% borrowernumber %]">Circulation history</a></li>
10
        [% IF ( readingrecordview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/members/readingrec.pl?borrowernumber=[% borrowernumber %]">Circulation history</a></li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (-3 / +4 lines)
Lines 1-5 Link Here
1
[% USE KohaBranchName %]
1
[% USE KohaBranchName %]
2
[% USE KohaDates %]
2
[% USE KohaDates %]
3
[% USE Currency %]
3
[% IF ( export_remove_fields OR export_with_csv_profile ) %]
4
[% IF ( export_remove_fields OR export_with_csv_profile ) %]
4
   [% SET exports_enabled = 1 %]
5
   [% SET exports_enabled = 1 %]
5
[% END %]
6
[% END %]
Lines 577-592 No patron matched <span class="ex">[% message %]</span> Link Here
577
578
578
        	[% IF ( charges ) %]
579
        	[% IF ( charges ) %]
579
			    <li>
580
			    <li>
580
            <span class="circ-hlt">Fees &amp; Charges:</span> Patron has  <a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Outstanding fees &amp; charges[% IF ( chargesamount ) %] of [% chargesamount %][% END %]</a>.
581
            <span class="circ-hlt">Fees &amp; Charges:</span> Patron has  <a href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Outstanding fees &amp; charges[% IF ( chargesamount ) %] of [% chargesamount | $Currency %][% END %]</a>.
581
                [% IF ( charges_is_blocker ) %]
582
                [% IF ( charges_is_blocker ) %]
582
                    Checkouts are <span class="circ-hlt">BLOCKED</span> because fine balance is <span class="circ-hlt">OVER THE LIMIT</span>.
583
                    Checkouts are <span class="circ-hlt">BLOCKED</span> because fine balance is <span class="circ-hlt">OVER THE LIMIT</span>.
583
                [% END %]
584
                [% END %]
584
            <a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrowernumber %]">Make payment</a></li>
585
            <a href="/cgi-bin/koha/members/account_payment.pl?borrowernumber=[% borrowernumber %]">Make payment</a></li>
585
			[% END %]
586
			[% END %]
586
587
587
        	[% IF ( credits ) %]
588
        	[% IF ( credits ) %]
588
			<li>
589
			<li>
589
                <span class="circ-hlt">Credits:</span> Patron has a credit[% IF ( creditsamount ) %] of [% creditsamount %][% END %]
590
                <span class="circ-hlt">Credits:</span> Patron has a credit[% IF ( creditsamount ) %] of [% creditsamount | $Currency %][% END %]
590
            </li>
591
            </li>
591
			[% END %]
592
			[% END %]
592
593
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt (-1 / +1 lines)
Lines 74-80 $(document).ready(function () { Link Here
74
[% IF ( fines ) %]
74
[% IF ( fines ) %]
75
    <div class="dialog alert">
75
    <div class="dialog alert">
76
        <h3>Patron has outstanding fines of [% fines %].</h3>
76
        <h3>Patron has outstanding fines of [% fines %].</h3>
77
        <p><a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% fineborrowernumber %]">Make payment</a>.</p>
77
        <p><a href="/cgi-bin/koha/members/account_payment.pl?borrowernumber=[% fineborrowernumber %]">Make payment</a>.</p>
78
    </div>
78
    </div>
79
[% END %]
79
[% END %]
80
80
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/help/reports/guided_reports.tt (-18 lines)
Lines 108-131 Link Here
108
108
109
<h3>DB table value for reports</h3>
109
<h3>DB table value for reports</h3>
110
110
111
<p><strong>Question:</strong> What do the codes in the accounttype field in the accountlines table stand for?</p>
112
113
<p><strong>Answer:</strong></p>
114
115
<ul>
116
	<li>A = Account management fee</li>
117
	<li>C = Credit</li>
118
	<li>F = Overdue fine</li>
119
	<li>FOR = Forgiven</li>
120
	<li>FU = Overdue, still acccruing</li>
121
	<li>L = Lost item</li>
122
	<li>LR = Lost item returned/refunded</li>
123
	<li>M = Sundry</li>
124
	<li>N = New card</li>
125
	<li>PAY = Payment</li>
126
	<li>W = Writeoff</li>
127
</ul>
128
129
<p><strong>Question:</strong> What are the possible codes for the type field in the statistics table?</p>
111
<p><strong>Question:</strong> What are the possible codes for the type field in the statistics table?</p>
130
112
131
<p><strong>Answer:</strong></p>
113
<p><strong>Answer:</strong></p>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/account.tt (+431 lines)
Line 0 Link Here
1
[% SET accounts_view = 1 %]
2
[% USE KohaDates %]
3
[% USE Currency %]
4
[% INCLUDE 'doc-head-open.inc' %]
5
<title>Koha &rsaquo; Patrons &rsaquo; Account for [% INCLUDE 'patron-title.inc' %]</title>
6
[% INCLUDE 'doc-head-close.inc' %]
7
8
<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/en/css/datatables.css" />
9
<script type="text/javascript" src="[% interface %]/[% theme %]/en/lib/jquery/plugins/jquery.dataTables.min.js"></script>
10
[% INCLUDE 'datatables-strings.inc' %]
11
[% INCLUDE 'browser-strings.inc' %]
12
<script type="text/javascript" src="[% interface %]/[% theme %]/en/js/datatables.js"></script>
13
<script type="text/javascript" src="[% interface %]/[% theme %]/en/js/strings.js"></script>
14
15
<script type="text/javascript">
16
//<![CDATA[
17
$(document).ready(function() {
18
    $('#account-credits').hide();
19
    $('#account-debits-switcher').click(function() {
20
         $('#account-debits').slideUp();
21
         $('#account-credits').slideDown();
22
    });
23
    $('#account-credits-switcher').click(function() {
24
         $('#account-credits').slideUp();
25
         $('#account-debits').slideDown();
26
    });
27
28
    var anOpen = [];
29
    var sImageUrl = "[% interface %]/[% theme %]/img/";
30
31
    var debitsTable = $('#debits-table').dataTable( {
32
        "bProcessing": true,
33
        "aoColumns": [
34
            {
35
                "mDataProp": null,
36
                "sClass": "control center",
37
                "sDefaultContent": '<img src="'+sImageUrl+'details_open.png'+'">'
38
            },
39
            { "mDataProp": "debit_id" },
40
            { "mDataProp": "description" },
41
            {
42
                "mDataProp": "type",
43
                "fnRender": function ( o, val ) {
44
                    return STRINGS['DebitTypes'][val];
45
                },
46
            },
47
            { "mDataProp": "amount_original" },
48
            { "mDataProp": "amount_outstanding" },
49
            { "mDataProp": "created_on" },
50
            { "mDataProp": "updated_on" }
51
        ],
52
        "aaData": [
53
            [% FOREACH d IN debits %]
54
                {
55
                    [% PROCESS format_data data=d highlight='debit' %]
56
57
                    // Data for related item if there is one linked
58
                    "title": "[% d.item.biblio.title || d.deleted_item.biblio.title || d.deleted_item.deleted_biblio.title %]",
59
                    "biblionumber": "[% d.item.biblio.biblionumber || d.deleted_item.biblio.biblionumber %]",
60
                    "barcode": "[% d.item.barcode || d.deleted_item.barcode %]",
61
                    "itemnumber": "[% d.item.itemnumber %]", //This way itemnumber will be undef if deleted
62
63
64
                    // Data for related issue if there is one linked
65
                    [% IF d.issue %]
66
                        [% SET table = 'issue' %]
67
                    [% ELSIF d.old_issue %]
68
                        [% SET table = 'old_issue' %]
69
                    [% END %]
70
71
                    [% IF table %]
72
                        "issue": {
73
                            [% PROCESS format_data data=d.$table %]
74
                        },
75
                    [% END %]
76
77
78
                    "account_offsets": [
79
                        [% FOREACH ao IN d.account_offsets %]
80
                            {
81
                                [% PROCESS format_data data=ao highlight='offset'%]
82
83
                                "credit": {
84
                                    [% PROCESS format_data data=ao.credit highlight='credit' %]
85
                                }
86
                            },
87
                        [% END %]
88
                    ]
89
90
                },
91
            [% END %]
92
        ]
93
    } );
94
95
    $('#debits-table td.control').live( 'click', function () {
96
        var nTr = this.parentNode;
97
        var i = $.inArray( nTr, anOpen );
98
99
        if ( i === -1 ) {
100
            $('img', this).attr( 'src', sImageUrl+"details_close.png" );
101
            var nDetailsRow = debitsTable.fnOpen( nTr, fnFormatDebitDetails(debitsTable, nTr), 'details' );
102
            $('div.innerDetails', nDetailsRow).slideDown();
103
            anOpen.push( nTr );
104
        }
105
        else {
106
            $('img', this).attr( 'src', sImageUrl+"details_open.png" );
107
            $('div.innerDetails', $(nTr).next()[0]).slideUp( function () {
108
                debitsTable.fnClose( nTr );
109
                anOpen.splice( i, 1 );
110
            } );
111
        }
112
    } );
113
114
    var creditsTable = $('#credits-table').dataTable( {
115
        "bProcessing": true,
116
        "aoColumns": [
117
            {
118
                "mDataProp": null,
119
                "sClass": "control center",
120
                "sDefaultContent": '<img src="'+sImageUrl+'details_open.png'+'">'
121
            },
122
            { "mDataProp": "credit_id" },
123
            { "mDataProp": "notes" },
124
            {
125
                "mDataProp": "type",
126
                "fnRender": function ( o, val ) {
127
                    return STRINGS['CreditTypes'][val];
128
                },
129
            },
130
            { "mDataProp": "amount_paid" },
131
            { "mDataProp": "amount_remaining" },
132
            { "mDataProp": "created_on" },
133
            { "mDataProp": "updated_on" }
134
        ],
135
        "aaData": [
136
            [% FOREACH c IN credits %]
137
                {
138
                    [% PROCESS format_data data=c highlight='credit' %]
139
140
                    "account_offsets": [
141
                        [% FOREACH ao IN c.account_offsets %]
142
                            {
143
                                [% PROCESS format_data data=ao highlight='offset' %]
144
145
                                "debit": {
146
                                    [% PROCESS format_data data=ao.debit highlight='debit' %]
147
                                }
148
                            },
149
                        [% END %]
150
                    ]
151
152
                },
153
            [% END %]
154
        ]
155
    } );
156
157
    $('#credits-table td.control').live( 'click', function () {
158
        var nTr = this.parentNode;
159
        var i = $.inArray( nTr, anOpen );
160
161
        if ( i === -1 ) {
162
            $('img', this).attr( 'src', sImageUrl+"details_close.png" );
163
            var nDetailsRow = creditsTable.fnOpen( nTr, fnFormatCreditDetails(creditsTable, nTr), 'details' );
164
            $('div.innerDetails', nDetailsRow).slideDown();
165
            anOpen.push( nTr );
166
        }
167
        else {
168
            $('img', this).attr( 'src', sImageUrl+"details_open.png" );
169
            $('div.innerDetails', $(nTr).next()[0]).slideUp( function () {
170
                creditsTable.fnClose( nTr );
171
                anOpen.splice( i, 1 );
172
            } );
173
        }
174
    } );
175
176
} );
177
178
function fnFormatDebitDetails( debitsTable, nTr ) {
179
    var oData = debitsTable.fnGetData( nTr );
180
181
    var sOut = '<div class="innerDetails" style="display:none;">';
182
183
    var account_offsets = oData.account_offsets;
184
185
    sOut += '<a class="debit_print btn btn-small" style="margin:5px;" onclick="accountPrint(\'debit\',' + oData.debit_id + ')">' +
186
                '<i class="icon-print"></i> ' + _('Print receipt') +
187
            '</a>';
188
189
    sOut += '<ul>';
190
    if ( oData.title ) {
191
        sOut += '<li>' + _('Title: ');
192
        if ( oData.biblionumber ) {
193
            sOut += '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=' + oData.biblionumber + '">';
194
        }
195
196
        sOut += oData.title;
197
198
        if ( oData.biblionumber ) {
199
            sOut += '</a>';
200
        }
201
202
        sOut += '</li>';
203
    }
204
205
    if ( oData.barcode ) {
206
        sOut += '<li>' + _('Barcode: ');
207
        if ( oData.itemnumber ) {
208
            sOut += '<a href="/cgi-bin/koha/catalogue/moredetail.pl?itemnumber=11&biblionumber=' + oData.biblionumber + '&bi=' + oData.biblionumber + '#item' + oData.itemnumber + '' + oData.biblionumber + '">';
209
        }
210
211
        sOut += oData.barcode;
212
213
        if ( oData.itemnumber ) {
214
            sOut += '</a>';
215
        }
216
217
        sOut += '</li>';
218
    }
219
220
    if ( oData.notes ) {
221
        sOut += '<li>' + _('Notes: ') + oData.notes + '</li>';
222
    }
223
224
    sOut += '</ul>';
225
226
    if ( account_offsets.length ) {
227
        sOut +=
228
            '<div class="innerDetails">' +
229
                '<table cellpadding="5" cellspacing="0" border="0" style="margin:10px;">' +
230
                    '<thead>' +
231
                        '<tr><th colspan="99">' + _('Payments applied') + '</th></tr>' +
232
                        '<tr>' +
233
                            '<th>' + _('ID') + '</th>' +
234
                            '<th>' + _('Created on') + '</th>' +
235
                            '<th>' + _('Payment amount') + '</th>' +
236
                            '<th>' + _('Applied amount') + '</th>' +
237
                            '<th>' + _('Type') + '</th>' +
238
                            '<th>' + _('Notes') + '</th>' +
239
                        '</tr>' +
240
                    '</thead>' +
241
                    '<tbody>';
242
243
        for ( var i = 0; i < account_offsets.length; i++ ) {
244
            ao = account_offsets[i];
245
            sOut +=
246
            '<tr>' +
247
                '<td>' + ao.credit_id + '</td>' +
248
                '<td>' + ao.created_on + '</td>' +
249
                '<td>' + ao.credit.amount_paid + '</td>' +
250
                '<td>' + ao.amount + '</td>' +
251
                '<td>' + STRINGS['CreditTypes'][ao.credit.type] + '</td>' +
252
                '<td>' + ao.credit.notes + '</td>' +
253
            '</tr>';
254
        }
255
256
        sOut +=
257
            '</tbody>'+
258
            '</table>';
259
    }
260
261
    sOut +=
262
        '</div>';
263
264
    return sOut;
265
}
266
267
function fnFormatCreditDetails( creditsTable, nTr ) {
268
    var oData = creditsTable.fnGetData( nTr );
269
270
    var sOut = '<div class="innerDetails" style="display:none;">';
271
272
    sOut += '<button class="credit_print btn btn-small" style="margin:5px;" onclick="accountPrint(\'credit\',' + oData.credit_id + ')">' +
273
                '<i class="icon-print"></i> ' + _('Print receipt') +
274
            '</button>';
275
276
    var account_offsets = oData.account_offsets;
277
278
    if ( account_offsets.length ) {
279
        sOut +=
280
                '<table cellpadding="5" cellspacing="0" border="0" style="margin:10px;">' +
281
                    '<thead>' +
282
                        '<tr><th colspan="99">' + _('Fees paid') + '</th></tr>' +
283
                        '<tr>' +
284
                            '<th>' + _('ID') + '</th>' +
285
                            '<th>' + _('Description') + '</th>' +
286
                            '<th>' + _('Type') + '</th>' +
287
                            '<th>' + _('Amount') + '</th>' +
288
                            '<th>' + _('Remaining') + '</th>' +
289
                            '<th>' + _('Created on') + '</th>' +
290
                            '<th>' + _('Updated on') + '</th>' +
291
                            '<th>' + _('Notes') + '</th>' +
292
                        '</tr>' +
293
                    '</thead>' +
294
                    '<tbody>';
295
296
        for ( var i = 0; i < account_offsets.length; i++ ) {
297
            ao = account_offsets[i];
298
            sOut +=
299
            '<tr>' +
300
                '<td>' + ao.debit.debit_id + '</td>' +
301
                '<td>' + ao.debit.description + '</td>' +
302
                '<td>' + STRINGS['DebitTypes'][ao.debit.type] + '</td>' +
303
                '<td>' + ao.debit.amount_original + '</td>' +
304
                '<td>' + ao.debit.amount_outstanding + '</td>' +
305
                '<td>' + ao.debit.created_on + '</td>' +
306
                '<td>' + ao.debit.updated_on + '</td>' +
307
                '<td>' + ao.debit.notes + '</td>' +
308
            '</tr>';
309
        }
310
311
        sOut +=
312
            '</tbody>'+
313
            '</table>';
314
    }
315
316
    sOut +=
317
        '</div>';
318
319
    return sOut;
320
}
321
322
function accountPrint( type, id ) {
323
    window.open( '/cgi-bin/koha/members/account_print.pl?type=' + type + '&id=' + id );
324
}
325
//]]>
326
</script>
327
</head>
328
<body>
329
[% INCLUDE 'header.inc' %]
330
[% INCLUDE 'patron-search.inc' %]
331
332
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; Account for [% INCLUDE 'patron-title.inc' %]</div>
333
334
<div id="doc3" class="yui-t2">
335
    <div id="bd">
336
           <div id="yui-main">
337
                <div class="yui-b">
338
                [% INCLUDE 'members-toolbar.inc' %]
339
340
                <div class="statictabs">
341
                    <ul>
342
                        <li class="active">
343
                            <a href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Account</a>
344
                        </li>
345
346
                        <li>
347
                            <a href="/cgi-bin/koha/members/account_payment.pl?borrowernumber=[% borrowernumber %]" >Pay fines</a>
348
                        </li>
349
350
                        <li>
351
                            <a href="/cgi-bin/koha/members/account_debit.pl?borrowernumber=[% borrowernumber %]" >Create manual invoice</a>
352
                        </li>
353
354
                        <li>
355
                            <a href="/cgi-bin/koha/members/account_credit.pl?borrowernumber=[% borrowernumber %]" >Create manual credit</a>
356
                        </li>
357
                    </ul>
358
                </div>
359
360
                <div class="tabs-container">
361
362
                    <p>
363
                        <h3>Account balance: [% borrower.account_balance | $Currency %]</h3>
364
                    </p>
365
366
                    <div>
367
                        <div id="account-debits">
368
                            <a id="account-debits-switcher" href="#" onclick="return false">View payments</a>
369
                            <table cellpadding="0" cellspacing="0" border="0" class="display" id="debits-table">
370
                                <thead>
371
                                    <tr>
372
                                        <th colspan="99">Fees</th>
373
                                    </tr>
374
                                    <tr>
375
                                        <th></th>
376
                                        <th>ID</th>
377
                                        <th>Description</th>
378
                                        <th>Type</th>
379
                                        <th>Amount</th>
380
                                        <th>Outsanding</th>
381
                                        <th>Created on</th>
382
                                        <th>Updated on</th>
383
                                    </tr>
384
                                </thead>
385
                                <tbody></tbody>
386
                            </table>
387
                        </div>
388
389
                        <div id="account-credits">
390
                            <a id="account-credits-switcher" href="#"  onclick="return false">View fees</a>
391
                            <table cellpadding="0" cellspacing="0" border="0" class="display" id="credits-table">
392
                                <thead>
393
                                    <tr>
394
                                        <th colspan="99">Payments</th>
395
                                    </tr>
396
                                    <tr>
397
                                        <th></th>
398
                                        <th>ID</th>
399
                                        <th>Notes</th>
400
                                        <th>Type</th>
401
                                        <th>Amount</th>
402
                                        <th>Remaining</th>
403
                                        <th>Created on</th>
404
                                        <th>Updated on</th>
405
                                    </tr>
406
                                </thead>
407
                                <tbody></tbody>
408
                            </table>
409
                        </div>
410
                    </div>
411
                </div>
412
            </div>
413
        </div>
414
415
    <div class="yui-b">
416
        [% INCLUDE 'circ-menu.inc' %]
417
    </div>
418
</div>
419
[% INCLUDE 'intranet-bottom.inc' %]
420
421
[% BLOCK format_data %]
422
    [% FOREACH key IN data.result_source.columns %]
423
        [% IF key.match('^amount') %]
424
            "[% key %]": "[% data.$key FILTER $Currency highlight => highlight %]",
425
        [% ELSIF key.match('_on$') %]
426
            "[% key %]": "[% data.$key | $KohaDates %]",
427
        [% ELSE %]
428
            "[% key %]": "[% data.$key %]",
429
        [% END %]
430
    [% END %]
431
[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/account_credit.tt (+92 lines)
Line 0 Link Here
1
[% SET accounts_view = 1 %]
2
[% INCLUDE 'doc-head-open.inc' %]
3
<title>Koha &rsaquo; Borrowers &rsaquo; Create manual credit</title>
4
[% INCLUDE 'doc-head-close.inc' %]
5
<script type="text/javascript">
6
//<![CDATA[
7
$(document).ready(function(){
8
        $('#account_credit').preventDoubleFormSubmit();
9
        $("fieldset.rows input").addClass("noEnterSubmit");
10
});
11
//]]>
12
</script>
13
</head>
14
<body id="pat_account_credit" class="pat">
15
    [% INCLUDE 'header.inc' %]
16
    [% INCLUDE 'patron-search.inc' %]
17
18
    <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; Manual credit</div>
19
20
    <div id="doc3" class="yui-t2">
21
        <div id="bd">
22
               <div id="yui-main">
23
            <div class="yui-b">
24
                    [% INCLUDE 'members-toolbar.inc' %]
25
26
                    <div class="statictabs">
27
                        <ul>
28
                            <li><a href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Account</a></li>
29
                            <li><a href="/cgi-bin/koha/members/account_payment.pl?borrowernumber=[% borrowernumber %]" >Pay fines</a></li>
30
                            <li><a href="/cgi-bin/koha/members/account_debit.pl?borrowernumber=[% borrowernumber %]" >Create manual invoice</a></li>
31
                            <li class="active"><a href="/cgi-bin/koha/members/account_credit.pl?borrowernumber=[% borrowernumber %]" >Create manual credit</a></li>
32
                        </ul>
33
34
                        <div class="tabs-container">
35
36
                            <form action="/cgi-bin/koha/members/account_credit_do.pl" method="post" id="account_credit">
37
                                <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" />
38
39
                                <fieldset class="rows">
40
                                    <legend>Manual credit</legend>
41
42
                                    <ol>
43
                                        <li>
44
                                            <label for="type">Credit Type: </label>
45
                                            <select name="type" id="type">
46
                                                <option value="CREDIT">Credit</option>
47
                                                <option value="FORGIVEN">Forgiven</option>
48
                                                [% FOREACH c IN credit_types_loop %]
49
                                                    <option value="[% c.authorised_value %]">[% c.lib %]</option>
50
                                                [% END %]
51
                                            </select>
52
                                        </li>
53
54
                                        <li>
55
                                            <label for="barcode">Barcode: </label>
56
                                            <input type="text" name="barcode" id="barcode" />
57
                                        </li>
58
59
                                        <li>
60
                                            <label for="desc">Description: </label>
61
                                            <input type="text" name="desc" size="50" id="desc" />
62
                                        </li>
63
64
                                        <li>
65
                                            <label for="note">Note: </label>
66
                                            <input type="text" name="note" size="50" id="note" />
67
                                        </li>
68
69
                                        <li>
70
                                            <label for="amount">Amount: </label>
71
                                            <input type="text" name="amount" id="amount" />
72
                                            Example: 5.00
73
                                        </li>
74
                                    </ol>
75
76
                                </fieldset>
77
78
                                <fieldset class="action">
79
                                    <input type="submit" name="add" value="Add credit" />
80
                                    <a class="cancel" href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Cancel</a>
81
                                </fieldset>
82
                            </form>
83
84
                        </div>
85
                    </div>
86
                </div>
87
            </div>
88
        <div class="yui-b">
89
            [% INCLUDE 'circ-menu.inc' %]
90
        </div>
91
    </div>
92
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/account_debit.tt (+109 lines)
Line 0 Link Here
1
[% SET accounts_view = 1 %]
2
[% INCLUDE 'doc-head-open.inc' %]
3
<title>Koha &rsaquo; Borrowers &rsaquo; Create manual invoice</title>
4
[% INCLUDE 'doc-head-close.inc' %]
5
<script type="text/javascript">
6
//<![CDATA[
7
$(document).ready(function(){
8
    $('#maninvoice').preventDoubleFormSubmit();
9
    $("fieldset.rows input").addClass("noEnterSubmit");
10
11
    var type_fees = new Array();
12
    type_fees['L'] = '';
13
    type_fees['F'] = '';
14
    type_fees['A'] = '';
15
    type_fees['N'] = '';
16
    type_fees['M'] = '';
17
    [% FOREACH invoice_types_loo IN invoice_types_loop %]
18
        type_fees['[% invoice_types_loo.authorised_value %]'] = "[% invoice_types_loo.lib %]";
19
    [% END %]
20
});
21
//]]>
22
</script>
23
</head>
24
25
<body>
26
    [% INCLUDE 'header.inc' %]
27
    [% INCLUDE 'patron-search.inc' %]
28
29
    <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; Manual invoice</div>
30
31
    <div id="doc3" class="yui-t2">
32
        <div id="bd">
33
            <div id="yui-main">
34
                <div class="yui-b">
35
                    [% INCLUDE 'members-toolbar.inc' %]
36
37
                    <div class="statictabs">
38
                    <ul>
39
                        <li><a href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Account</a></li>
40
                        <li><a href="/cgi-bin/koha/members/account_payment.pl?borrowernumber=[% borrowernumber %]" >Pay fines</a></li>
41
                        <li class="active"><a href="/cgi-bin/koha/members/account_debit.pl?borrowernumber=[% borrowernumber %]" >Create manual invoice</a></li>
42
                        <li><a href="/cgi-bin/koha/members/account_credit.pl?borrowernumber=[% borrowernumber %]" >Create manual credit</a></li>
43
                    </ul>
44
                    <div class="tabs-container">
45
46
                    <form action="/cgi-bin/koha/members/account_debit_do.pl" method="post" id="account_debit">
47
                        <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" />
48
49
                        <fieldset class="rows">
50
                            <legend>Manual Invoice</legend>
51
52
                            <ol>
53
                                <li>
54
                                    <label for="type">Type: </label>
55
                                    <select name="type" id="type">
56
                                        <option value="LOST">Lost item</option>
57
                                        <option value="FINE">Fine</option>
58
                                        <option value="ACCOUNT_MANAGEMENT_FEE">Account management fee</option>
59
                                        <option value="NEW_CARD">New card</option>
60
                                        <option value="SUNDRY">Sundry</option>
61
62
                                        [% FOREACH invoice_types_loo IN invoice_types_loop %]
63
                                            <option value="[% invoice_types_loo.authorised_value %]">[% invoice_types_loo.lib %]</option>
64
                                        [% END %]
65
                                    </select>
66
                                </li>
67
68
                                <!-- TODO: Write ajax barcode validator that appends the itemnumber for this form in a hidden input -->
69
                                 <li>
70
                                    <label for="barcode">Barcode: </label>
71
                                    <input type="text" name="barcode" id="barcode" />
72
                                </li>
73
74
                                <li>
75
                                    <label for="description">Description: </label>
76
                                    <input type="text" name="description" id="description" size="50" />
77
                                </li>
78
79
                                <li>
80
                                    <label for="notes">Notes: </label>
81
                                    <input type="text" name="notes" size="50" id="notes" />
82
                                </li>
83
84
                                <li>
85
                                    <label for="amount">Amount: </label>
86
                                    <input type="text" name="amount" id="amount" /> Example: 5.00
87
                                </li>
88
89
                            </ol>
90
                        </fieldset>
91
92
                        <fieldset class="action">
93
                            <input type="submit" name="add" value="Save" />
94
                            <a class="cancel" href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Cancel</a>
95
                        </fieldset>
96
97
                    </form>
98
99
                </div>
100
            </div>
101
        </div>
102
    </div>
103
104
<div class="yui-b">
105
  [% INCLUDE 'circ-menu.inc' %]
106
</div>
107
108
</div>
109
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/account_payment.tt (+226 lines)
Line 0 Link Here
1
[% SET accounts_view = 1 %]
2
[% USE Currency %]
3
[% INCLUDE 'doc-head-open.inc' %]
4
<title>Koha &rsaquo; Patrons &rsaquo; Pay Fines for  [% borrower.firstname %] [% borrower.surname %]</title>
5
[% INCLUDE 'doc-head-close.inc' %]
6
[% INCLUDE 'browser-strings.inc' %]
7
<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
8
<script type= "text/javascript">
9
//<![CDATA[
10
$( document ).ready(function() {
11
    // Convert codes to translated strings
12
    $(".debit-type").each(function() {
13
        $(this).html( STRINGS['DebitTypes'][ $(this).html() ] );
14
    });
15
16
    // Show amount recieved only if the "Receive different amount" checkbox is checked
17
    $("#amount-received-p").hide();
18
    $("#receive_different_amount").click(function() {
19
        if( $(this).is(':checked')) {
20
            $("#amount-received-p").show();
21
            $("#amount_received").focus();
22
        } else {
23
            $("#amount-received-p").hide();
24
        }
25
    });
26
27
    $("#amount_received").keyup(function() {
28
        // Allow only numbers in ammount received
29
        $(this).val($(this).val().replace(/[^\d.]/g, ''));
30
31
        // Make sure the amount recieved is greater than the amount to pay if it is being used
32
        if ( $("#amount_to_pay").val() && parseFloat( $("#amount_received").val() ) < parseFloat( $("#amount_to_pay").val() ) ) {
33
            $("#process").attr('disabled','disabled');
34
        } else {
35
            $("#process").removeAttr('disabled');
36
        }
37
    });
38
39
    // Allow only numbers in ammount to pay
40
    $("#amount_to_pay").keyup(function() {
41
        var $this = $(this);
42
        $this.val($this.val().replace(/[^\d.]/g, ''));
43
    });
44
45
    // Enable the "Select all/Clear all" links
46
    $('#CheckAll').click(function() {
47
        $("input[name='debit_id']" ).prop('checked', true).trigger("change");
48
    });
49
    $('#ClearAll').click(function() {
50
        $("input[name='debit_id']" ).prop('checked', false).trigger("change");
51
    });
52
53
    // Update the "amount to pay" field whenever a fee checkbox is changed
54
    // Note, this is just a payment suggestion and can be changed to any amount
55
    $("input[name='debit_id']" ).change(function() {
56
        var sum = 0;
57
        $("input[name='debit_id']:checked" ).each(function(i,n){
58
            sum += parseFloat( $( "#amount_outstanding_" + $(this).val() ).val() );
59
        });
60
        $('#amount_to_pay').val( sum );
61
    });
62
});
63
64
function checkForm(){
65
    // If using the "amount to receive" field, make sure the librarian is recieving at
66
    // least enough to pay those fees.
67
    if ( $('#amount_received').val() ) {
68
        if ( parseFloat( $('#amount_received').val() ) < parseFloat( $('#amount_to_pay').val() ) ) {
69
            alert( _("Cannot pay more than receieved!") );
70
            return false;
71
        }
72
    }
73
74
    return true;
75
}
76
//]]>
77
</script>
78
</head>
79
<body id="pat_pay" class="pat">
80
    [% INCLUDE 'header.inc' %]
81
    [% INCLUDE 'patron-search.inc' %]
82
83
    <div id="breadcrumbs">
84
        <a href="/cgi-bin/koha/mainpage.pl">Home</a>
85
        &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>
86
        &rsaquo; Pay fines for [% borrower.firstname %] [% borrower.surname %]
87
    </div>
88
89
    <div id="doc3" class="yui-t2">
90
        <div id="bd">
91
            <div id="yui-main">
92
                <div class="yui-b">
93
                    [% INCLUDE 'members-toolbar.inc' borrowernumber=borrower.borrowernumber %]
94
95
                    <div class="statictabs">
96
                        <ul>
97
                            <li><a href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrower.borrowernumber %]">Account</a></li>
98
                            <li class="active"><a href="/cgi-bin/koha/members/account_payment.pl?borrowernumber=[% borrower.borrowernumber %]" >Pay fines</a></li>
99
                            <li><a href="/cgi-bin/koha/members/account_debit.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual invoice</a></li>
100
                            <li><a href="/cgi-bin/koha/members/account_credit.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual credit</a></li>
101
                        </ul>
102
103
                        <div class="tabs-container">
104
105
                        [% IF ( debits ) %]
106
                            <form action="/cgi-bin/koha/members/account_payment_do.pl" method="post" id="account-payment-form" onsubmit="return checkForm()">
107
108
                                <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrower.borrowernumber %]" />
109
110
                                <p>
111
                                    <span class="checkall">
112
                                        <a id="CheckAll" href="#">Select all</a>
113
                                    </span>
114
115
                                    |
116
117
                                    <span class="clearall">
118
                                        <a id="ClearAll" href="#">Clear all</a>
119
                                    </span>
120
                                </p>
121
122
                                <table id="finest">
123
                                    <thead>
124
                                        <tr>
125
                                            <th>&nbsp;</th>
126
                                            <th>Description</th>
127
                                            <th>Account type</th>
128
                                            <th>Original amount</th>
129
                                            <th>Amount outstanding</th>
130
                                        </tr>
131
                                    </thead>
132
133
                                    <tbody>
134
                                        [% SET total_due = 0 %]
135
                                        [% FOREACH d IN debits %]
136
                                            [% SET total_due = total_due + d.amount_outstanding %]
137
                                            <tr>
138
                                                <td>
139
                                                    <input type="checkbox" checked="checked" name="debit_id" value="[% d.debit_id %]" />
140
                                                </td>
141
142
                                                <td>
143
                                                    [% d.description %]
144
145
                                                    [% IF d.notes %]
146
                                                        ( <i>[% d.notes %]</i> )
147
                                                    [% END %]
148
                                                </td>
149
150
                                                <td>
151
                                                    <span class="debit-type">[% d.type %]</span>
152
                                                </td>
153
154
                                                <td class="debit">
155
                                                    [% d.amount_original | $Currency %]
156
                                                    <input type="hidden" id="amount_original_[% d.debit_id %]" value="[% Currency.format_without_symbol( d.amount_original ) %]" />
157
                                                </td>
158
159
                                                <td class="debit">
160
                                                    [% d.amount_outstanding | $Currency %]
161
                                                    <input type="hidden" id="amount_outstanding_[% d.debit_id %]" value="[% Currency.format_without_symbol( d.amount_outstanding ) %]" />
162
                                                </td>
163
                                            </tr>
164
                                        [% END %]
165
                                    </tbody>
166
167
                                    <tfoot>
168
                                        <tr>
169
                                            <td class="total" colspan="4">Total Due:</td>
170
                                            <td>[% total_due | $Currency %]</td>
171
                                        </tr>
172
                                    </tfoot>
173
174
                                </table>
175
176
                                <fieldset>
177
                                    <p>
178
                                        <label for="amount_to_pay">Amount to pay: [% Currency.symbol() %]</label>
179
                                        <input type="text" name="amount_to_pay" id="amount_to_pay" value="[% Currency.format_without_symbol( total_due ) %]" />
180
181
                                        <input type="checkbox" id="receive_different_amount" />
182
                                        <label for="receive_different_amount"><i>Receive different amount</i></label>
183
                                    </p>
184
185
                                    <p id="amount-received-p">
186
                                        <label for="amount_received">Amount recieved: [% Currency.symbol() %]</label>
187
                                        <input type="text" name="amount_received" id="amount_received" />
188
                                    </p>
189
190
                                    <p>
191
                                        <label for="type">Type:</label>
192
                                        <select id="type" name="type">
193
                                            <option value="PAYMENT">Payment</option>
194
                                            <option value="WRITEOFF">Writeoff</option>
195
                                        </select>
196
                                    </p>
197
198
                                    <p>
199
                                        <label for="notes">Payment notes:</label>
200
                                        <input type="textbox" name="notes" id="notes" />
201
                                    <p>
202
                                </fieldset>
203
204
                                <fieldset class="action">
205
                                    <input type="submit" id="process" value="Process" class="submit" />
206
                                    <a class="cancel" href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrower.borrowernumber %]">Cancel</a>
207
                                </fieldset>
208
209
                            </form>
210
211
                        [% ELSE %]
212
                            <p>
213
                                [% borrower.firstname %] [% borrower.surname %] has no outstanding fines.
214
                            </p>
215
                        [% END %]
216
217
                    </div>
218
                </div>
219
            </div>
220
        </div>
221
222
        <div class="yui-b">
223
            [% INCLUDE 'circ-menu.tt' %]
224
        </div>
225
    </div>
226
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/account_print.tt (+146 lines)
Line 0 Link Here
1
[% USE KohaDates %]
2
[% USE Currency %]
3
[% USE EncodeUTF8 %]
4
[% INCLUDE 'doc-head-open.inc' %]
5
<title>Print Receipt for [% cardnumber %]</title>
6
[% INCLUDE 'doc-head-close.inc' %]
7
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
<link rel="shortcut icon" href="[% IF ( IntranetFavicon ) %][% IntranetFavicon %][% ELSE %][% interface %]/[% theme %]/img/favicon.ico[% END %]" type="image/x-icon" />
9
<script type="text/javascript">
10
    function printThenClose() {
11
        window.print();
12
        window.close();
13
    }
14
</script>
15
</head>
16
17
[% SET account = debit || credit %]
18
[% SET borrower = account.borrower %]
19
20
<body id="account-print-body" onload="printThenClose();">
21
22
    <table>
23
        <thead>
24
            <tr>
25
                <th colspan="99">
26
                    [% IF debit %]
27
                        Invoice
28
                    [% ELSIF credit %]
29
                        Payment receipt
30
                    [% END %]
31
                </th>
32
            </tr>
33
34
            <tr>
35
                <th colspan="99">
36
                    [% borrower.branch.branchname | $EncodeUTF8 %]
37
                </th>
38
            </tr>
39
40
            <tr>
41
                <th>Name:</th>
42
                <th colspan="99">[% borrower.firstname | $EncodeUTF8 %] [% borrower.surname | $EncodeUTF8 %]</th>
43
            </tr>
44
45
            <tr>
46
                <th>Card number:</th>
47
                <th colspan="99">[% borrower.cardnumber %]</th>
48
            </tr>
49
50
            <tr>
51
                <th>Date:</th>
52
                <th colspan="99">[% account.created_on | $KohaDates %]</th>
53
            </tr>
54
55
            [% IF account.description %]
56
                <tr>
57
                    <th>Description:</th>
58
                    <th colspan="99">[% account.description | $EncodeUTF8 %]</th>
59
                </tr>
60
            [% END %]
61
62
            [% IF credit %]
63
                <tr>
64
                    <th>Amount paid:</th>
65
                    <th colspan="99">[% credit.amount_paid | $Currency highlight => type %]</th>
66
                </tr>
67
                [% IF credit.amount_received %]
68
                    <tr>
69
                        <th>Amount received:</th>
70
                        <th colspan="99">[% credit.amount_received | $Currency highlight => type %]</th>
71
                    </tr>
72
                    <tr>
73
                        <th>Change due:</th>
74
                        <th colspan="99">[% credit.amount_received - credit.amount_paid | $Currency highlight => type %]</th>
75
                    </tr>
76
                [% END %]
77
                <tr>
78
                    <th>Balance:</th>
79
                    <th colspan="99">[% credit.amount_remaining | $Currency highlight => type %]</th>
80
                </tr>
81
                [% IF credit.account_offsets %]
82
                    <tr>
83
                        <th colspan="99">Fees paid</th>
84
                    </tr>
85
                    <tr>
86
                        <th>Description</th>
87
                        <th>Type</th>
88
                        <th>Amount</th>
89
                        <th>Paid</th>
90
                        <th>Outstanding</th>
91
                        <th>Date</th>
92
                    </tr>
93
                [% END %]
94
            [% ELSIF debit %]
95
                <tr>
96
                    <th>Amount:</th>
97
                    <th colspan="99">[% debit.amount_original | $Currency highlight => type %]</th>
98
                </tr>
99
                <tr>
100
                    <th>Outstanding:</th>
101
                    <th colspan="99">[% debit.amount_outstanding | $Currency highlight => type %]</th>
102
                </tr>
103
                [% IF debit.account_offsets %]
104
                    <tr>
105
                        <th colspan="99">Payments applied</th>
106
                    </tr>
107
                    <tr>
108
                        <th>Date</th>
109
                        <th>Type</th>
110
                        <th>Payment</th>
111
                        <th>Applied</th>
112
                        <th>Balance</th>
113
                        <th>Notes</th>
114
                    </tr>
115
                [% END %]
116
            [% END %]
117
        </thead>
118
119
        <tbody>
120
            [% IF credit.account_offsets %]
121
                [% FOREACH ao IN credit.account_offsets %]
122
                    <tr>
123
                        <td>[% ao.debit.description %]</td>
124
                        <td>[% ao.debit.type %]</td>
125
                        <td>[% ao.debit.amount_original | $Currency highlight => 'debit' %]</td>
126
                        <td>[% ao.amount | $Currency highlight => 'offset' %]</td>
127
                        <td>[% ao.debit.amount_outstanding | $Currency highlight => 'debit' %]</td>
128
                        <td>[% ao.debit.created_on | $KohaDates %]</td>
129
                    </tr>
130
                [% END %]
131
            [% ELSIF debit.account_offsets %]
132
                [% FOREACH ao IN debit.account_offsets %]
133
                    <tr>
134
                        <td>[% ao.credit.type %]</td>
135
                        <td>[% ao.credit.created_on | $KohaDates %]</td>
136
                        <td>[% ao.credit.amount_paid | $Currency highlight => 'credit' %]</td>
137
                        <td>[% ao.amount | $Currency highlight => 'offset' %]</td>
138
                        <td>[% ao.credit.amount_remaining | $Currency highlight => 'credit' %]</td>
139
                        <td>[% ao.credit.notes %]</td>
140
                    </tr>
141
                [% END %]
142
            [% END %]
143
        </tbody>
144
    </table>
145
146
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt (-99 lines)
Lines 1-99 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Patrons &rsaquo; Account for [% INCLUDE 'patron-title.inc' %]</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
</head>
5
<body id="pat_borraccount" class="pat">
6
[% INCLUDE 'header.inc' %]
7
[% INCLUDE 'patron-search.inc' %]
8
9
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; Account for [% INCLUDE 'patron-title.inc' %]</div>
10
11
<div id="doc3" class="yui-t2">
12
   
13
   <div id="bd">
14
	<div id="yui-main">
15
	<div class="yui-b">
16
[% INCLUDE 'members-toolbar.inc' %]
17
<form action="/cgi-bin/koha/members/boraccount.pl" method="get"><input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" /></form>
18
19
<!-- The manual invoice and credit buttons -->
20
<div class="statictabs">
21
<ul>
22
    <li class="active"><a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Account</a></li>
23
	<li><a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrowernumber %]" >Pay fines</a></li>
24
	<li><a href="/cgi-bin/koha/members/maninvoice.pl?borrowernumber=[% borrowernumber %]" >Create manual invoice</a></li>
25
	<li><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% borrowernumber %]" >Create manual credit</a></li>
26
</ul>
27
<div class="tabs-container">
28
<!-- The table with the account items -->
29
<table>
30
  <tr>
31
  	<th>Date</th>
32
    <th>Description of charges</th>
33
    <th>Note</th>
34
    <th>Amount</th>
35
    <th>Outstanding</th>
36
    [% IF ( reverse_col ) %]
37
    <th>&nbsp;</th>
38
    [% END %]
39
    <th>Print</th>
40
  </tr>
41
42
	<!-- FIXME: Shouldn't hardcode dollar signs, since Euro or Pound might be needed -->
43
  [% FOREACH account IN accounts %]
44
45
   [% IF ( loop.odd ) %]<tr>[% ELSE %]<tr class="highlight">[% END %]
46
      <td>[% account.date %]</td>
47
      <td>[% account.description %]&nbsp;[% IF ( account.itemnumber ) %]<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% account.biblionumber %]&amp;itemnumber=[% account.itemnumber %]">View item</a>&nbsp;[% END %][% account.title |html %]</td>
48
      <td>[% account.note | html_line_break %]</td>
49
      [% IF ( account.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amount %]</td>
50
      [% IF ( account.amountoutstandingcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amountoutstanding %]</td>
51
    [% IF ( reverse_col ) %]
52
      <td>
53
	[% IF ( account.payment ) %]
54
		<a href="boraccount.pl?action=reverse&amp;accountlines_id=[% account.accountlines_id %]&amp;borrowernumber=[% account.borrowernumber %]">Reverse</a>
55
	[% ELSE %]
56
		&nbsp;
57
	[% END %]
58
      </td>
59
	[% END %]
60
<td>
61
	[% IF ( account.payment ) %]
62
		<a target="_blank" href="printfeercpt.pl?action=print&amp;accountlines_id=[% account.accountlines_id %]&amp;borrowernumber=[% account.borrowernumber %]">Print</a>
63
	[% ELSE %]
64
		<a target="_blank" href="printinvoice.pl?action=print&amp;accountlines_id=[% account.accountlines_id %]&amp;borrowernumber=[% account.borrowernumber %]">Print</a>
65
	[% END %]
66
      </td>
67
    </tr>
68
69
  [% END %]
70
<tfoot>
71
  <tr>
72
    <td colspan="4">Total due</td>
73
    [% IF ( totalcredit ) %]
74
      [% IF ( reverse_col ) %]
75
        <td colspan="3" class="credit">
76
      [% ELSE %]
77
        <td colspan="2" class="credit">
78
      [% END %]
79
    [% ELSE %]
80
      [% IF ( reverse_col ) %]
81
        <td colspan="3" class="debit">
82
      [% ELSE %]
83
        <td colspan="2" class="credit">
84
      [% END %]
85
    [% END %]
86
    [% total %]</td>
87
  </tr>
88
  </tfoot>
89
</table>
90
</div></div>
91
92
</div>
93
</div>
94
95
<div class="yui-b">
96
[% INCLUDE 'circ-menu.inc' %]
97
</div>
98
</div>
99
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/mancredit.tt (-6 / +6 lines)
Lines 26-39 $(document).ready(function(){ Link Here
26
<!-- The manual invoice and credit buttons -->
26
<!-- The manual invoice and credit buttons -->
27
<div class="statictabs">
27
<div class="statictabs">
28
<ul>
28
<ul>
29
	<li><a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Account</a></li>
29
   <li><a href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Account</a></li>
30
	<li><a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrowernumber %]" >Pay fines</a></li>
30
    <li><a href="/cgi-bin/koha/members/account_payment.pl?borrowernumber=[% borrowernumber %]" >Pay fines</a></li>
31
	<li><a href="/cgi-bin/koha/members/maninvoice.pl?borrowernumber=[% borrowernumber %]" >Create manual invoice</a></li>
31
 <li><a href="/cgi-bin/koha/members/account_debit.pl?borrowernumber=[% borrowernumber %]" >Create manual invoice</a></li>
32
    <li class="active"><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% borrowernumber %]" >Create manual credit</a></li>
32
    <li class="active"><a href="/cgi-bin/koha/members/account_credit.pl?borrowernumber=[% borrowernumber %]" >Create manual credit</a></li>
33
</ul>
33
</ul>
34
<div class="tabs-container">
34
<div class="tabs-container">
35
35
36
<form action="/cgi-bin/koha/members/mancredit.pl" method="post" id="mancredit">
36
<form action="/cgi-bin/koha/members/account_credit.pl" method="post" id="mancredit">
37
<input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" />
37
<input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" />
38
38
39
<fieldset class="rows">
39
<fieldset class="rows">
Lines 48-54 $(document).ready(function(){ Link Here
48
	<li><label for="amount">Amount: </label><input type="text" name="amount" id="amount" /> Example: 5.00</li>
48
	<li><label for="amount">Amount: </label><input type="text" name="amount" id="amount" /> Example: 5.00</li>
49
</ol></fieldset>
49
</ol></fieldset>
50
50
51
<fieldset class="action"><input type="submit" name="add" value="Add credit" /> <a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Cancel</a></fieldset>
51
<fieldset class="action"><input type="submit" name="add" value="Add credit" /> <a class="cancel" href="/cgi-bin/koha/members/account.pl?borrowernumber=[% borrowernumber %]">Cancel</a></fieldset>
52
</form>
52
</form>
53
53
54
</div></div>
54
</div></div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/maninvoice.tt (-87 lines)
Lines 1-87 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Borrowers &rsaquo; Create manual invoice</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
<script type="text/javascript">
5
//<![CDATA[
6
$(document).ready(function(){
7
        $('#maninvoice').preventDoubleFormSubmit();
8
        $("fieldset.rows input").addClass("noEnterSubmit");
9
});
10
//]]>
11
</script>
12
</head>
13
<body id="pat_maninvoice" class="pat">
14
[% INCLUDE 'header.inc' %]
15
[% INCLUDE 'patron-search.inc' %]
16
17
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; Manual Invoice</div>
18
19
<div id="doc3" class="yui-t2">
20
   
21
   <div id="bd">
22
	<div id="yui-main">
23
	<div class="yui-b">
24
[% INCLUDE 'members-toolbar.inc' %]
25
26
<!-- The manual invoice and credit buttons -->
27
<div class="statictabs">
28
<ul>
29
	<li><a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Account</a></li>
30
	<li><a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrowernumber %]" >Pay fines</a></li>
31
    <li class="active"><a href="/cgi-bin/koha/members/maninvoice.pl?borrowernumber=[% borrowernumber %]" >Create manual invoice</a></li>
32
	<li><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% borrowernumber %]" >Create manual credit</a></li>
33
</ul>
34
<div class="tabs-container">
35
36
[% IF ( ERROR ) %]
37
[% IF ( ITEMNUMBER ) %]
38
  ERROR an invalid itemnumber was entered, please hit back and try again
39
[% END %]
40
[% ELSE %]
41
<form action="/cgi-bin/koha/members/maninvoice.pl" method="post" id="maninvoice"><input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" />
42
	<fieldset class="rows">
43
	<legend>Manual Invoice</legend>
44
	<ol>
45
      <li>
46
<script type="text/javascript">
47
var type_fees = new Array();
48
type_fees['L'] = '';
49
type_fees['F'] = '';
50
type_fees['A'] = '';
51
type_fees['N'] = '';
52
type_fees['M'] = '';
53
[% FOREACH invoice_types_loo IN invoice_types_loop %]
54
type_fees['[% invoice_types_loo.authorised_value %]'] = "[% invoice_types_loo.lib %]";
55
[% END %]
56
</script>
57
        <label for="type">Type: </label>
58
        <select name="type" id="type" onchange="this.form.desc.value=this.options[this.selectedIndex].value; this.form.amount.value=type_fees[this.options[this.selectedIndex].value];">
59
          <option value="L">Lost item</option>
60
          <option value="F">Fine</option>
61
          <option value="A">Account management fee</option>
62
          <option value="N">New card</option>
63
          <option value="M">Sundry</option>
64
          [% FOREACH invoice_types_loo IN invoice_types_loop %]
65
            <option value="[% invoice_types_loo.authorised_value %]">[% invoice_types_loo.authorised_value %]</option>
66
          [% END %]
67
        </select>
68
      </li>
69
	<li><label for="barcode">Barcode: </label><input type="text" name="barcode" id="barcode" /></li>
70
	<li><label for="desc">Description: </label><input type="text" name="desc" id="desc" size="50" /></li>
71
    <li><label for="note">Note: </label><input type="text" name="note" size="50" id="note" /></li>
72
	<li><label for="amount">Amount: </label><input type="text" name="amount" id="amount" /> Example: 5.00</li>
73
	</ol></fieldset>
74
<fieldset class="action"><input type="submit" name="add" value="Save" /> <a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Cancel</a></fieldset>
75
</form>
76
77
[% END %]
78
</div></div>
79
80
</div>
81
</div>
82
83
<div class="yui-b">
84
[% INCLUDE 'circ-menu.inc' %]
85
</div>
86
</div>
87
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/pay.tt (-153 lines)
Lines 1-153 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Patrons &rsaquo; Pay Fines for  [% borrower.firstname %] [% borrower.surname %]</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
5
<script type= "text/javascript">
6
//<![CDATA[
7
function enableCheckboxActions(){
8
    // Enable/disable controls if checkboxes are checked
9
    var checkedBoxes = $("input.cb:checked");
10
    if ($(checkedBoxes).size()) {
11
      $("#payselected").prop("disabled",false);
12
    } else {
13
      $("#payselected").prop("disabled",true);
14
    }
15
}
16
    $(document).ready(function(){
17
 $('#pay-fines-form').preventDoubleFormSubmit();
18
        $("#woall").click(function(event){
19
            var answer = confirm(_("Are you sure you want to write off [% total | format('%.2f') %] in outstanding fines? This cannot be undone!"));
20
                if (!answer){
21
                    event.preventDefault();
22
                }
23
        });
24
        $('#CheckAll').click(function(){
25
            $("#finest").checkCheckboxes();
26
            enableCheckboxActions();
27
            return false;
28
        });
29
        $('#CheckNone').click(function(){
30
            $("#finest").unCheckCheckboxes();
31
            enableCheckboxActions();
32
            return false;
33
        });
34
        $(".cb").change(function(){
35
            enableCheckboxActions();
36
        });
37
        enableCheckboxActions();
38
    });
39
//]]>
40
</script>
41
</head>
42
<body id="pat_pay" class="pat">
43
[% INCLUDE 'header.inc' %]
44
[% INCLUDE 'patron-search.inc' %]
45
46
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; Pay fines for [% borrower.firstname %] [% borrower.surname %]</div>
47
48
<div id="doc3" class="yui-t2">
49
   
50
   <div id="bd">
51
	<div id="yui-main">
52
	<div class="yui-b">
53
[% INCLUDE 'members-toolbar.inc' borrowernumber=borrower.borrowernumber %]
54
55
<!-- The manual invoice and credit buttons -->
56
<div class="statictabs">
57
<ul>
58
	<li><a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrower.borrowernumber %]">Account</a></li>
59
    <li class="active"><a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrower.borrowernumber %]" >Pay fines</a></li>
60
	<li><a href="/cgi-bin/koha/members/maninvoice.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual invoice</a></li>
61
	<li><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual credit</a></li>
62
</ul>
63
<div class="tabs-container">
64
65
[% IF ( accounts ) %]
66
    <form action="/cgi-bin/koha/members/pay.pl" method="post" id="pay-fines-form">
67
	<input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrower.borrowernumber %]" />
68
<p><span class="checkall"><a id="CheckAll" href="#">Select all</a></span> | <span class="clearall"><a id="CheckNone" href="#">Clear all</a></span></p>
69
<table id="finest">
70
<thead>
71
<tr>
72
    <th>&nbsp;</th>
73
    <th>Fines &amp; charges</th>
74
    <th>Description</th>
75
    <th>Payment note</th>
76
    <th>Account type</th>
77
    <th>Notify id</th>
78
    <th>Level</th>
79
    <th>Amount</th>
80
    <th>Amount outstanding</th>
81
</tr>
82
</thead>
83
<tfoot>
84
<tr>
85
    <td class="total" colspan="8">Total Due:</td>
86
    <td>[% total | format('%.2f') %]</td>
87
</tr>
88
</tfoot>
89
<tbody>
90
[% FOREACH account_grp IN accounts %]
91
    [% FOREACH line IN account_grp.accountlines %]
92
<tr>
93
    <td>
94
    [% IF ( line.amountoutstanding > 0 ) %]
95
        <input class="cb" type="checkbox" checked="checked" name="incl_par_[% line.accountno %]" />
96
    [% END %]
97
    </td>
98
    <td>
99
    [% IF ( line.amountoutstanding > 0 ) %]
100
        <input type="submit" name="pay_indiv_[% line.accountno %]" value="Pay" />
101
        <input type="submit" name="wo_indiv_[% line.accountno %]" value="Write off" />
102
    [% END %]
103
    <input type="hidden" name="itemnumber[% line.accountno %]" value="[% line.itemnumber %]" />
104
    <input type="hidden" name="description[% line.accountno %]" value="[% line.description %]" />
105
    <input type="hidden" name="accounttype[% line.accountno %]" value="[% line.accounttype %]" />
106
    <input type="hidden" name="amount[% line.accountno %]" value="[% line.amount %]" />
107
    <input type="hidden" name="accountlines_id[% line.accountno %]" value="[% line.accountlines_id %]" />
108
    <input type="hidden" name="amountoutstanding[% line.accountno %]" value="[% line.amountoutstanding %]" />
109
    <input type="hidden" name="borrowernumber[% line.accountno %]" value="[% line.borrowernumber %]" />
110
    <input type="hidden" name="accountno[% line.accountno %]" value="[% line.accountno %]" />
111
    <input type="hidden" name="notify_id[% line.accountno %]" value="[% line.notify_id %]" />
112
    <input type="hidden" name="notify_level[% line.accountno %]" value="[% line.notify_level %]" />
113
    <input type="hidden" name="totals[% line.accountno %]" value="[% line.totals %]" />
114
    </td>
115
    <td>[% line.description %] ([% line.title |html_entity %])</td>
116
    <td><input type="text" name="payment_note_[% line.accountno %]" /></td>
117
    <td>[% line.accounttype %]</td>
118
    <td>[% line.notify_id %]</td>
119
    <td>[% line.notify_level %]</td>
120
    <td class="debit">[% line.amount | format('%.2f') %]</td>
121
    <td class="debit">[% line.amountoutstanding | format('%.2f') %]</td>
122
</tr>
123
[% END %]
124
[% IF ( account_grp.total ) %]
125
<tr>
126
127
    <td class="total" colspan="8">Sub total:</td>
128
    <td>[% account_grp.total | format('%.2f') %]</td>
129
</tr>
130
[% END %]
131
[% END %]
132
</tbody>
133
</table>
134
<fieldset class="action">
135
<input type="submit" id="paycollect" name="paycollect"  value="Pay amount" class="submit" />
136
<input type="submit" name="woall"  id="woall" value="Write off all" class="submit" />
137
<input type="submit" id="payselected" name="payselected"  value="Pay selected" class="submit" />
138
<a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrower.borrowernumber %]">Cancel</a>
139
</fieldset>
140
</form>
141
[% ELSE %]
142
    <p>[% borrower.firstname %] [% borrower.surname %] has no outstanding fines.</p>
143
[% END %]
144
</div></div>
145
146
</div>
147
</div>
148
149
<div class="yui-b">
150
[% INCLUDE 'circ-menu.tt' %]
151
</div>
152
</div>
153
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tt (-233 lines)
Lines 1-233 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Patrons &rsaquo; Collect fine payment for  [% borrower.firstname %] [% borrower.surname %]</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
<script type= "text/javascript">
5
//<![CDATA[
6
$(document).ready(function() {
7
    $('#payindivfine, #woindivfine, #payfine').preventDoubleFormSubmit();
8
});
9
//]]>
10
</script>
11
<script type= "text/javascript">
12
//<![CDATA[
13
function moneyFormat(textObj) {
14
    var newValue = textObj.value;
15
    var decAmount = "";
16
    var dolAmount = "";
17
    var decFlag   = false;
18
    var aChar     = "";
19
20
    for(i=0; i < newValue.length; i++) {
21
        aChar = newValue.substring(i, i+1);
22
        if (aChar >= "0" && aChar <= "9") {
23
            if(decFlag) {
24
                decAmount = "" + decAmount + aChar;
25
            }
26
            else {
27
                dolAmount = "" + dolAmount + aChar;
28
            }
29
        }
30
        if (aChar == ".") {
31
            if (decFlag) {
32
                dolAmount = "";
33
                break;
34
            }
35
            decFlag = true;
36
        }
37
    }
38
39
    if (dolAmount == "") {
40
        dolAmount = "0";
41
    }
42
// Strip leading 0s
43
    if (dolAmount.length > 1) {
44
        while(dolAmount.length > 1 && dolAmount.substring(0,1) == "0") {
45
            dolAmount = dolAmount.substring(1,dolAmount.length);
46
        }
47
    }
48
    if (decAmount.length > 2) {
49
        decAmount = decAmount.substring(0,2);
50
    }
51
// Pad right side
52
    if (decAmount.length == 1) {
53
       decAmount = decAmount + "0";
54
    }
55
    if (decAmount.length == 0) {
56
       decAmount = decAmount + "00";
57
    }
58
59
    textObj.value = dolAmount + "." + decAmount;
60
}
61
//]]>
62
</script>
63
</head>
64
<body id="pat_paycollect" class="pat">
65
[% INCLUDE 'header.inc' %]
66
[% INCLUDE 'patron-search.inc' %]
67
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; <a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrower.borrowernumber %]">Pay fines for [% borrower.firstname %] [% borrower.surname %]</a> &rsaquo; [% IF ( pay_individual ) %]Pay an individual fine[% ELSIF ( writeoff_individual ) %]Write off an individual fine[% ELSE %][% IF ( selected_accts ) %]Pay an amount toward selected fines[% ELSE %]Pay an amount toward all fines[% END %][% END %]</div>
68
69
<div id="doc3" class="yui-t2">
70
71
<div id="bd">
72
<div id="yui-main">
73
<div class="yui-b">
74
[% INCLUDE 'members-toolbar.inc' borrowernumber=borrower.borrowernumber %]
75
76
77
<!-- The manual invoice and credit buttons -->
78
<div class="statictabs">
79
<ul>
80
    <li>
81
    <a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrower.borrowernumber %]">Account</a>
82
    </li>
83
    <li class="active">
84
    <a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrower.borrowernumber %]" >Pay fines</a>
85
    </li>
86
    <li>
87
    <a href="/cgi-bin/koha/members/maninvoice.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual invoice</a>
88
    </li>
89
    <li>
90
    <a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual credit</a>
91
    </li>
92
</ul>
93
<div class="tabs-container">
94
[% IF ( error_over ) %]
95
    <div id="error_message" class="dialog alert">
96
    You must pay a value less than or equal to [% total_due | format('%.2f') %].
97
    </div>
98
[% END %]
99
100
[% IF ( pay_individual ) %]
101
    <form name="payindivfine" id="payindivfine" onsubmit="return validatePayment(this);" method="post" action="/cgi-bin/koha/members/paycollect.pl">
102
    <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrower.borrowernumber %]" />
103
    <input type="hidden" name="pay_individual" id="pay_individual" value="[% pay_individual %]" />
104
    <input type="hidden" name="itemnumber" id="itemnumber" value="[% itemnumber %]" />
105
    <input type="hidden" name="description" id="description" value="[% description %]" />
106
    <input type="hidden" name="accounttype" id="accounttype" value="[% accounttype %]" />
107
    <input type="hidden" name="notify_id" id="notify_id" value="[% notify_id %]" />
108
    <input type="hidden" name="notify_level" id="notify_level" value="[% notify_level %]" />
109
    <input type="hidden" name="amount" id="amount" value="[% amount %]" />
110
    <input type="hidden" name="amountoutstanding" id="amountoutstanding" value="[% amountoutstanding %]" />
111
    <input type="hidden" name="accountno" id="accountno" value="[% accountno %]" />
112
    <input type="hidden" name="accountlines_id" id="accountlines_id" value="[% accountlines_id %]" />
113
    <input type="hidden" name="title" id="title" value="[% title %]" />
114
115
<fieldset class="rows">
116
    <legend>Pay an individual fine</legend>
117
    <input type="hidden" name="payment_note" id="payment_note" value="[% payment_note %]" />
118
    <table>
119
    <thead><tr>
120
            <th>Description</th>
121
            <th>Account type</th>
122
            <th>Notify id</th>
123
            <th>Level</th>
124
            <th>Amount</th>
125
            <th>Amount outstanding</th>
126
        </tr></thead>
127
    <tfoot>
128
        <td colspan="5">Total amount payable:</td><td>[% amountoutstanding | format('%.2f') %]</td>
129
    </tfoot>
130
    <tbody><tr>
131
            <td>
132
                [% description %] [% title  %]
133
            </td>
134
            <td>[% accounttype %]</td>
135
            <td>[% notify_id %]</td>
136
            <td>[% notify_level %]</td>
137
            <td class="debit">[% amount | format('%.2f') %]</td>
138
            <td class="debit">[% amountoutstanding | format('%.2f') %]</td>
139
        </tr></tbody>
140
</table>
141
142
<ol>
143
144
    <li>
145
        <label for="paid">Collect from patron: </label>
146
            <!-- default to paying all -->
147
        <input name="paid" id="paid" value="[% amountoutstanding | format('%.2f') %]" onchange="moneyFormat(document.payindivfine.paid)"/>
148
    </li>
149
</ol>
150
</fieldset>
151
152
    <div class="action"><input type="submit" name="submitbutton" value="Confirm" />
153
        <a class="cancel" href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrower.borrowernumber %]">Cancel</a></div>
154
    </form>
155
[% ELSIF ( writeoff_individual ) %]
156
    <form name="woindivfine" id="woindivfine" action="/cgi-bin/koha/members/pay.pl" method="post" >
157
    <fieldset class="rows">
158
    <legend>Write off an individual fine</legend>
159
    <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrower.borrowernumber %]" />
160
    <input type="hidden" name="pay_individual" id="pay_individual" value="[% pay_individual %]" />
161
    <input type="hidden" name="itemnumber" id="itemnumber" value="[% itemnumber %]" />
162
    <input type="hidden" name="description" id="description" value="[% description %]" />
163
    <input type="hidden" name="accounttype" id="accounttype" value="[% accounttype %]" />
164
    <input type="hidden" name="notify_id" id="notify_id" value="[% notify_id %]" />
165
    <input type="hidden" name="notify_level" id="notify_level" value="[% notify_level %]" />
166
    <input type="hidden" name="amount" id="amount" value="[% amount %]" />
167
    <input type="hidden" name="amountoutstanding" id="amountoutstanding" value="[% amountoutstanding %]" />
168
    <input type="hidden" name="accountno" id="accountno" value="[% accountno %]" />
169
    <input type="hidden" name="accountlines_id" id="accountlines_id" value="[% accountlines_id %]" />
170
    <input type="hidden" name="title" id="title" value="[% title %]" />
171
    <input type="hidden" name="payment_note" id="payment_note" value="[% payment_note %]" />
172
    <table>
173
    <thead><tr>
174
            <th>Description</th>
175
            <th>Account type</th>
176
            <th>Notify id</th>
177
            <th>Level</th>
178
            <th>Amount</th>
179
            <th>Amount outstanding</th>
180
        </tr></thead>
181
    <tfoot><td colspan="5">Total amount to be written off:</td><td>[% amountoutstanding | format('%.2f') %]</td></tfoot>
182
    <tbody><tr>
183
            <td>[% description %] [% title %]</td>
184
            <td>[% accounttype %]</td>
185
            <td>[% notify_id %]</td>
186
            <td>[% notify_level %]</td>
187
            <td class="debit">[% amount | format('%.2f') %]</td>
188
            <td class="debit">[% amountoutstanding | format('%.2f') %]</td>
189
        </tr></tbody>
190
    </table>
191
    </fieldset>
192
    <div class="action"><input type="submit" name="confirm_writeoff" id="confirm_writeoff" value="Write off this charge" />
193
        <a class="cancel" href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrower.borrowernumber %]">Cancel</a></div>
194
    </form>
195
[% ELSE %]
196
197
    <form name="payfine" id="payfine" onsubmit="return validatePayment(this);" method="post" action="/cgi-bin/koha/members/paycollect.pl">
198
    <input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrower.borrowernumber %]" />
199
    <input type="hidden" name="selected_accts" id="selected_accts" value="[% selected_accts %]" />
200
    <input type="hidden" name="total" id="total" value="[% total %]" />
201
202
    <fieldset class="rows">
203
    [% IF ( selected_accts ) %]<legend>Pay an amount toward selected fines</legend>[% ELSE %]<legend>Pay an amount toward all fines</legend>[% END %]
204
    <ol>
205
        <li>
206
            <span class="label">Total amount outstanding: </span>
207
            <span class="debit">[% total | format('%.2f') %]</span>
208
        </li>
209
    <li>
210
        <label for="paid">Collect from patron: </label>
211
        <!-- default to paying all -->
212
        <input name="paid" id="paid" value="[% total | format('%.2f') %]" onchange="moneyFormat(document.payfine.paid)"/>
213
    </li>
214
    <li>
215
        <label for="selected_accts_notes">Note: </label>
216
        <textarea name="selected_accts_notes" id="selected_accts_notes">[% selected_accts_notes %]</textarea>
217
    </li>
218
    </ol>
219
    </fieldset>
220
    <div class="action"><input type="submit" name="submitbutton" value="Confirm" />
221
        <a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrower.borrowernumber %]">Cancel</a></div>
222
    </form>
223
[% END %]
224
</div></div>
225
</div>
226
</div>
227
228
<div class="yui-b">
229
[% INCLUDE 'circ-menu.tt' %]
230
</div>
231
</div>
232
[% INCLUDE 'intranet-bottom.inc' %]
233
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/printfeercpt.tt (-63 lines)
Lines 1-63 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Print Receipt for [% cardnumber %]</title>
3
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
4
<link rel="shortcut icon" href="[% IF ( IntranetFavicon ) %][% IntranetFavicon %][% ELSE %][% interface %]/[% theme %]/img/favicon.ico[% END %]" type="image/x-icon" />
5
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/printreceiptinvoice.css" />
6
<script type="text/javascript">
7
    function printThenClose() {
8
        window.print();
9
        window.close();
10
    }
11
</script>
12
</head>
13
<body id="pat_printfeercpt" class="pat" onload="printThenClose();">
14
15
<div id="receipt">
16
<!-- The table with the account items -->
17
<table>
18
[% IF ( LibraryName ) %]
19
 <tr>
20
	<th colspan=3 class="centerednames">
21
		<h3>[% LibraryName %]</h3>
22
	</th>
23
 </tr>
24
[% END %]
25
 <tr>
26
	<th colspan=3 class="centerednames">
27
        <h2><u>Fee receipt</u></h2>
28
	</th>
29
 </tr>
30
 <tr>
31
	<th colspan=3 class="centerednames">
32
		[% IF ( branchname ) %]<h2>[% branchname %]</h2>[% END %]
33
	</th>
34
 </tr>
35
 <tr>
36
	<th colspan=3 >
37
		Received with thanks from  [% firstname %] [% surname %] <br />
38
        Card number : [% cardnumber %]<br />
39
	</th>
40
 </tr>
41
  <tr>
42
	<th>Date</th>
43
    <th>Description of charges</th>
44
    <th>Amount</th>
45
 </tr>
46
47
  [% FOREACH account IN accounts %]
48
<tr class="highlight">
49
      <td>[% account.date %]</td>
50
      <td>[% account.description %]</td>
51
      [% IF ( account.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amount %]</td>
52
    </tr>
53
54
  [% END %]
55
<tfoot>
56
  <tr>
57
    <td colspan="2">Total outstanding dues as on date : </td>
58
    [% IF ( totalcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% total %]</td>
59
  </tr>
60
  </tfoot>
61
</table>
62
</div>
63
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/printinvoice.tt (-65 lines)
Lines 1-65 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Print Receipt for [% cardnumber %]</title>
3
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
4
<link rel="shortcut icon" href="[% IF ( IntranetFavicon ) %][% IntranetFavicon %][% ELSE %][% interface %]/[% theme %]/img/favicon.ico[% END %]" type="image/x-icon" />
5
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/printreceiptinvoice.css" />
6
<script type="text/javascript">
7
    function printThenClose() {
8
        window.print();
9
        window.close();
10
    }
11
</script>
12
</head>
13
<body id="printinvoice" class="pat" onload="printThenClose();">
14
15
<div id="receipt">
16
<!-- The table with the account items -->
17
<table>
18
[% IF ( LibraryName ) %]
19
  <tr>
20
    <th colspan="4" class="centerednames">
21
		<h3>[% LibraryName %]</h3>
22
	</th>
23
  </tr>
24
[% END %]
25
  <tr>
26
    <th colspan="4" class="centerednames">
27
		<h2><u>INVOICE</u></h2>
28
	</th>
29
  </tr>
30
  <tr>
31
    <th colspan="4" class="centerednames">
32
		[% IF ( branchname ) %]<h2>[% branchname %]</h2>[% END %]
33
	</th>
34
  </tr>
35
  <tr>
36
    <th colspan="4" >
37
        Bill to: [% firstname %] [% surname %] <br />
38
        Card number: [% cardnumber %]<br />
39
	</th>
40
  </tr>
41
  <tr>
42
	<th>Date</th>
43
    <th>Description of charges</th>
44
    <th style="text-align:right;">Amount</th>
45
    <th style="text-align:right;">Amount outstanding</th>
46
 </tr>
47
48
  [% FOREACH account IN accounts %]
49
<tr class="highlight">
50
      <td>[% account.date %]</td>
51
      <td>[% account.description %]</td>
52
      [% IF ( account.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amount %]</td>
53
      [% IF ( account.amountoutstandingcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amountoutstanding %]</td>
54
    </tr>
55
56
  [% END %]
57
<tfoot>
58
  <tr>
59
    <td colspan="3">Total outstanding dues as on date: </td>
60
    [% IF ( totalcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% total %]</td>
61
  </tr>
62
  </tfoot>
63
</table>
64
</div>
65
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/browser-strings.inc (+34 lines)
Line 0 Link Here
1
[% USE KohaAuthorisedValues %]
2
<script type="text/javascript">
3
//<![CDATA[
4
    var BROWSER_RETURN_TO_SEARCH = _("Return to results");
5
    var BROWSER_PREVIOUS = _("Previous");
6
    var BROWSER_NEXT = _("Next");
7
8
    var STRINGS = {
9
        "DebitTypes": {
10
            "FINE"                      : _("Fine"),
11
            "ACCOUNT_MANAGEMENT_FEE"    : _("Account management fee"),
12
            "SUNDRY"                    : _("Sundry"),
13
            "LOST"                      : _("Lost item"),
14
            "HOLD"                      : _("Hold fee"),
15
            "RENTAL"                    : _("Rental fee"),
16
            "NEW_CARD"                  : _("New card"),
17
            [% FOREACH a IN KohaAuthorisedValues.Get('MANUAL_INV') %]
18
                "[% a.authorised_value %]" : "[% a.lib %]",
19
            [% END %]
20
        },
21
22
        "CreditTypes": {
23
            "CREDIT"                    : _("Credit"),
24
            "PAYMENT"                   : _("Payment"),
25
            "WRITEOFF"                  : _("Writeoff"),
26
            "FOUND"                     : _("Lost item found"),
27
            "FORGIVEN"                  : _("Forgiven"),
28
            [% FOREACH a IN KohaAuthorisedValues.Get('MANUAL_CREDIT') %]
29
                "[% a.authorised_value %]" : "[% a.lib %]",
30
            [% END %]
31
        }
32
    }
33
//]]>
34
</script>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-account.tt (-33 / +350 lines)
Lines 1-9 Link Here
1
[% USE Koha %]
1
[% USE Koha %]
2
[% USE KohaDates %]
2
[% USE KohaDates %]
3
[% USE Currency %]
3
4
4
[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Your fines and charges
5
[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Your fines and charges
5
[% INCLUDE 'doc-head-close.inc' %]
6
[% INCLUDE 'doc-head-close.inc' %]
6
[% BLOCK cssinclude %][% END %]
7
[% BLOCK cssinclude %][% END %]
8
9
7
</head>
10
</head>
8
<body id="opac-account" class="scrollto">
11
<body id="opac-account" class="scrollto">
9
[% INCLUDE 'masthead.inc' %]
12
[% INCLUDE 'masthead.inc' %]
Lines 11-17 Link Here
11
<div class="main">
14
<div class="main">
12
    <ul class="breadcrumb">
15
    <ul class="breadcrumb">
13
        <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
16
        <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
14
        <li>[% FOREACH BORROWER_INF IN BORROWER_INFO %]<a href="/cgi-bin/koha/opac-user.pl">[% BORROWER_INF.firstname %] [% BORROWER_INF.surname %]</a>[% END %] <span class="divider">&rsaquo;</span></li>
17
        <li><a href="/cgi-bin/koha/opac-user.pl">[% borrower.firstname %] [% borrower.surname %]</a> <span class="divider">&rsaquo;</span></li>
15
        <li><a href="#">Your fines and charges</a></li>
18
        <li><a href="#">Your fines and charges</a></li>
16
    </ul>
19
    </ul>
17
20
Lines 25-62 Link Here
25
            <div class="span10">
28
            <div class="span10">
26
                <div id="useraccount" class="maincontent">
29
                <div id="useraccount" class="maincontent">
27
                    <h3>Fines and charges</h3>
30
                    <h3>Fines and charges</h3>
31
                    [% IF credits || debits %]
32
33
                        <p>
34
                            <h3>Account balance: [% borrower.account_balance | $Currency %]</h3>
35
                        </p>
36
37
                        <div>
38
                            <div id="account-debits">
39
                                <a id="account-debits-switcher" href="#" onclick="return false">View payments</a>
40
                                <table cellpadding="0" cellspacing="0" border="0" class="display" id="debits-table">
41
                                    <thead>
42
                                        <tr>
43
                                            <th colspan="99">Fees</th>
44
                                        </tr>
45
                                        <tr>
46
                                            <th></th>
47
                                            <th>ID</th>
48
                                            <th>Description</th>
49
                                            <th>Type</th>
50
                                            <th>Amount</th>
51
                                            <th>Outsanding</th>
52
                                            <th>Created on</th>
53
                                            <th>Updated on</th>
54
                                        </tr>
55
                                    </thead>
56
                                    <tbody></tbody>
57
                                </table>
58
                            </div>
28
59
29
                    [% IF ( ACCOUNT_LINES ) %]
60
                            <div id="account-credits">
30
                        <table class="table table-bordered table-striped">
61
                                <a id="account-credits-switcher" href="#"  onclick="return false">View fees</a>
31
                            <thead>
62
                                <table cellpadding="0" cellspacing="0" border="0" class="display" id="credits-table">
32
                                <tr>
63
                                    <thead>
33
                                    <th>Date</th>
64
                                        <tr>
34
                                    <th>Description</th>
65
                                            <th colspan="99">Payments</th>
35
                                    <th>Fine amount</th>
66
                                        </tr>
36
                                    <th>Amount outstanding</th>
67
                                        <tr>
37
                                </tr>
68
                                            <th></th>
38
                            </thead>
69
                                            <th>ID</th>
39
70
                                            <th>Notes</th>
40
                            <tfoot>
71
                                            <th>Type</th>
41
                            <tr>
72
                                            <th>Amount</th>
42
                                <th class="sum" colspan="3">Total due</th>
73
                                            <th>Remaining</th>
43
                                <td class="sum">[% total %]</td>
74
                                            <th>Created on</th>
44
                            </tr>
75
                                            <th>Updated on</th>
45
                            </tfoot>
76
                                        </tr>
46
77
                                    </thead>
47
                            <tbody>
78
                                    <tbody></tbody>
48
                                [% FOREACH ACCOUNT_LINE IN ACCOUNT_LINES %]
79
                                </table>
49
                                    [% IF ( ACCOUNT_LINE.odd ) %]<tr class="highlight">[% ELSE %]<tr>[% END %]
80
                            </div>
50
                                        <td>[% ACCOUNT_LINE.date | $KohaDates %]</td>
81
                        </div>
51
                                        <td>[% ACCOUNT_LINE.description %]
52
                                        [% IF ( ACCOUNT_LINE.title ) %][% ACCOUNT_LINE.title |html %][% END %]</td>
53
                                        [% IF ( ACCOUNT_LINE.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% ACCOUNT_LINE.amount %]</td>
54
                                        [% IF ( ACCOUNT_LINE.amountoutstandingcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% ACCOUNT_LINE.amountoutstanding %]</td>
55
                                    </tr>
56
                                [% END %]
57
                            </tbody>
58
59
                        </table>
60
                    [% ELSE %]
82
                    [% ELSE %]
61
                        <h4>You have no fines or charges</h4>
83
                        <h4>You have no fines or charges</h4>
62
                    [% END %]
84
                    [% END %]
Lines 67-70 Link Here
67
</div> <!-- / .main -->
89
</div> <!-- / .main -->
68
90
69
[% INCLUDE 'opac-bottom.inc' %]
91
[% INCLUDE 'opac-bottom.inc' %]
70
[% BLOCK jsinclude %][% END %]
92
[% INCLUDE 'datatables.inc' %]
93
94
<script type="text/javascript">
95
//<![CDATA[
96
$(document).ready(function() {
97
    $('#account-credits').hide();
98
    $('#account-debits-switcher').click(function() {
99
         $('#account-debits').slideUp();
100
         $('#account-credits').slideDown();
101
    });
102
    $('#account-credits-switcher').click(function() {
103
         $('#account-credits').slideUp();
104
         $('#account-debits').slideDown();
105
    });
106
107
    var anOpen = [];
108
    var sImageUrl = "[% interface %]/[% theme %]/images/";
109
110
    var debitsTable = $('#debits-table').dataTable( {
111
        "bProcessing": true,
112
        "aoColumns": [
113
            {
114
                "mDataProp": null,
115
                "sClass": "control center",
116
                "sDefaultContent": '<img src="'+sImageUrl+'details_open.png'+'">'
117
            },
118
            { "mDataProp": "debit_id" },
119
            { "mDataProp": "description" },
120
            { "mDataProp": "type" },
121
            { "mDataProp": "amount_original" },
122
            { "mDataProp": "amount_outstanding" },
123
            { "mDataProp": "created_on" },
124
            { "mDataProp": "updated_on" }
125
        ],
126
        "aaData": [
127
            [% FOREACH d IN debits %]
128
                {
129
                    [% PROCESS format_data data=d highlight='debit' %]
130
131
                    // Data for related item if there is one linked
132
                    "title": "[% d.item.biblio.title || d.deleted_item.biblio.title || d.deleted_item.deleted_biblio.title %]",
133
                    "biblionumber": "[% d.item.biblio.biblionumber || d.deleted_item.biblio.biblionumber %]",
134
                    "barcode": "[% d.item.barcode || d.deleted_item.barcode %]",
135
                    "itemnumber": "[% d.item.itemnumber %]", //This way itemnumber will be undef if deleted
136
137
138
                    // Data for related issue if there is one linked
139
                    [% IF d.issue %]
140
                        [% SET table = 'issue' %]
141
                    [% ELSIF d.old_issue %]
142
                        [% SET table = 'old_issue' %]
143
                    [% END %]
144
145
                    [% IF table %]
146
                        "issue": {
147
                            [% PROCESS format_data data=d.$table %]
148
                        },
149
                    [% END %]
150
151
152
                    "account_offsets": [
153
                        [% FOREACH ao IN d.account_offsets %]
154
                            {
155
                                [% PROCESS format_data data=ao highlight='offset'%]
156
157
                                "credit": {
158
                                    [% PROCESS format_data data=ao.credit highlight='credit' %]
159
                                }
160
                            },
161
                        [% END %]
162
                    ]
163
164
                },
165
            [% END %]
166
        ]
167
    } );
168
169
    $('#debits-table td.control').live( 'click', function () {
170
        var nTr = this.parentNode;
171
        var i = $.inArray( nTr, anOpen );
172
173
        if ( i === -1 ) {
174
            $('img', this).attr( 'src', sImageUrl+"details_close.png" );
175
            var nDetailsRow = debitsTable.fnOpen( nTr, fnFormatDebitDetails(debitsTable, nTr), 'details' );
176
            $('div.innerDetails', nDetailsRow).slideDown();
177
            anOpen.push( nTr );
178
        }
179
        else {
180
            $('img', this).attr( 'src', sImageUrl+"details_open.png" );
181
            $('div.innerDetails', $(nTr).next()[0]).slideUp( function () {
182
                debitsTable.fnClose( nTr );
183
                anOpen.splice( i, 1 );
184
            } );
185
        }
186
    } );
187
188
    var creditsTable = $('#credits-table').dataTable( {
189
        "bProcessing": true,
190
        "aoColumns": [
191
            {
192
                "mDataProp": null,
193
                "sClass": "control center",
194
                "sDefaultContent": '<img src="'+sImageUrl+'details_open.png'+'">'
195
            },
196
            { "mDataProp": "credit_id" },
197
            { "mDataProp": "notes" },
198
            { "mDataProp": "type" },
199
            { "mDataProp": "amount_paid" },
200
            { "mDataProp": "amount_remaining" },
201
            { "mDataProp": "created_on" },
202
            { "mDataProp": "updated_on" }
203
        ],
204
        "aaData": [
205
            [% FOREACH c IN credits %]
206
                {
207
                    [% PROCESS format_data data=c highlight='credit' %]
208
209
                    "account_offsets": [
210
                        [% FOREACH ao IN c.account_offsets %]
211
                            {
212
                                [% PROCESS format_data data=ao highlight='offset' %]
213
214
                                "debit": {
215
                                    [% PROCESS format_data data=ao.debit highlight='debit' %]
216
                                }
217
                            },
218
                        [% END %]
219
                    ]
220
221
                },
222
            [% END %]
223
        ]
224
    } );
225
226
    $('#credits-table td.control').live( 'click', function () {
227
        var nTr = this.parentNode;
228
        var i = $.inArray( nTr, anOpen );
229
230
        if ( i === -1 ) {
231
            $('img', this).attr( 'src', sImageUrl+"details_close.png" );
232
            var nDetailsRow = creditsTable.fnOpen( nTr, fnFormatCreditDetails(creditsTable, nTr), 'details' );
233
            $('div.innerDetails', nDetailsRow).slideDown();
234
            anOpen.push( nTr );
235
        }
236
        else {
237
            $('img', this).attr( 'src', sImageUrl+"details_open.png" );
238
            $('div.innerDetails', $(nTr).next()[0]).slideUp( function () {
239
                creditsTable.fnClose( nTr );
240
                anOpen.splice( i, 1 );
241
            } );
242
        }
243
    } );
244
245
} );
246
247
function fnFormatDebitDetails( debitsTable, nTr ) {
248
    var oData = debitsTable.fnGetData( nTr );
249
250
    var sOut = '<div class="innerDetails" style="display:none;">';
251
252
    var account_offsets = oData.account_offsets;
253
254
    sOut += '<ul>';
255
    if ( oData.title ) {
256
        sOut += '<li>' + _('Title: ');
257
        if ( oData.biblionumber ) {
258
            sOut += '<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=' + oData.biblionumber + '">';
259
        }
260
261
        sOut += oData.title;
262
263
        if ( oData.biblionumber ) {
264
            sOut += '</a>';
265
        }
266
267
        sOut += '</li>';
268
    }
269
270
    if ( oData.barcode ) {
271
        sOut += '<li>' + _('Barcode: ') + oData.barcode + '</li>';
272
    }
273
274
    if ( oData.notes ) {
275
        sOut += '<li>' + _('Notes: ') + oData.notes + '</li>';
276
    }
277
278
    sOut += '</ul>';
279
280
    if ( account_offsets.length ) {
281
        sOut +=
282
            '<div class="innerDetails">' +
283
                '<table cellpadding="5" cellspacing="0" border="0" style="margin:10px;">' +
284
                    '<thead>' +
285
                        '<tr><th colspan="99">' + _('Payments applied') + '</th></tr>' +
286
                        '<tr>' +
287
                            '<th>' + _('ID') + '</th>' +
288
                            '<th>' + _('Created on') + '</th>' +
289
                            '<th>' + _('Payment amount') + '</th>' +
290
                            '<th>' + _('Applied amount') + '</th>' +
291
                            '<th>' + _('Type') + '</th>' +
292
                            '<th>' + _('Notes') + '</th>' +
293
                        '</tr>' +
294
                    '</thead>' +
295
                    '<tbody>';
296
297
        for ( var i = 0; i < account_offsets.length; i++ ) {
298
            ao = account_offsets[i];
299
            sOut +=
300
            '<tr>' +
301
                '<td>' + ao.credit_id + '</td>' +
302
                '<td>' + ao.created_on + '</td>' +
303
                '<td>' + ao.credit.amount_paid + '</td>' +
304
                '<td>' + ao.amount + '</td>' +
305
                '<td>' + ao.credit.type + '</td>' +
306
                '<td>' + ao.credit.notes + '</td>' +
307
            '</tr>';
308
        }
309
310
        sOut +=
311
            '</tbody>'+
312
            '</table>';
313
    }
314
315
    sOut +=
316
        '</div>';
317
318
    return sOut;
319
}
320
321
function fnFormatCreditDetails( creditsTable, nTr ) {
322
    var oData = creditsTable.fnGetData( nTr );
323
324
    var sOut = '<div class="innerDetails" style="display:none;">';
325
326
    var account_offsets = oData.account_offsets;
327
328
    if ( account_offsets.length ) {
329
        sOut +=
330
                '<table cellpadding="5" cellspacing="0" border="0" style="margin:10px;">' +
331
                    '<thead>' +
332
                        '<tr><th colspan="99">' + _('Fees paid') + '</th></tr>' +
333
                        '<tr>' +
334
                            '<th>' + _('ID') + '</th>' +
335
                            '<th>' + _('Description') + '</th>' +
336
                            '<th>' + _('Type') + '</th>' +
337
                            '<th>' + _('Amount') + '</th>' +
338
                            '<th>' + _('Remaining') + '</th>' +
339
                            '<th>' + _('Created on') + '</th>' +
340
                            '<th>' + _('Updated on') + '</th>' +
341
                            '<th>' + _('Notes') + '</th>' +
342
                        '</tr>' +
343
                    '</thead>' +
344
                    '<tbody>';
345
346
        for ( var i = 0; i < account_offsets.length; i++ ) {
347
            ao = account_offsets[i];
348
            sOut +=
349
            '<tr>' +
350
                '<td>' + ao.debit.debit_id + '</td>' +
351
                '<td>' + ao.debit.description + '</td>' +
352
                '<td>' + ao.debit.type + '</td>' +
353
                '<td>' + ao.debit.amount_original + '</td>' +
354
                '<td>' + ao.debit.amount_outstanding + '</td>' +
355
                '<td>' + ao.debit.created_on + '</td>' +
356
                '<td>' + ao.debit.updated_on + '</td>' +
357
                '<td>' + ao.debit.notes + '</td>' +
358
            '</tr>';
359
        }
360
361
        sOut +=
362
            '</tbody>'+
363
            '</table>';
364
    }
365
366
    sOut +=
367
        '</div>';
368
369
    return sOut;
370
}
371
372
//]]>
373
</script>
374
375
[% BLOCK jsinclude %][% END %]
376
377
[% BLOCK format_data %]
378
    [% FOREACH key IN data.result_source.columns %]
379
        [% IF key.match('^amount') %]
380
            "[% key %]": "[% data.$key FILTER $Currency %]",
381
        [% ELSIF key.match('_on$') %]
382
            "[% key %]": "[% data.$key | $KohaDates %]",
383
        [% ELSE %]
384
            "[% key %]": "[% data.$key %]",
385
        [% END %]
386
    [% END %]
387
[% END %]
(-)a/koha-tmpl/opac-tmpl/prog/en/includes/browser-strings.inc (+34 lines)
Line 0 Link Here
1
[% USE KohaAuthorisedValues %]
2
<script type="text/javascript">
3
//<![CDATA[
4
    var BROWSER_RETURN_TO_SEARCH = _("Return to results");
5
    var BROWSER_PREVIOUS = _("Previous");
6
    var BROWSER_NEXT = _("Next");
7
8
    var STRINGS = {
9
        "DebitTypes": {
10
            "FINE"                      : _("Fine"),
11
            "ACCOUNT_MANAGEMENT_FEE"    : _("Account management fee"),
12
            "SUNDRY"                    : _("Sundry"),
13
            "LOST"                      : _("Lost item"),
14
            "HOLD"                      : _("Hold fee"),
15
            "RENTAL"                    : _("Rental fee"),
16
            "NEW_CARD"                  : _("New card"),
17
            [% FOREACH a IN KohaAuthorisedValues.Get('MANUAL_INV') %]
18
                "[% a.authorised_value %]" : "[% a.lib %]",
19
            [% END %]
20
        },
21
22
        "CreditTypes": {
23
            "CREDIT"                    : _("Credit"),
24
            "PAYMENT"                   : _("Payment"),
25
            "WRITEOFF"                  : _("Writeoff"),
26
            "FOUND"                     : _("Lost item found"),
27
            "FORGIVEN"                  : _("Forgiven"),
28
            [% FOREACH a IN KohaAuthorisedValues.Get('MANUAL_CREDIT') %]
29
                "[% a.authorised_value %]" : "[% a.lib %]",
30
            [% END %]
31
        }
32
    }
33
//]]>
34
</script>
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-account.tt (-52 / +381 lines)
Lines 1-64 Link Here
1
[% SET accountview = 1 %]
2
1
[% USE Koha %]
3
[% USE Koha %]
2
[% USE KohaDates %]
4
[% USE KohaDates %]
5
[% USE Currency %]
3
6
4
[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Your fines and charges
7
[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Your fines and charges
5
[% INCLUDE 'doc-head-close.inc' %]
8
[% INCLUDE 'doc-head-close.inc' %]
6
</head>
9
</head>
7
<body id="opac-account">
10
<body id="opac-account">
8
<div id="doc3" class="yui-t1">
11
<div id="doc3" class="yui-t1">
9
   <div id="bd">
12
    <div id="bd">
10
[% INCLUDE 'masthead.inc' %]
13
        [% INCLUDE 'masthead.inc' %]
11
12
	<div id="yui-main">
14
	<div id="yui-main">
13
	<div class="yui-b"><div class="yui-g">
15
            <div class="yui-b">
14
		<div id="useraccount" class="container">
16
                <div class="yui-g">
15
<!--CONTENT-->
17
                        <div id="useraccount" class="container">
16
    [% FOREACH BORROWER_INF IN BORROWER_INFO %]
18
                        <h3><a href="/cgi-bin/koha/opac-user.pl">[% borrower.firstname %] [% borrower.surname %]'s account</a> &#8674; Fines and charges</h3>
17
        <h3><a href="/cgi-bin/koha/opac-user.pl">[% BORROWER_INF.firstname %] [% BORROWER_INF.surname %]'s account</a> &#8674; Fines and charges</h3>
18
    [% END %]
19
19
20
    [% IF ( ACCOUNT_LINES ) %]
20
                        [% IF credits || debits %]
21
        <table>
21
22
            <thead>
22
                            <p>
23
                <tr>
23
                                <h3>Account balance: [% borrower.account_balance | $Currency %]</h3>
24
                    <th>Date</th>
24
                            </p>
25
                    <th>Description</th>
25
26
                    <th>Fine amount</th>
26
                            <div>
27
                    <th>Amount outstanding</th>
27
                                <div id="account-debits">
28
                </tr>
28
                                    <a id="account-debits-switcher" href="#" onclick="return false">View payments</a>
29
            </thead>
29
                                    <table cellpadding="0" cellspacing="0" border="0" class="display" id="debits-table">
30
30
                                        <thead>
31
            <tfoot>
31
                                            <tr>
32
            <tr>
32
                                                <th colspan="99">Fees</th>
33
                <th class="sum" colspan="3">Total due</th>
33
                                            </tr>
34
                <td class="sum">[% total %]</td>
34
                                            <tr>
35
            </tr>
35
                                                <th></th>
36
            </tfoot>
36
                                                <th>ID</th>
37
37
                                                <th>Description</th>
38
            <tbody>
38
                                                <th>Type</th>
39
                [% FOREACH ACCOUNT_LINE IN ACCOUNT_LINES %]
39
                                                <th>Amount</th>
40
                    [% IF ( ACCOUNT_LINE.odd ) %]<tr class="highlight">[% ELSE %]<tr>[% END %]
40
                                                <th>Outsanding</th>
41
                        <td>[% ACCOUNT_LINE.date | $KohaDates %]</td>
41
                                                <th>Created on</th>
42
                        <td>[% ACCOUNT_LINE.description %]
42
                                                <th>Updated on</th>
43
                        [% IF ( ACCOUNT_LINE.title ) %][% ACCOUNT_LINE.title |html %][% END %]</td>
43
                                            </tr>
44
                        [% IF ( ACCOUNT_LINE.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% ACCOUNT_LINE.amount %]</td>
44
                                        </thead>
45
                        [% IF ( ACCOUNT_LINE.amountoutstandingcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% ACCOUNT_LINE.amountoutstanding %]</td>
45
                                        <tbody></tbody>
46
                    </tr>
46
                                    </table>
47
                [% END %]
47
                                </div>
48
            </tbody>
48
49
49
                                <div id="account-credits">
50
        </table>
50
                                    <a id="account-credits-switcher" href="#"  onclick="return false">View fees</a>
51
    [% ELSE %]
51
                                    <table cellpadding="0" cellspacing="0" border="0" class="display" id="credits-table">
52
        <h4>You have no fines or charges</h4>
52
                                        <thead>
53
    [% END %]
53
                                            <tr>
54
</div>
54
                                                <th colspan="99">Payments</th>
55
</div>
55
                                            </tr>
56
</div>
56
                                            <tr>
57
</div>
57
                                                <th></th>
58
<div class="yui-b">
58
                                                <th>ID</th>
59
<div id="leftmenus" class="container">
59
                                                <th>Notes</th>
60
[% INCLUDE 'navigation.inc' IsPatronPage=1 %]
60
                                                <th>Type</th>
61
</div>
61
                                                <th>Amount</th>
62
</div>
62
                                                <th>Remaining</th>
63
                                                <th>Created on</th>
64
                                                <th>Updated on</th>
65
                                            </tr>
66
                                        </thead>
67
                                        <tbody></tbody>
68
                                    </table>
69
                                </div>
70
                            </div>
71
                        [% ELSE %]
72
                            <h4>You have no fines or charges</h4>
73
                        [% END %]
74
                    </div>
75
                </div>
76
            </div>
77
        </div>
78
79
    <div class="yui-b">
80
        <div id="leftmenus" class="container">
81
            [% INCLUDE 'navigation.inc' IsPatronPage=1 %]
82
        </div>
83
    </div>
63
</div>
84
</div>
64
[% INCLUDE 'opac-bottom.inc' %]
85
[% INCLUDE 'opac-bottom.inc' %]
86
87
[% INCLUDE 'datatables.inc' %]
88
[% INCLUDE 'browser-strings.inc' %]
89
90
<script type="text/javascript">
91
//<![CDATA[
92
$(document).ready(function() {
93
    $('#account-credits').hide();
94
    $('#account-debits-switcher').click(function() {
95
         $('#account-debits').slideUp();
96
         $('#account-credits').slideDown();
97
    });
98
    $('#account-credits-switcher').click(function() {
99
         $('#account-credits').slideUp();
100
         $('#account-debits').slideDown();
101
    });
102
103
    var anOpen = [];
104
    var sImageUrl = "[% interface %]/[% theme %]/images/";
105
106
    var debitsTable = $('#debits-table').dataTable( {
107
        "bProcessing": true,
108
        "aoColumns": [
109
            {
110
                "mDataProp": null,
111
                "sClass": "control center",
112
                "sDefaultContent": '<img src="'+sImageUrl+'details_open.png'+'">'
113
            },
114
            { "mDataProp": "debit_id" },
115
            { "mDataProp": "description" },
116
            {
117
                "mDataProp": "type",
118
                "fnRender": function ( o, val ) {
119
                    return STRINGS['DebitTypes'][val];
120
                },
121
            },
122
            { "mDataProp": "amount_original" },
123
            { "mDataProp": "amount_outstanding" },
124
            { "mDataProp": "created_on" },
125
            { "mDataProp": "updated_on" }
126
        ],
127
        "aaData": [
128
            [% FOREACH d IN debits %]
129
                {
130
                    [% PROCESS format_data data=d highlight='debit' %]
131
132
                    // Data for related item if there is one linked
133
                    "title": "[% d.item.biblio.title || d.deleted_item.biblio.title || d.deleted_item.deleted_biblio.title %]",
134
                    "biblionumber": "[% d.item.biblio.biblionumber || d.deleted_item.biblio.biblionumber %]",
135
                    "barcode": "[% d.item.barcode || d.deleted_item.barcode %]",
136
                    "itemnumber": "[% d.item.itemnumber %]", //This way itemnumber will be undef if deleted
137
138
139
                    // Data for related issue if there is one linked
140
                    [% IF d.issue %]
141
                        [% SET table = 'issue' %]
142
                    [% ELSIF d.old_issue %]
143
                        [% SET table = 'old_issue' %]
144
                    [% END %]
145
146
                    [% IF table %]
147
                        "issue": {
148
                            [% PROCESS format_data data=d.$table %]
149
                        },
150
                    [% END %]
151
152
153
                    "account_offsets": [
154
                        [% FOREACH ao IN d.account_offsets %]
155
                            {
156
                                [% PROCESS format_data data=ao highlight='offset'%]
157
158
                                "credit": {
159
                                    [% PROCESS format_data data=ao.credit highlight='credit' %]
160
                                }
161
                            },
162
                        [% END %]
163
                    ]
164
165
                },
166
            [% END %]
167
        ]
168
    } );
169
170
    $('#debits-table td.control').live( 'click', function () {
171
        var nTr = this.parentNode;
172
        var i = $.inArray( nTr, anOpen );
173
174
        if ( i === -1 ) {
175
            $('img', this).attr( 'src', sImageUrl+"details_close.png" );
176
            var nDetailsRow = debitsTable.fnOpen( nTr, fnFormatDebitDetails(debitsTable, nTr), 'details' );
177
            $('div.innerDetails', nDetailsRow).slideDown();
178
            anOpen.push( nTr );
179
        }
180
        else {
181
            $('img', this).attr( 'src', sImageUrl+"details_open.png" );
182
            $('div.innerDetails', $(nTr).next()[0]).slideUp( function () {
183
                debitsTable.fnClose( nTr );
184
                anOpen.splice( i, 1 );
185
            } );
186
        }
187
    } );
188
189
    var creditsTable = $('#credits-table').dataTable( {
190
        "bProcessing": true,
191
        "aoColumns": [
192
            {
193
                "mDataProp": null,
194
                "sClass": "control center",
195
                "sDefaultContent": '<img src="'+sImageUrl+'details_open.png'+'">'
196
            },
197
            { "mDataProp": "credit_id" },
198
            { "mDataProp": "notes" },
199
            {
200
                "mDataProp": "type",
201
                "fnRender": function ( o, val ) {
202
                    return STRINGS['CreditTypes'][val];
203
                },
204
            },
205
            { "mDataProp": "amount_paid" },
206
            { "mDataProp": "amount_remaining" },
207
            { "mDataProp": "created_on" },
208
            { "mDataProp": "updated_on" }
209
        ],
210
        "aaData": [
211
            [% FOREACH c IN credits %]
212
                {
213
                    [% PROCESS format_data data=c highlight='credit' %]
214
215
                    "account_offsets": [
216
                        [% FOREACH ao IN c.account_offsets %]
217
                            {
218
                                [% PROCESS format_data data=ao highlight='offset' %]
219
220
                                "debit": {
221
                                    [% PROCESS format_data data=ao.debit highlight='debit' %]
222
                                }
223
                            },
224
                        [% END %]
225
                    ]
226
227
                },
228
            [% END %]
229
        ]
230
    } );
231
232
    $('#credits-table td.control').live( 'click', function () {
233
        var nTr = this.parentNode;
234
        var i = $.inArray( nTr, anOpen );
235
236
        if ( i === -1 ) {
237
            $('img', this).attr( 'src', sImageUrl+"details_close.png" );
238
            var nDetailsRow = creditsTable.fnOpen( nTr, fnFormatCreditDetails(creditsTable, nTr), 'details' );
239
            $('div.innerDetails', nDetailsRow).slideDown();
240
            anOpen.push( nTr );
241
        }
242
        else {
243
            $('img', this).attr( 'src', sImageUrl+"details_open.png" );
244
            $('div.innerDetails', $(nTr).next()[0]).slideUp( function () {
245
                creditsTable.fnClose( nTr );
246
                anOpen.splice( i, 1 );
247
            } );
248
        }
249
    } );
250
251
} );
252
253
function fnFormatDebitDetails( debitsTable, nTr ) {
254
    var oData = debitsTable.fnGetData( nTr );
255
256
    var sOut = '<div class="innerDetails" style="display:none;">';
257
258
    var account_offsets = oData.account_offsets;
259
260
    sOut += '<ul>';
261
    if ( oData.title ) {
262
        sOut += '<li>' + _('Title: ');
263
        if ( oData.biblionumber ) {
264
            sOut += '<a href="/cgi-bin/koha/opac-detail.pl?biblionumber=' + oData.biblionumber + '">';
265
        }
266
267
        sOut += oData.title;
268
269
        if ( oData.biblionumber ) {
270
            sOut += '</a>';
271
        }
272
273
        sOut += '</li>';
274
    }
275
276
    if ( oData.barcode ) {
277
        sOut += '<li>' + _('Barcode: ') + oData.barcode + '</li>';
278
    }
279
280
    if ( oData.notes ) {
281
        sOut += '<li>' + _('Notes: ') + oData.notes + '</li>';
282
    }
283
284
    sOut += '</ul>';
285
286
    if ( account_offsets.length ) {
287
        sOut +=
288
            '<div class="innerDetails">' +
289
                '<table cellpadding="5" cellspacing="0" border="0" style="margin:10px;">' +
290
                    '<thead>' +
291
                        '<tr><th colspan="99">' + _('Payments applied') + '</th></tr>' +
292
                        '<tr>' +
293
                            '<th>' + _('ID') + '</th>' +
294
                            '<th>' + _('Created on') + '</th>' +
295
                            '<th>' + _('Payment amount') + '</th>' +
296
                            '<th>' + _('Applied amount') + '</th>' +
297
                            '<th>' + _('Type') + '</th>' +
298
                            '<th>' + _('Notes') + '</th>' +
299
                        '</tr>' +
300
                    '</thead>' +
301
                    '<tbody>';
302
303
        for ( var i = 0; i < account_offsets.length; i++ ) {
304
            ao = account_offsets[i];
305
            sOut +=
306
            '<tr>' +
307
                '<td>' + ao.credit_id + '</td>' +
308
                '<td>' + ao.created_on + '</td>' +
309
                '<td>' + ao.credit.amount_paid + '</td>' +
310
                '<td>' + ao.amount + '</td>' +
311
                '<td>' + ao.credit.type + '</td>' +
312
                '<td>' + ao.credit.notes + '</td>' +
313
            '</tr>';
314
        }
315
316
        sOut +=
317
            '</tbody>'+
318
            '</table>';
319
    }
320
321
    sOut +=
322
        '</div>';
323
324
    return sOut;
325
}
326
327
function fnFormatCreditDetails( creditsTable, nTr ) {
328
    var oData = creditsTable.fnGetData( nTr );
329
330
    var sOut = '<div class="innerDetails" style="display:none;">';
331
332
    var account_offsets = oData.account_offsets;
333
334
    if ( account_offsets.length ) {
335
        sOut +=
336
                '<table cellpadding="5" cellspacing="0" border="0" style="margin:10px;">' +
337
                    '<thead>' +
338
                        '<tr><th colspan="99">' + _('Fees paid') + '</th></tr>' +
339
                        '<tr>' +
340
                            '<th>' + _('ID') + '</th>' +
341
                            '<th>' + _('Description') + '</th>' +
342
                            '<th>' + _('Type') + '</th>' +
343
                            '<th>' + _('Amount') + '</th>' +
344
                            '<th>' + _('Remaining') + '</th>' +
345
                            '<th>' + _('Created on') + '</th>' +
346
                            '<th>' + _('Updated on') + '</th>' +
347
                            '<th>' + _('Notes') + '</th>' +
348
                        '</tr>' +
349
                    '</thead>' +
350
                    '<tbody>';
351
352
        for ( var i = 0; i < account_offsets.length; i++ ) {
353
            ao = account_offsets[i];
354
            sOut +=
355
            '<tr>' +
356
                '<td>' + ao.debit.debit_id + '</td>' +
357
                '<td>' + ao.debit.description + '</td>' +
358
                '<td>' + ao.debit.type + '</td>' +
359
                '<td>' + ao.debit.amount_original + '</td>' +
360
                '<td>' + ao.debit.amount_outstanding + '</td>' +
361
                '<td>' + ao.debit.created_on + '</td>' +
362
                '<td>' + ao.debit.updated_on + '</td>' +
363
                '<td>' + ao.debit.notes + '</td>' +
364
            '</tr>';
365
        }
366
367
        sOut +=
368
            '</tbody>'+
369
            '</table>';
370
    }
371
372
    sOut +=
373
        '</div>';
374
375
    return sOut;
376
}
377
378
//]]>
379
</script>
380
381
[% BLOCK jsinclude %][% END %]
382
383
[% BLOCK format_data %]
384
    [% FOREACH key IN data.result_source.columns %]
385
        [% IF key.match('^amount') %]
386
            "[% key %]": "[% data.$key FILTER $Currency %]",
387
        [% ELSIF key.match('_on$') %]
388
            "[% key %]": "[% data.$key | $KohaDates %]",
389
        [% ELSE %]
390
            "[% key %]": "[% data.$key %]",
391
        [% END %]
392
    [% END %]
393
[% END %]
(-)a/members/account.pl (+112 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2000-2002 Katipo Communications
4
# Copyright 2013 ByWater Solutions
5
#
6
# This file is part of Koha.
7
#
8
# Koha is free software; you can redistribute it and/or modify it under the
9
# terms of the GNU General Public License as published by the Free Software
10
# Foundation; either version 2 of the License, or (at your option) any later
11
# version.
12
#
13
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License along
18
# with Koha; if not, write to the Free Software Foundation, Inc.,
19
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21
use Modern::Perl;
22
23
use CGI;
24
25
use C4::Auth;
26
use C4::Output;
27
use C4::Dates qw/format_date/;
28
use C4::Members;
29
use C4::Branch;
30
use C4::Members::Attributes qw(GetBorrowerAttributes);
31
use Koha::Database;
32
33
my $cgi = new CGI;
34
35
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
36
    {
37
        template_name   => "members/account.tt",
38
        query           => $cgi,
39
        type            => "intranet",
40
        authnotrequired => 0,
41
        flagsrequired   => { borrowers => 1, updatecharges => 1 },
42
        debug           => 1,
43
    }
44
);
45
46
my $borrowernumber = $cgi->param('borrowernumber');
47
48
my $borrower = GetMember( 'borrowernumber' => $borrowernumber );
49
50
my @debits = Koha::Database->new()->schema->resultset('AccountDebit')->search(
51
    { 'me.borrowernumber' => $borrowernumber },
52
    { prefetch            => { account_offsets => 'credit' } }
53
);
54
55
my @credits = Koha::Database->new()->schema->resultset('AccountCredit')->search(
56
    { 'me.borrowernumber' => $borrowernumber },
57
    { prefetch            => { account_offsets => 'debit' } }
58
);
59
60
$template->param(
61
    debits   => \@debits,
62
    credits  => \@credits,
63
    borrower => $borrower,
64
);
65
66
# Standard /members/ borrower details data
67
## FIXME: This code is in every /members/ script and should be unified
68
69
if ( $borrower->{'category_type'} eq 'C' ) {
70
    my ( $catcodes, $labels ) =
71
      GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
72
    my $cnt = scalar(@$catcodes);
73
    $template->param( 'CATCODE_MULTI' => 1 ) if $cnt > 1;
74
    $template->param( 'catcode' => $catcodes->[0] ) if $cnt == 1;
75
}
76
77
my ( $picture, $dberror ) = GetPatronImage( $borrower->{'borrowernumber'} );
78
$template->param( picture => 1 ) if $picture;
79
80
if ( C4::Context->preference('ExtendedPatronAttributes') ) {
81
    my $attributes = GetBorrowerAttributes($borrowernumber);
82
    $template->param(
83
        ExtendedPatronAttributes => 1,
84
        extendedattributes       => $attributes
85
    );
86
}
87
88
$template->param(
89
    borrowernumber => $borrowernumber,
90
    firstname      => $borrower->{'firstname'},
91
    surname        => $borrower->{'surname'},
92
    cardnumber     => $borrower->{'cardnumber'},
93
    categorycode   => $borrower->{'categorycode'},
94
    category_type  => $borrower->{'category_type'},
95
    categoryname   => $borrower->{'description'},
96
    address        => $borrower->{'address'},
97
    address2       => $borrower->{'address2'},
98
    city           => $borrower->{'city'},
99
    state          => $borrower->{'state'},
100
    zipcode        => $borrower->{'zipcode'},
101
    country        => $borrower->{'country'},
102
    phone          => $borrower->{'phone'},
103
    email          => $borrower->{'email'},
104
    branchcode     => $borrower->{'branchcode'},
105
    branchname     => GetBranchName( $borrower->{'branchcode'} ),
106
    is_child       => ( $borrower->{'category_type'} eq 'C' ),
107
    activeBorrowerRelationship =>
108
      ( C4::Context->preference('borrowerRelationship') ne '' ),
109
    RoutingSerials => C4::Context->preference('RoutingSerials'),
110
);
111
112
output_html_with_http_headers $cgi, $cookie, $template->output;
(-)a/members/account_credit.pl (+103 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
#written 11/1/2000 by chris@katipo.oc.nz
4
#script to display borrowers account details
5
6
# Copyright 2000-2002 Katipo Communications
7
# Copyright 2010 BibLibre
8
#
9
# This file is part of Koha.
10
#
11
# Koha is free software; you can redistribute it and/or modify it under the
12
# terms of the GNU General Public License as published by the Free Software
13
# Foundation; either version 2 of the License, or (at your option) any later
14
# version.
15
#
16
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License along
21
# with Koha; if not, write to the Free Software Foundation, Inc.,
22
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
24
use strict;
25
use warnings;
26
27
use C4::Auth;
28
use C4::Output;
29
use CGI;
30
31
use C4::Koha;
32
use C4::Members;
33
use C4::Branch;
34
use C4::Items;
35
use C4::Members::Attributes qw(GetBorrowerAttributes);
36
use Koha::Database;
37
38
my $cgi = new CGI;
39
40
my $borrowernumber = $cgi->param('borrowernumber');
41
42
my $borrower = GetMember( 'borrowernumber' => $borrowernumber );
43
44
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
45
    {
46
        template_name   => "members/account_credit.tt",
47
        query           => $cgi,
48
        type            => "intranet",
49
        authnotrequired => 0,
50
        flagsrequired   => { borrowers => 1, updatecharges => 1 },
51
        debug           => 1,
52
    }
53
);
54
55
$template->param( credit_types_loop => GetAuthorisedValues('ACCOUNT_CREDIT') );
56
57
# Standard /members/ borrower details data
58
## FIXME: This code is in every /members/ script and should be unified
59
60
if ( $borrower->{'category_type'} eq 'C' ) {
61
    my ( $catcodes, $labels ) =
62
      GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
63
    my $cnt = scalar(@$catcodes);
64
    $template->param( 'CATCODE_MULTI' => 1 ) if $cnt > 1;
65
    $template->param( 'catcode' => $catcodes->[0] ) if $cnt == 1;
66
}
67
68
my ( $picture, $dberror ) = GetPatronImage( $borrower->{'borrowernumber'} );
69
$template->param( picture => 1 ) if $picture;
70
71
if ( C4::Context->preference('ExtendedPatronAttributes') ) {
72
    my $attributes = GetBorrowerAttributes($borrowernumber);
73
    $template->param(
74
        ExtendedPatronAttributes => 1,
75
        extendedattributes       => $attributes
76
    );
77
}
78
79
$template->param(
80
    borrowernumber => $borrowernumber,
81
    firstname      => $borrower->{'firstname'},
82
    surname        => $borrower->{'surname'},
83
    cardnumber     => $borrower->{'cardnumber'},
84
    categorycode   => $borrower->{'categorycode'},
85
    category_type  => $borrower->{'category_type'},
86
    categoryname   => $borrower->{'description'},
87
    address        => $borrower->{'address'},
88
    address2       => $borrower->{'address2'},
89
    city           => $borrower->{'city'},
90
    state          => $borrower->{'state'},
91
    zipcode        => $borrower->{'zipcode'},
92
    country        => $borrower->{'country'},
93
    phone          => $borrower->{'phone'},
94
    email          => $borrower->{'email'},
95
    branchcode     => $borrower->{'branchcode'},
96
    branchname     => GetBranchName( $borrower->{'branchcode'} ),
97
    is_child       => ( $borrower->{'category_type'} eq 'C' ),
98
    activeBorrowerRelationship =>
99
      ( C4::Context->preference('borrowerRelationship') ne '' ),
100
    RoutingSerials => C4::Context->preference('RoutingSerials'),
101
);
102
103
output_html_with_http_headers $cgi, $cookie, $template->output;
(-)a/members/account_credit_do.pl (+68 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2000-2002 Katipo Communications
4
# Copyright 2010 BibLibre
5
# Copyright 2013 ByWater Solutions
6
#
7
# This file is part of Koha.
8
#
9
# Koha is free software; you can redistribute it and/or modify it under the
10
# terms of the GNU General Public License as published by the Free Software
11
# Foundation; either version 2 of the License, or (at your option) any later
12
# version.
13
#
14
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License along
19
# with Koha; if not, write to the Free Software Foundation, Inc.,
20
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22
use Modern::Perl;
23
24
use CGI;
25
26
use C4::Auth;
27
use C4::Output;
28
use C4::Members;
29
use C4::Items;
30
use C4::Branch;
31
use C4::Members::Attributes qw(GetBorrowerAttributes);
32
use Koha::Accounts;
33
use Koha::Database;
34
35
my $cgi = new CGI;
36
37
my $borrowernumber = $cgi->param('borrowernumber');
38
my $borrower =
39
  Koha::Database->new()->schema->resultset('Borrower')->find($borrowernumber);
40
41
if ( checkauth( $cgi, 0, { borrowers => 1 }, 'intranet' ) ) {
42
43
    my $barcode     = $cgi->param('barcode');
44
    my $itemnumber  = $cgi->param('itemnumber');
45
    my $description = $cgi->param('description');
46
    my $amount      = $cgi->param('amount');
47
    my $type        = $cgi->param('type');
48
    my $notes       = $cgi->param('notes');
49
50
    if ( !$itemnumber && $barcode ) {
51
        $itemnumber = GetItemnumberFromBarcode($barcode);
52
    }
53
54
    my $debit = AddCredit(
55
        {
56
            borrower    => $borrower,
57
            amount      => $amount,
58
            type        => $type,
59
            itemnumber  => $itemnumber,
60
            description => $description,
61
            notes       => $notes,
62
63
        }
64
    );
65
66
    print $cgi->redirect(
67
        "/cgi-bin/koha/members/account.pl?borrowernumber=$borrowernumber");
68
}
(-)a/members/account_debit.pl (+104 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
#written 11/1/2000 by chris@katipo.oc.nz
4
#script to display borrowers account details
5
6
# Copyright 2000-2002 Katipo Communications
7
# Copyright 2010 BibLibre
8
#
9
# This file is part of Koha.
10
#
11
# Koha is free software; you can redistribute it and/or modify it under the
12
# terms of the GNU General Public License as published by the Free Software
13
# Foundation; either version 2 of the License, or (at your option) any later
14
# version.
15
#
16
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License along
21
# with Koha; if not, write to the Free Software Foundation, Inc.,
22
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
24
use strict;
25
use warnings;
26
27
use CGI;
28
29
use C4::Auth;
30
use C4::Output;
31
use C4::Members;
32
use C4::Items;
33
use C4::Branch;
34
use C4::Members::Attributes qw(GetBorrowerAttributes);
35
use C4::Koha;
36
use Koha::Accounts;
37
use Koha::Database;
38
39
my $input = new CGI;
40
41
my $borrowernumber = $input->param('borrowernumber');
42
43
my $borrower = GetMember( 'borrowernumber' => $borrowernumber );
44
45
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
46
    {
47
        template_name   => "members/account_debit.tt",
48
        query           => $input,
49
        type            => "intranet",
50
        authnotrequired => 0,
51
        flagsrequired   => { borrowers => 1, updatecharges => 1 },
52
        debug           => 1,
53
    }
54
);
55
56
$template->param( invoice_types_loop => GetAuthorisedValues('MANUAL_INV') );
57
58
# Standard /members/ borrower details data
59
## FIXME: This code is in every /members/ script and should be unified
60
61
if ( $borrower->{'category_type'} eq 'C' ) {
62
    my ( $catcodes, $labels ) =
63
      GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
64
    my $cnt = scalar(@$catcodes);
65
    $template->param( 'CATCODE_MULTI' => 1 ) if $cnt > 1;
66
    $template->param( 'catcode' => $catcodes->[0] ) if $cnt == 1;
67
}
68
69
my ( $picture, $dberror ) = GetPatronImage( $borrower->{'borrowernumber'} );
70
$template->param( picture => 1 ) if $picture;
71
72
if ( C4::Context->preference('ExtendedPatronAttributes') ) {
73
    my $attributes = GetBorrowerAttributes($borrowernumber);
74
    $template->param(
75
        ExtendedPatronAttributes => 1,
76
        extendedattributes       => $attributes
77
    );
78
}
79
80
$template->param(
81
    borrowernumber => $borrowernumber,
82
    firstname      => $borrower->{'firstname'},
83
    surname        => $borrower->{'surname'},
84
    cardnumber     => $borrower->{'cardnumber'},
85
    categorycode   => $borrower->{'categorycode'},
86
    category_type  => $borrower->{'category_type'},
87
    categoryname   => $borrower->{'description'},
88
    address        => $borrower->{'address'},
89
    address2       => $borrower->{'address2'},
90
    city           => $borrower->{'city'},
91
    state          => $borrower->{'state'},
92
    zipcode        => $borrower->{'zipcode'},
93
    country        => $borrower->{'country'},
94
    phone          => $borrower->{'phone'},
95
    email          => $borrower->{'email'},
96
    branchcode     => $borrower->{'branchcode'},
97
    branchname     => GetBranchName( $borrower->{'branchcode'} ),
98
    is_child       => ( $borrower->{'category_type'} eq 'C' ),
99
    activeBorrowerRelationship =>
100
      ( C4::Context->preference('borrowerRelationship') ne '' ),
101
    RoutingSerials => C4::Context->preference('RoutingSerials'),
102
);
103
104
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/members/account_debit_do.pl (+69 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2000-2002 Katipo Communications
4
# Copyright 2010 BibLibre
5
# Copyright 2013 ByWater Solutions
6
#
7
# This file is part of Koha.
8
#
9
# Koha is free software; you can redistribute it and/or modify it under the
10
# terms of the GNU General Public License as published by the Free Software
11
# Foundation; either version 2 of the License, or (at your option) any later
12
# version.
13
#
14
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License along
19
# with Koha; if not, write to the Free Software Foundation, Inc.,
20
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22
use Modern::Perl;
23
24
use CGI;
25
26
use C4::Auth;
27
use C4::Output;
28
use C4::Members;
29
use C4::Items;
30
use C4::Branch;
31
use C4::Members::Attributes qw(GetBorrowerAttributes);
32
use Koha::Accounts;
33
use Koha::Database;
34
35
my $cgi = new CGI;
36
37
my $borrowernumber = $cgi->param('borrowernumber');
38
my $borrower =
39
  Koha::Database->new()->schema->resultset('Borrower')->find($borrowernumber);
40
41
if ( checkauth( $cgi, 0, { borrowers => 1 }, 'intranet' ) ) {
42
43
    #  print $cgi->header;
44
    my $barcode     = $cgi->param('barcode');
45
    my $itemnumber  = $cgi->param('itemnumber');
46
    my $description = $cgi->param('description');
47
    my $amount      = $cgi->param('amount');
48
    my $type        = $cgi->param('type');
49
    my $notes       = $cgi->param('notes');
50
51
    if ( !$itemnumber && $barcode ) {
52
        $itemnumber = GetItemnumberFromBarcode($barcode);
53
    }
54
55
    my $debit = AddDebit(
56
        {
57
            borrower    => $borrower,
58
            amount      => $amount,
59
            type        => $type,
60
            itemnumber  => $itemnumber,
61
            description => $description,
62
            notes       => $notes,
63
64
        }
65
    );
66
67
    print $cgi->redirect(
68
        "/cgi-bin/koha/members/account.pl?borrowernumber=$borrowernumber");
69
}
(-)a/members/account_payment.pl (+122 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2000-2002 Katipo Communications
4
# Copyright 2010 BibLibre
5
# Copyright 2010,2011 PTFS-Europe Ltd
6
# Copyright 2013 ByWater Solutions
7
#
8
# This file is part of Koha.
9
#
10
# Koha is free software; you can redistribute it and/or modify it under the
11
# terms of the GNU General Public License as published by the Free Software
12
# Foundation; either version 2 of the License, or (at your option) any later
13
# version.
14
#
15
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
16
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License along
20
# with Koha; if not, write to the Free Software Foundation, Inc.,
21
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23
=head1 account_payment.pl
24
25
 written 11/1/2000 by chris@katipo.oc.nz
26
 part of the koha library system, script to facilitate paying off fines
27
28
=cut
29
30
use Modern::Perl;
31
32
use CGI;
33
34
use URI::Escape;
35
36
use C4::Context;
37
use C4::Auth;
38
use C4::Output;
39
use C4::Members;
40
use C4::Stats;
41
use C4::Koha;
42
use C4::Overdues;
43
use C4::Branch;
44
use C4::Members::Attributes qw(GetBorrowerAttributes);
45
use Koha::Database;
46
47
our $cgi = CGI->new;
48
49
our ( $template, $loggedinuser, $cookie ) = get_template_and_user(
50
    {
51
        template_name   => 'members/account_payment.tt',
52
        query           => $cgi,
53
        type            => 'intranet',
54
        authnotrequired => 0,
55
        flagsrequired   => { borrowers => 1, updatecharges => 1 },
56
        debug           => 1,
57
    }
58
);
59
60
my $borrowernumber = $cgi->param('borrowernumber');
61
62
my $borrower = GetMember( borrowernumber => $borrowernumber );
63
64
my @debits = Koha::Database->new()->schema->resultset('AccountDebit')->search(
65
    {
66
        'me.borrowernumber' => $borrowernumber,
67
        amount_outstanding  => { '>' => 0 }
68
    }
69
);
70
71
$template->param(
72
    debits   => \@debits,
73
    borrower => $borrower,
74
);
75
76
# Standard /members/ borrower details data
77
## FIXME: This code is in every /members/ script and should be unified
78
79
if ( $borrower->{'category_type'} eq 'C' ) {
80
    my ( $catcodes, $labels ) =
81
      GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
82
    my $cnt = scalar(@$catcodes);
83
    $template->param( 'CATCODE_MULTI' => 1 ) if $cnt > 1;
84
    $template->param( 'catcode' => $catcodes->[0] ) if $cnt == 1;
85
}
86
87
my ( $picture, $dberror ) = GetPatronImage( $borrower->{'borrowernumber'} );
88
$template->param( picture => 1 ) if $picture;
89
90
if ( C4::Context->preference('ExtendedPatronAttributes') ) {
91
    my $attributes = GetBorrowerAttributes($borrowernumber);
92
    $template->param(
93
        ExtendedPatronAttributes => 1,
94
        extendedattributes       => $attributes
95
    );
96
}
97
98
$template->param(
99
    borrowernumber => $borrowernumber,
100
    firstname      => $borrower->{'firstname'},
101
    surname        => $borrower->{'surname'},
102
    cardnumber     => $borrower->{'cardnumber'},
103
    categorycode   => $borrower->{'categorycode'},
104
    category_type  => $borrower->{'category_type'},
105
    categoryname   => $borrower->{'description'},
106
    address        => $borrower->{'address'},
107
    address2       => $borrower->{'address2'},
108
    city           => $borrower->{'city'},
109
    state          => $borrower->{'state'},
110
    zipcode        => $borrower->{'zipcode'},
111
    country        => $borrower->{'country'},
112
    phone          => $borrower->{'phone'},
113
    email          => $borrower->{'email'},
114
    branchcode     => $borrower->{'branchcode'},
115
    branchname     => GetBranchName( $borrower->{'branchcode'} ),
116
    is_child       => ( $borrower->{'category_type'} eq 'C' ),
117
    activeBorrowerRelationship =>
118
      ( C4::Context->preference('borrowerRelationship') ne '' ),
119
    RoutingSerials => C4::Context->preference('RoutingSerials'),
120
);
121
122
output_html_with_http_headers $cgi, $cookie, $template->output;
(-)a/members/account_payment_do.pl (+66 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2000-2002 Katipo Communications
4
# Copyright 2010 BibLibre
5
# Copyright 2013 ByWater Solutions
6
#
7
# This file is part of Koha.
8
#
9
# Koha is free software; you can redistribute it and/or modify it under the
10
# terms of the GNU General Public License as published by the Free Software
11
# Foundation; either version 2 of the License, or (at your option) any later
12
# version.
13
#
14
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License along
19
# with Koha; if not, write to the Free Software Foundation, Inc.,
20
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22
use Modern::Perl;
23
24
use CGI;
25
26
use C4::Auth;
27
use C4::Members;
28
use C4::Items;
29
use C4::Branch;
30
use C4::Members::Attributes qw(GetBorrowerAttributes);
31
use Koha::Accounts;
32
use Koha::Database;
33
34
my $cgi = new CGI;
35
36
if ( checkauth( $cgi, 0, { borrowers => 1 }, 'intranet' ) ) {
37
    my $borrowernumber = $cgi->param('borrowernumber');
38
39
    my $borrower =
40
      Koha::Database->new()->schema->resultset('Borrower')
41
      ->find($borrowernumber);
42
43
    my $amount_to_pay   = $cgi->param('amount_to_pay');
44
    my $amount_received = $cgi->param('amount_received');
45
    my $type            = $cgi->param('type');
46
    my $notes           = $cgi->param('notes');
47
    my @debit_id        = $cgi->param('debit_id');
48
49
    $amount_received ||= $amount_to_pay
50
      if $type eq Koha::Accounts::CreditTypes::Payment();
51
52
    my $debit = AddCredit(
53
        {
54
            borrower        => $borrower,
55
            amount_received => $amount_received,
56
            amount          => $amount_to_pay,
57
            type            => $type,
58
            notes           => $notes,
59
            debit_id        => \@debit_id,
60
61
        }
62
    );
63
64
    print $cgi->redirect(
65
        "/cgi-bin/koha/members/account.pl?borrowernumber=$borrowernumber");
66
}
(-)a/members/account_print.pl (+58 lines)
Line 0 Link Here
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 2 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 CGI;
21
22
use C4::Auth;
23
use C4::Output;
24
use Koha::Database;
25
26
my $cgi = new CGI;
27
28
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
29
    {
30
        template_name   => "members/account_print.tt",
31
        query           => $cgi,
32
        type            => "intranet",
33
        authnotrequired => 0,
34
        flagsrequired   => { borrowers => 1, updatecharges => 1 },
35
        debug           => 1,
36
    }
37
);
38
39
my $type = $cgi->param('type');
40
my $id   = $cgi->param('id');
41
42
warn "No type passed in!" unless $type;
43
warn "No id passed in!"   unless $id;
44
45
if ( $type eq 'debit' ) {
46
    my $debit =
47
      Koha::Database->new()->schema->resultset('AccountDebit')->find($id);
48
    $template->param( debit => $debit );
49
}
50
elsif ( $type eq 'credit' ) {
51
    my $credit =
52
      Koha::Database->new()->schema->resultset('AccountCredit')->find($id);
53
    $template->param( credit => $credit );
54
}
55
56
$template->param( type => $type );
57
58
output_html_with_http_headers $cgi, $cookie, $template->output;
(-)a/members/boraccount.pl (-135 lines)
Lines 1-135 Link Here
1
#!/usr/bin/perl
2
3
4
#writen 11/1/2000 by chris@katipo.oc.nz
5
#script to display borrowers account details
6
7
8
# Copyright 2000-2002 Katipo Communications
9
#
10
# This file is part of Koha.
11
#
12
# Koha is free software; you can redistribute it and/or modify it under the
13
# terms of the GNU General Public License as published by the Free Software
14
# Foundation; either version 2 of the License, or (at your option) any later
15
# version.
16
#
17
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License along
22
# with Koha; if not, write to the Free Software Foundation, Inc.,
23
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25
use strict;
26
use warnings;
27
28
use C4::Auth;
29
use C4::Output;
30
use C4::Dates qw/format_date/;
31
use CGI;
32
use C4::Members;
33
use C4::Branch;
34
use C4::Accounts;
35
use C4::Members::Attributes qw(GetBorrowerAttributes);
36
37
my $input=new CGI;
38
39
40
my ($template, $loggedinuser, $cookie)
41
    = get_template_and_user({template_name => "members/boraccount.tmpl",
42
                            query => $input,
43
                            type => "intranet",
44
                            authnotrequired => 0,
45
                            flagsrequired => {borrowers => 1, updatecharges => 1},
46
                            debug => 1,
47
                            });
48
49
my $borrowernumber=$input->param('borrowernumber');
50
my $action = $input->param('action') || '';
51
52
#get borrower details
53
my $data=GetMember('borrowernumber' => $borrowernumber);
54
55
if ( $action eq 'reverse' ) {
56
  ReversePayment( $input->param('accountlines_id') );
57
}
58
59
if ( $data->{'category_type'} eq 'C') {
60
   my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
61
   my $cnt = scalar(@$catcodes);
62
   $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
63
   $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
64
}
65
66
#get account details
67
my ($total,$accts,undef)=GetMemberAccountRecords($borrowernumber);
68
my $totalcredit;
69
if($total <= 0){
70
        $totalcredit = 1;
71
}
72
73
my $reverse_col = 0; # Flag whether we need to show the reverse column
74
foreach my $accountline ( @{$accts}) {
75
    $accountline->{amount} += 0.00;
76
    if ($accountline->{amount} <= 0 ) {
77
        $accountline->{amountcredit} = 1;
78
    }
79
    $accountline->{amountoutstanding} += 0.00;
80
    if ( $accountline->{amountoutstanding} <= 0 ) {
81
        $accountline->{amountoutstandingcredit} = 1;
82
    }
83
84
    $accountline->{date} = format_date($accountline->{date});
85
    $accountline->{amount} = sprintf '%.2f', $accountline->{amount};
86
    $accountline->{amountoutstanding} = sprintf '%.2f', $accountline->{amountoutstanding};
87
    if ($accountline->{accounttype} eq 'Pay') {
88
        $accountline->{payment} = 1;
89
        $reverse_col = 1;
90
    }
91
}
92
93
$template->param( adultborrower => 1 ) if ( $data->{'category_type'} eq 'A' );
94
95
my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
96
$template->param( picture => 1 ) if $picture;
97
98
if (C4::Context->preference('ExtendedPatronAttributes')) {
99
    my $attributes = GetBorrowerAttributes($borrowernumber);
100
    $template->param(
101
        ExtendedPatronAttributes => 1,
102
        extendedattributes => $attributes
103
    );
104
}
105
106
$template->param(
107
    finesview           => 1,
108
    firstname           => $data->{'firstname'},
109
    surname             => $data->{'surname'},
110
    othernames          => $data->{'othernames'},
111
    borrowernumber      => $borrowernumber,
112
    cardnumber          => $data->{'cardnumber'},
113
    categorycode        => $data->{'categorycode'},
114
    category_type       => $data->{'category_type'},
115
    categoryname		=> $data->{'description'},
116
    address             => $data->{'address'},
117
    address2            => $data->{'address2'},
118
    city                => $data->{'city'},
119
    state               => $data->{'state'},
120
    zipcode             => $data->{'zipcode'},
121
    country             => $data->{'country'},
122
    phone               => $data->{'phone'},
123
    email               => $data->{'email'},
124
    branchcode          => $data->{'branchcode'},
125
	branchname			=> GetBranchName($data->{'branchcode'}),
126
    total               => sprintf("%.2f",$total),
127
    totalcredit         => $totalcredit,
128
    is_child            => ($data->{'category_type'} eq 'C'),
129
    reverse_col         => $reverse_col,
130
    accounts            => $accts,
131
	activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
132
    RoutingSerials => C4::Context->preference('RoutingSerials'),
133
);
134
135
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/members/mancredit.pl (-114 lines)
Lines 1-114 Link Here
1
#!/usr/bin/perl
2
3
#written 11/1/2000 by chris@katipo.oc.nz
4
#script to display borrowers account details
5
6
7
# Copyright 2000-2002 Katipo Communications
8
# Copyright 2010 BibLibre
9
#
10
# This file is part of Koha.
11
#
12
# Koha is free software; you can redistribute it and/or modify it under the
13
# terms of the GNU General Public License as published by the Free Software
14
# Foundation; either version 2 of the License, or (at your option) any later
15
# version.
16
#
17
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License along
22
# with Koha; if not, write to the Free Software Foundation, Inc.,
23
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25
use strict;
26
use warnings;
27
28
use C4::Auth;
29
use C4::Output;
30
use CGI;
31
32
use C4::Members;
33
use C4::Branch;
34
use C4::Accounts;
35
use C4::Items;
36
use C4::Members::Attributes qw(GetBorrowerAttributes);
37
38
my $input=new CGI;
39
my $flagsrequired = { borrowers => 1, updatecharges => 1 };
40
41
my $borrowernumber=$input->param('borrowernumber');
42
43
#get borrower details
44
my $data=GetMember('borrowernumber' => $borrowernumber);
45
my $add=$input->param('add');
46
47
if ($add){
48
    if ( checkauth( $input, 0, $flagsrequired, 'intranet' ) ) {
49
        my $barcode = $input->param('barcode');
50
        my $itemnum;
51
        if ($barcode) {
52
            $itemnum = GetItemnumberFromBarcode($barcode);
53
        }
54
        my $desc    = $input->param('desc');
55
        my $note    = $input->param('note');
56
        my $amount  = $input->param('amount') || 0;
57
        $amount = -$amount;
58
        my $type = $input->param('type');
59
        manualinvoice( $borrowernumber, $itemnum, $desc, $type, $amount, $note );
60
        print $input->redirect("/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber");
61
    }
62
} else {
63
	my ($template, $loggedinuser, $cookie)
64
	  = get_template_and_user({template_name => "members/mancredit.tmpl",
65
					  query => $input,
66
					  type => "intranet",
67
					  authnotrequired => 0,
68
                      flagsrequired => $flagsrequired,
69
					  debug => 1,
70
					  });
71
					  
72
    if ( $data->{'category_type'} eq 'C') {
73
        my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
74
        my $cnt = scalar(@$catcodes);
75
        $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
76
        $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
77
    }
78
79
    $template->param( adultborrower => 1 ) if ( $data->{category_type} eq 'A' );
80
    my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
81
    $template->param( picture => 1 ) if $picture;
82
83
if (C4::Context->preference('ExtendedPatronAttributes')) {
84
    my $attributes = GetBorrowerAttributes($borrowernumber);
85
    $template->param(
86
        ExtendedPatronAttributes => 1,
87
        extendedattributes => $attributes
88
    );
89
}
90
    
91
    $template->param(
92
        borrowernumber => $borrowernumber,
93
        firstname => $data->{'firstname'},
94
        surname  => $data->{'surname'},
95
		    cardnumber => $data->{'cardnumber'},
96
		    categorycode => $data->{'categorycode'},
97
		    category_type => $data->{'category_type'},
98
		    categoryname  => $data->{'description'},
99
		    address => $data->{'address'},
100
		    address2 => $data->{'address2'},
101
		    city => $data->{'city'},
102
		    state => $data->{'state'},
103
		    zipcode => $data->{'zipcode'},
104
		    country => $data->{'country'},
105
		    phone => $data->{'phone'},
106
		    email => $data->{'email'},
107
		    branchcode => $data->{'branchcode'},
108
		    branchname => GetBranchName($data->{'branchcode'}),
109
		    is_child        => ($data->{'category_type'} eq 'C'),
110
			activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
111
            RoutingSerials => C4::Context->preference('RoutingSerials'),
112
        );
113
    output_html_with_http_headers $input, $cookie, $template->output;
114
}
(-)a/members/maninvoice.pl (-141 lines)
Lines 1-141 Link Here
1
#!/usr/bin/perl
2
3
#written 11/1/2000 by chris@katipo.oc.nz
4
#script to display borrowers account details
5
6
7
# Copyright 2000-2002 Katipo Communications
8
# Copyright 2010 BibLibre
9
#
10
# This file is part of Koha.
11
#
12
# Koha is free software; you can redistribute it and/or modify it under the
13
# terms of the GNU General Public License as published by the Free Software
14
# Foundation; either version 2 of the License, or (at your option) any later
15
# version.
16
#
17
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License along
22
# with Koha; if not, write to the Free Software Foundation, Inc.,
23
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25
use strict;
26
use warnings;
27
28
use C4::Auth;
29
use C4::Output;
30
use CGI;
31
use C4::Members;
32
use C4::Accounts;
33
use C4::Items;
34
use C4::Branch;
35
use C4::Members::Attributes qw(GetBorrowerAttributes);
36
37
my $input=new CGI;
38
my $flagsrequired = { borrowers => 1 };
39
40
my $borrowernumber=$input->param('borrowernumber');
41
42
43
# get borrower details
44
my $data=GetMember('borrowernumber'=>$borrowernumber);
45
my $add=$input->param('add');
46
if ($add){
47
    if ( checkauth( $input, 0, $flagsrequired, 'intranet' ) ) {
48
        #  print $input->header;
49
        my $barcode=$input->param('barcode');
50
        my $itemnum;
51
        if ($barcode) {
52
            $itemnum = GetItemnumberFromBarcode($barcode);
53
        }
54
        my $desc=$input->param('desc');
55
        my $amount=$input->param('amount');
56
        my $type=$input->param('type');
57
        my $note    = $input->param('note');
58
        my $error   = manualinvoice( $borrowernumber, $itemnum, $desc, $type, $amount, $note );
59
        if ($error) {
60
            my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
61
                {   template_name   => "members/maninvoice.tmpl",
62
                    query           => $input,
63
                    type            => "intranet",
64
                    authnotrequired => 0,
65
                    flagsrequired   => $flagsrequired,
66
                    debug           => 1,
67
                }
68
            );
69
            if ( $error =~ /FOREIGN KEY/ && $error =~ /itemnumber/ ) {
70
                $template->param( 'ITEMNUMBER' => 1 );
71
            }
72
            $template->param( 'ERROR' => $error );
73
            output_html_with_http_headers $input, $cookie, $template->output;
74
        } else {
75
            print $input->redirect("/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber");
76
            exit;
77
        }
78
    }
79
} else {
80
81
	my ($template, $loggedinuser, $cookie)
82
	= get_template_and_user({template_name => "members/maninvoice.tmpl",
83
					query => $input,
84
					type => "intranet",
85
					authnotrequired => 0,
86
					flagsrequired => {borrowers => 1, updatecharges => 1},
87
					debug => 1,
88
					});
89
					
90
  # get authorised values with type of MANUAL_INV
91
  my @invoice_types;
92
  my $dbh = C4::Context->dbh;
93
  my $sth = $dbh->prepare('SELECT * FROM authorised_values WHERE category = "MANUAL_INV"');
94
  $sth->execute();
95
  while ( my $row = $sth->fetchrow_hashref() ) {
96
    push @invoice_types, $row;
97
  }
98
  $template->param( invoice_types_loop => \@invoice_types );
99
100
    if ( $data->{'category_type'} eq 'C') {
101
        my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
102
        my $cnt = scalar(@$catcodes);
103
        $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
104
        $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
105
    }
106
107
    $template->param( adultborrower => 1 ) if ( $data->{'category_type'} eq 'A' );
108
    my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
109
    $template->param( picture => 1 ) if $picture;
110
111
if (C4::Context->preference('ExtendedPatronAttributes')) {
112
    my $attributes = GetBorrowerAttributes($borrowernumber);
113
    $template->param(
114
        ExtendedPatronAttributes => 1,
115
        extendedattributes => $attributes
116
    );
117
}
118
	$template->param(
119
                borrowernumber => $borrowernumber,
120
		firstname => $data->{'firstname'},
121
                surname  => $data->{'surname'},
122
		cardnumber => $data->{'cardnumber'},
123
		categorycode => $data->{'categorycode'},
124
		category_type => $data->{'category_type'},
125
		categoryname  => $data->{'description'},
126
		address => $data->{'address'},
127
		address2 => $data->{'address2'},
128
		city => $data->{'city'},
129
		state => $data->{'state'},
130
		zipcode => $data->{'zipcode'},
131
		country => $data->{'country'},
132
		phone => $data->{'phone'},
133
		email => $data->{'email'},
134
		branchcode => $data->{'branchcode'},
135
		branchname => GetBranchName($data->{'branchcode'}),
136
		is_child        => ($data->{'category_type'} eq 'C'),
137
		activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
138
        RoutingSerials => C4::Context->preference('RoutingSerials'),
139
    );
140
    output_html_with_http_headers $input, $cookie, $template->output;
141
}
(-)a/members/moremember.pl (-3 / +2 lines)
Lines 223-229 if ( C4::Context->preference("IndependentBranches") ) { Link Here
223
my $branchdetail = GetBranchDetail( $data->{'branchcode'});
223
my $branchdetail = GetBranchDetail( $data->{'branchcode'});
224
@{$data}{keys %$branchdetail} = values %$branchdetail; # merge in all branch columns
224
@{$data}{keys %$branchdetail} = values %$branchdetail; # merge in all branch columns
225
225
226
my ( $total, $accts, $numaccts) = GetMemberAccountRecords( $borrowernumber );
227
my $lib1 = &GetSortDetails( "Bsort1", $data->{'sort1'} );
226
my $lib1 = &GetSortDetails( "Bsort1", $data->{'sort1'} );
228
my $lib2 = &GetSortDetails( "Bsort2", $data->{'sort2'} );
227
my $lib2 = &GetSortDetails( "Bsort2", $data->{'sort2'} );
229
$template->param( lib1 => $lib1 ) if ($lib1);
228
$template->param( lib1 => $lib1 ) if ($lib1);
Lines 414-421 $template->param( Link Here
414
    branch          => $branch,
413
    branch          => $branch,
415
    todaysdate      => C4::Dates->today(),
414
    todaysdate      => C4::Dates->today(),
416
    totalprice      => sprintf("%.2f", $totalprice),
415
    totalprice      => sprintf("%.2f", $totalprice),
417
    totaldue        => sprintf("%.2f", $total),
416
    totaldue        => sprintf("%.2f", $data->{account_balance}),
418
    totaldue_raw    => $total,
417
    totaldue_raw    => $data->{account_balance},
419
    issueloop       => @issuedata,
418
    issueloop       => @issuedata,
420
    relissueloop    => @relissuedata,
419
    relissueloop    => @relissuedata,
421
    overdues_exist  => $overdues_exist,
420
    overdues_exist  => $overdues_exist,
(-)a/members/pay.pl (-261 lines)
Lines 1-261 Link Here
1
#!/usr/bin/perl
2
3
# Copyright 2000-2002 Katipo Communications
4
# Copyright 2010 BibLibre
5
# Copyright 2010,2011 PTFS-Europe Ltd
6
#
7
# This file is part of Koha.
8
#
9
# Koha is free software; you can redistribute it and/or modify it under the
10
# terms of the GNU General Public License as published by the Free Software
11
# Foundation; either version 2 of the License, or (at your option) any later
12
# version.
13
#
14
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License along
19
# with Koha; if not, write to the Free Software Foundation, Inc.,
20
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22
=head1 pay.pl
23
24
 written 11/1/2000 by chris@katipo.oc.nz
25
 part of the koha library system, script to facilitate paying off fines
26
27
=cut
28
29
use strict;
30
use warnings;
31
32
use URI::Escape;
33
use C4::Context;
34
use C4::Auth;
35
use C4::Output;
36
use CGI;
37
use C4::Members;
38
use C4::Accounts;
39
use C4::Stats;
40
use C4::Koha;
41
use C4::Overdues;
42
use C4::Branch;
43
use C4::Members::Attributes qw(GetBorrowerAttributes);
44
45
our $input = CGI->new;
46
47
our ( $template, $loggedinuser, $cookie ) = get_template_and_user(
48
    {   template_name   => 'members/pay.tmpl',
49
        query           => $input,
50
        type            => 'intranet',
51
        authnotrequired => 0,
52
        flagsrequired   => { borrowers => 1, updatecharges => 1 },
53
        debug           => 1,
54
    }
55
);
56
57
my @names = $input->param;
58
59
our $borrowernumber = $input->param('borrowernumber');
60
if ( !$borrowernumber ) {
61
    $borrowernumber = $input->param('borrowernumber0');
62
}
63
64
# get borrower details
65
our $borrower = GetMember( borrowernumber => $borrowernumber );
66
our $user = $input->remote_user;
67
$user ||= q{};
68
69
my $branches = GetBranches();
70
our $branch = GetBranch( $input, $branches );
71
72
my $writeoff_item = $input->param('confirm_writeoff');
73
my $paycollect    = $input->param('paycollect');
74
if ($paycollect) {
75
    print $input->redirect(
76
        "/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber");
77
}
78
my $payselected = $input->param('payselected');
79
if ($payselected) {
80
    payselected(@names);
81
}
82
83
my $writeoff_all = $input->param('woall');    # writeoff all fines
84
if ($writeoff_all) {
85
    writeoff_all(@names);
86
} elsif ($writeoff_item) {
87
    my $accountlines_id = $input->param('accountlines_id');
88
    my $itemno       = $input->param('itemnumber');
89
    my $account_type = $input->param('accounttype');
90
    my $amount       = $input->param('amountoutstanding');
91
    my $payment_note = $input->param("payment_note");
92
    WriteOffFee( $borrowernumber, $accountlines_id, $itemno, $account_type, $amount, $branch, $payment_note );
93
}
94
95
for (@names) {
96
    if (/^pay_indiv_(\d+)$/) {
97
        my $line_no = $1;
98
        redirect_to_paycollect( 'pay_individual', $line_no );
99
    } elsif (/^wo_indiv_(\d+)$/) {
100
        my $line_no = $1;
101
        redirect_to_paycollect( 'writeoff_individual', $line_no );
102
    }
103
}
104
105
$template->param(
106
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
107
    RoutingSerials => C4::Context->preference('RoutingSerials'),
108
);
109
110
add_accounts_to_template();
111
112
output_html_with_http_headers $input, $cookie, $template->output;
113
114
sub add_accounts_to_template {
115
116
    my ( $total, undef, undef ) = GetMemberAccountRecords($borrowernumber);
117
    my $accounts = [];
118
    my @notify   = NumberNotifyId($borrowernumber);
119
120
    my $notify_groups = [];
121
    for my $notify_id (@notify) {
122
        my ( $acct_total, $accountlines, undef ) =
123
          GetBorNotifyAcctRecord( $borrowernumber, $notify_id );
124
        if ( @{$accountlines} ) {
125
            my $totalnotify = AmountNotify( $notify_id, $borrowernumber );
126
            push @{$accounts},
127
              { accountlines => $accountlines,
128
                notify       => $notify_id,
129
                total        => $totalnotify,
130
              };
131
        }
132
    }
133
    borrower_add_additional_fields($borrower);
134
    $template->param(
135
        accounts => $accounts,
136
        borrower => $borrower,
137
        total    => $total,
138
    );
139
    return;
140
141
}
142
143
sub get_for_redirect {
144
    my ( $name, $name_in, $money ) = @_;
145
    my $s     = q{&} . $name . q{=};
146
    my $value = $input->param($name_in);
147
    if ( !defined $value ) {
148
        $value = ( $money == 1 ) ? 0 : q{};
149
    }
150
    if ($money) {
151
        $s .= sprintf '%.2f', $value;
152
    } else {
153
        $s .= $value;
154
    }
155
    return $s;
156
}
157
158
sub redirect_to_paycollect {
159
    my ( $action, $line_no ) = @_;
160
    my $redirect =
161
      "/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber";
162
    $redirect .= q{&};
163
    $redirect .= "$action=1";
164
    $redirect .= get_for_redirect( 'accounttype', "accounttype$line_no", 0 );
165
    $redirect .= get_for_redirect( 'amount', "amount$line_no", 1 );
166
    $redirect .=
167
      get_for_redirect( 'amountoutstanding', "amountoutstanding$line_no", 1 );
168
    $redirect .= get_for_redirect( 'accountno',    "accountno$line_no",    0 );
169
    $redirect .= get_for_redirect( 'title',        "title$line_no",        0 );
170
    $redirect .= get_for_redirect( 'itemnumber',   "itemnumber$line_no",   0 );
171
    $redirect .= get_for_redirect( 'notify_id',    "notify_id$line_no",    0 );
172
    $redirect .= get_for_redirect( 'notify_level', "notify_level$line_no", 0 );
173
    $redirect .= get_for_redirect( 'accountlines_id', "accountlines_id$line_no", 0 );
174
    $redirect .= q{&} . 'payment_note' . q{=} . uri_escape( $input->param("payment_note_$line_no") );
175
    $redirect .= '&remote_user=';
176
    $redirect .= $user;
177
    return print $input->redirect($redirect);
178
}
179
180
sub writeoff_all {
181
    my @params = @_;
182
    my @wo_lines = grep { /^accountno\d+$/ } @params;
183
    for (@wo_lines) {
184
        if (/(\d+)/) {
185
            my $value       = $1;
186
            my $accounttype = $input->param("accounttype$value");
187
188
            #    my $borrowernum    = $input->param("borrowernumber$value");
189
            my $itemno    = $input->param("itemnumber$value");
190
            my $amount    = $input->param("amountoutstanding$value");
191
            my $accountno = $input->param("accountno$value");
192
            my $accountlines_id = $input->param("accountlines_id$value");
193
            my $payment_note = $input->param("payment_note_$value");
194
            WriteOffFee( $borrowernumber, $accountlines_id, $itemno, $accounttype, $amount, $branch, $payment_note );
195
        }
196
    }
197
198
    $borrowernumber = $input->param('borrowernumber');
199
    print $input->redirect(
200
        "/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber");
201
    return;
202
}
203
204
sub borrower_add_additional_fields {
205
    my $b_ref = shift;
206
207
# some borrower info is not returned in the standard call despite being assumed
208
# in a number of templates. It should not be the business of this script but in lieu of
209
# a revised api here it is ...
210
    if ( $b_ref->{category_type} eq 'C' ) {
211
        my ( $catcodes, $labels ) =
212
          GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
213
        if ( @{$catcodes} ) {
214
            if ( @{$catcodes} > 1 ) {
215
                $b_ref->{CATCODE_MULTI} = 1;
216
            } elsif ( @{$catcodes} == 1 ) {
217
                $b_ref->{catcode} = $catcodes->[0];
218
            }
219
        }
220
    } elsif ( $b_ref->{category_type} eq 'A' ) {
221
        $b_ref->{adultborrower} = 1;
222
    }
223
    my ( $picture, $dberror ) = GetPatronImage( $b_ref->{borrowernumber} );
224
    if ($picture) {
225
        $b_ref->{has_picture} = 1;
226
    }
227
228
    if (C4::Context->preference('ExtendedPatronAttributes')) {
229
        $b_ref->{extendedattributes} = GetBorrowerAttributes($borrowernumber);
230
        $template->param(
231
            ExtendedPatronAttributes => 1,
232
        );
233
    }
234
235
    $b_ref->{branchname} = GetBranchName( $b_ref->{branchcode} );
236
    return;
237
}
238
239
sub payselected {
240
    my @params = @_;
241
    my $amt    = 0;
242
    my @lines_to_pay;
243
    foreach (@params) {
244
        if (/^incl_par_(\d+)$/) {
245
            my $index = $1;
246
            push @lines_to_pay, $input->param("accountno$index");
247
            $amt += $input->param("amountoutstanding$index");
248
        }
249
    }
250
    $amt = '&amt=' . $amt;
251
    my $sel = '&selected=' . join ',', @lines_to_pay;
252
    my $notes = '&notes=' . join("%0A", map { $input->param("payment_note_$_") } @lines_to_pay );
253
    my $redirect =
254
        "/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber"
255
      . $amt
256
      . $sel
257
      . $notes;
258
259
    print $input->redirect($redirect);
260
    return;
261
}
(-)a/members/paycollect.pl (-179 lines)
Lines 1-179 Link Here
1
#!/usr/bin/perl
2
# Copyright 2009,2010 PTFS Inc.
3
# Copyright 2011 PTFS-Europe Ltd
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 2 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, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use strict;
21
use warnings;
22
use URI::Escape;
23
use C4::Context;
24
use C4::Auth;
25
use C4::Output;
26
use CGI;
27
use C4::Members;
28
use C4::Accounts;
29
use C4::Koha;
30
use C4::Branch;
31
32
my $input = CGI->new();
33
34
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
35
    {   template_name   => 'members/paycollect.tmpl',
36
        query           => $input,
37
        type            => 'intranet',
38
        authnotrequired => 0,
39
        flagsrequired   => { borrowers => 1, updatecharges => 1 },
40
        debug           => 1,
41
    }
42
);
43
44
# get borrower details
45
my $borrowernumber = $input->param('borrowernumber');
46
my $borrower       = GetMember( borrowernumber => $borrowernumber );
47
my $user           = $input->remote_user;
48
49
# get account details
50
my $branch = GetBranch( $input, GetBranches() );
51
52
my ( $total_due, $accts, $numaccts ) = GetMemberAccountRecords($borrowernumber);
53
my $total_paid = $input->param('paid');
54
55
my $individual   = $input->param('pay_individual');
56
my $writeoff     = $input->param('writeoff_individual');
57
my $select_lines = $input->param('selected');
58
my $select       = $input->param('selected_accts');
59
my $payment_note = uri_unescape $input->param('payment_note');
60
my $accountno;
61
my $accountlines_id;
62
if ( $individual || $writeoff ) {
63
    if ($individual) {
64
        $template->param( pay_individual => 1 );
65
    } elsif ($writeoff) {
66
        $template->param( writeoff_individual => 1 );
67
    }
68
    my $accounttype       = $input->param('accounttype');
69
    $accountlines_id       = $input->param('accountlines_id');
70
    my $amount            = $input->param('amount');
71
    my $amountoutstanding = $input->param('amountoutstanding');
72
    $accountno = $input->param('accountno');
73
    my $itemnumber  = $input->param('itemnumber');
74
    my $description  = $input->param('description');
75
    my $title        = $input->param('title');
76
    my $notify_id    = $input->param('notify_id');
77
    my $notify_level = $input->param('notify_level');
78
    $total_due = $amountoutstanding;
79
    $template->param(
80
        accounttype       => $accounttype,
81
        accountlines_id    => $accountlines_id,
82
        accountno         => $accountno,
83
        amount            => $amount,
84
        amountoutstanding => $amountoutstanding,
85
        title             => $title,
86
        itemnumber        => $itemnumber,
87
        description       => $description,
88
        notify_id         => $notify_id,
89
        notify_level      => $notify_level,
90
        payment_note    => $payment_note,
91
    );
92
} elsif ($select_lines) {
93
    $total_due = $input->param('amt');
94
    $template->param(
95
        selected_accts => $select_lines,
96
        amt            => $total_due,
97
        selected_accts_notes => $input->param('notes'),
98
    );
99
}
100
101
if ( $total_paid and $total_paid ne '0.00' ) {
102
    if ( $total_paid < 0 or $total_paid > $total_due ) {
103
        $template->param(
104
            error_over => 1,
105
            total_due => $total_due
106
        );
107
    } else {
108
        if ($individual) {
109
            if ( $total_paid == $total_due ) {
110
                makepayment( $accountlines_id, $borrowernumber, $accountno, $total_paid, $user,
111
                    $branch, $payment_note );
112
            } else {
113
                makepartialpayment( $accountlines_id, $borrowernumber, $accountno, $total_paid,
114
                    $user, $branch, $payment_note );
115
            }
116
            print $input->redirect(
117
                "/cgi-bin/koha/members/pay.pl?borrowernumber=$borrowernumber");
118
        } else {
119
            if ($select) {
120
                if ( $select =~ /^([\d,]*).*/ ) {
121
                    $select = $1;    # ensure passing no junk
122
                }
123
                my @acc = split /,/, $select;
124
                my $note = $input->param('selected_accts_notes');
125
                recordpayment_selectaccts( $borrowernumber, $total_paid, \@acc, $note );
126
            } else {
127
                recordpayment( $borrowernumber, $total_paid );
128
            }
129
130
# recordpayment does not return success or failure so lets redisplay the boraccount
131
132
            print $input->redirect(
133
"/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber"
134
            );
135
        }
136
    }
137
} else {
138
    $total_paid = '0.00';    #TODO not right with pay_individual
139
}
140
141
borrower_add_additional_fields($borrower);
142
143
$template->param(
144
    borrowernumber => $borrowernumber,    # some templates require global
145
    borrower      => $borrower,
146
    total         => $total_due,
147
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
148
    RoutingSerials => C4::Context->preference('RoutingSerials'),
149
);
150
151
output_html_with_http_headers $input, $cookie, $template->output;
152
153
sub borrower_add_additional_fields {
154
    my $b_ref = shift;
155
156
# some borrower info is not returned in the standard call despite being assumed
157
# in a number of templates. It should not be the business of this script but in lieu of
158
# a revised api here it is ...
159
    if ( $b_ref->{category_type} eq 'C' ) {
160
        my ( $catcodes, $labels ) =
161
          GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
162
        if ( @{$catcodes} ) {
163
            if ( @{$catcodes} > 1 ) {
164
                $b_ref->{CATCODE_MULTI} = 1;
165
            } elsif ( @{$catcodes} == 1 ) {
166
                $b_ref->{catcode} = $catcodes->[0];
167
            }
168
        }
169
    } elsif ( $b_ref->{category_type} eq 'A' ) {
170
        $b_ref->{adultborrower} = 1;
171
    }
172
    my ( $picture, $dberror ) = GetPatronImage( $b_ref->{borrowernumber} );
173
    if ($picture) {
174
        $b_ref->{has_picture} = 1;
175
    }
176
177
    $b_ref->{branchname} = GetBranchName( $b_ref->{branchcode} );
178
    return;
179
}
(-)a/members/printfeercpt.pl (-143 lines)
Lines 1-143 Link Here
1
#!/usr/bin/perl
2
3
4
#writen 3rd May 2010 by kmkale@anantcorp.com adapted from boraccount.pl by chris@katipo.oc.nz
5
#script to print fee receipts
6
7
8
# Copyright Koustubha Kale
9
#
10
# This file is part of Koha.
11
#
12
# Koha is free software; you can redistribute it and/or modify it under the
13
# terms of the GNU General Public License as published by the Free Software
14
# Foundation; either version 2 of the License, or (at your option) any later
15
# version.
16
#
17
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License along
22
# with Koha; if not, write to the Free Software Foundation, Inc.,
23
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25
use strict;
26
use warnings;
27
28
use C4::Auth;
29
use C4::Output;
30
use C4::Dates qw/format_date/;
31
use CGI;
32
use C4::Members;
33
use C4::Branch;
34
use C4::Accounts;
35
36
my $input=new CGI;
37
38
39
my ($template, $loggedinuser, $cookie)
40
    = get_template_and_user({template_name => "members/printfeercpt.tmpl",
41
                            query => $input,
42
                            type => "intranet",
43
                            authnotrequired => 0,
44
                            flagsrequired => {borrowers => 1, updatecharges => 1},
45
                            debug => 1,
46
                            });
47
48
my $borrowernumber=$input->param('borrowernumber');
49
my $action = $input->param('action') || '';
50
my $accountlines_id = $input->param('accountlines_id');
51
52
#get borrower details
53
my $data=GetMember('borrowernumber' => $borrowernumber);
54
55
if ( $action eq 'print' ) {
56
#  ReversePayment( $borrowernumber, $input->param('accountno') );
57
}
58
59
if ( $data->{'category_type'} eq 'C') {
60
   my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
61
   my $cnt = scalar(@$catcodes);
62
   $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
63
   $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
64
}
65
66
#get account details
67
my ($total,$accts,$numaccts)=GetMemberAccountRecords($borrowernumber);
68
my $totalcredit;
69
if($total <= 0){
70
        $totalcredit = 1;
71
}
72
my @accountrows; # this is for the tmpl-loop
73
74
my $toggle;
75
for (my $i=0;$i<$numaccts;$i++){
76
    next if ( $accts->[$i]{'accountlines_id'} ne $accountlines_id );
77
    if($i%2){
78
            $toggle = 0;
79
    } else {
80
            $toggle = 1;
81
    }
82
    $accts->[$i]{'toggle'} = $toggle;
83
    $accts->[$i]{'amount'}+=0.00;
84
    if($accts->[$i]{'amount'} <= 0){
85
        $accts->[$i]{'amountcredit'} = 1;
86
	$accts->[$i]{'amount'}*=-1.00;
87
    }
88
    $accts->[$i]{'amountoutstanding'}+=0.00;
89
    if($accts->[$i]{'amountoutstanding'} <= 0){
90
        $accts->[$i]{'amountoutstandingcredit'} = 1;
91
    }
92
    my %row = ( 'date'              => format_date($accts->[$i]{'date'}),
93
                'amountcredit' => $accts->[$i]{'amountcredit'},
94
                'amountoutstandingcredit' => $accts->[$i]{'amountoutstandingcredit'},
95
                'toggle' => $accts->[$i]{'toggle'},
96
                'description'       => $accts->[$i]{'description'},
97
				'itemnumber'       => $accts->[$i]{'itemnumber'},
98
				'biblionumber'       => $accts->[$i]{'biblionumber'},
99
                'amount'            => sprintf("%.2f",$accts->[$i]{'amount'}),
100
                'amountoutstanding' => sprintf("%.2f",$accts->[$i]{'amountoutstanding'}),
101
                'accountno' => $accts->[$i]{'accountno'},
102
                'payment' => ( $accts->[$i]{'accounttype'} eq 'Pay' ),
103
104
                );
105
106
    if ($accts->[$i]{'accounttype'} ne 'F' && $accts->[$i]{'accounttype'} ne 'FU'){
107
        $row{'printtitle'}=1;
108
        $row{'title'} = $accts->[$i]{'title'};
109
    }
110
111
    push(@accountrows, \%row);
112
}
113
114
$template->param( adultborrower => 1 ) if ( $data->{'category_type'} eq 'A' );
115
116
my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
117
$template->param( picture => 1 ) if $picture;
118
119
$template->param(
120
    finesview           => 1,
121
    firstname           => $data->{'firstname'},
122
    surname             => $data->{'surname'},
123
    borrowernumber      => $borrowernumber,
124
    cardnumber          => $data->{'cardnumber'},
125
    categorycode        => $data->{'categorycode'},
126
    category_type       => $data->{'category_type'},
127
 #   category_description => $data->{'description'},
128
    categoryname		 => $data->{'description'},
129
    address             => $data->{'address'},
130
    address2            => $data->{'address2'},
131
    city                => $data->{'city'},
132
    zipcode             => $data->{'zipcode'},
133
    country             => $data->{'country'},
134
    phone               => $data->{'phone'},
135
    email               => $data->{'email'},
136
    branchcode          => $data->{'branchcode'},
137
	branchname			=> GetBranchName($data->{'branchcode'}),
138
    total               => sprintf("%.2f",$total),
139
    totalcredit         => $totalcredit,
140
	is_child        => ($data->{'category_type'} eq 'C'),
141
    accounts            => \@accountrows );
142
143
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/members/printinvoice.pl (-142 lines)
Lines 1-142 Link Here
1
#!/usr/bin/perl
2
3
#writen 3rd May 2010 by kmkale@anantcorp.com adapted from boraccount.pl by chris@katipo.oc.nz
4
#script to print fee receipts
5
6
# Copyright Koustubha Kale
7
#
8
# This file is part of Koha.
9
#
10
# Koha is free software; you can redistribute it and/or modify it under the
11
# terms of the GNU General Public License as published by the Free Software
12
# Foundation; either version 2 of the License, or (at your option) any later
13
# version.
14
#
15
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
16
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License along
20
# with Koha; if not, write to the Free Software Foundation, Inc.,
21
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23
use strict;
24
use warnings;
25
26
use C4::Auth;
27
use C4::Output;
28
use C4::Dates qw/format_date/;
29
use CGI;
30
use C4::Members;
31
use C4::Branch;
32
use C4::Accounts;
33
34
my $input = new CGI;
35
36
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
37
    {   template_name   => "members/printinvoice.tmpl",
38
        query           => $input,
39
        type            => "intranet",
40
        authnotrequired => 0,
41
        flagsrequired   => { borrowers => 1, updatecharges => 1 },
42
        debug           => 1,
43
    }
44
);
45
46
my $borrowernumber  = $input->param('borrowernumber');
47
my $action          = $input->param('action') || '';
48
my $accountlines_id = $input->param('accountlines_id');
49
50
#get borrower details
51
my $data = GetMember( 'borrowernumber' => $borrowernumber );
52
53
if ( $data->{'category_type'} eq 'C' ) {
54
    my ( $catcodes, $labels ) = GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
55
    my $cnt = scalar(@$catcodes);
56
    $template->param( 'CATCODE_MULTI' => 1 ) if $cnt > 1;
57
    $template->param( 'catcode' => $catcodes->[0] ) if $cnt == 1;
58
}
59
60
#get account details
61
my ( $total, $accts, $numaccts ) = GetMemberAccountRecords($borrowernumber);
62
my $totalcredit;
63
if ( $total <= 0 ) {
64
    $totalcredit = 1;
65
}
66
67
my @accountrows;    # this is for the tmpl-loop
68
69
my $toggle;
70
for ( my $i = 0 ; $i < $numaccts ; $i++ ) {
71
    next if ( $accts->[$i]{'accountlines_id'} ne $accountlines_id );
72
73
    if ( $i % 2 ) {
74
        $toggle = 0;
75
    } else {
76
        $toggle = 1;
77
    }
78
79
    $accts->[$i]{'toggle'} = $toggle;
80
    $accts->[$i]{'amount'} += 0.00;
81
82
    if ( $accts->[$i]{'amount'} <= 0 ) {
83
        $accts->[$i]{'amountcredit'} = 1;
84
    }
85
86
    $accts->[$i]{'amountoutstanding'} += 0.00;
87
    if ( $accts->[$i]{'amountoutstanding'} <= 0 ) {
88
        $accts->[$i]{'amountoutstandingcredit'} = 1;
89
    }
90
91
    my %row = (
92
        'date'                    => format_date( $accts->[$i]{'date'} ),
93
        'amountcredit'            => $accts->[$i]{'amountcredit'},
94
        'amountoutstandingcredit' => $accts->[$i]{'amountoutstandingcredit'},
95
        'toggle'                  => $accts->[$i]{'toggle'},
96
        'description'             => $accts->[$i]{'description'},
97
        'itemnumber'              => $accts->[$i]{'itemnumber'},
98
        'biblionumber'            => $accts->[$i]{'biblionumber'},
99
        'amount'                  => sprintf( "%.2f", $accts->[$i]{'amount'} ),
100
        'amountoutstanding'       => sprintf( "%.2f", $accts->[$i]{'amountoutstanding'} ),
101
        'accountno'               => $accts->[$i]{'accountno'},
102
        'payment'                 => ( $accts->[$i]{'accounttype'} eq 'Pay' ),
103
    );
104
105
    if ( $accts->[$i]{'accounttype'} ne 'F' && $accts->[$i]{'accounttype'} ne 'FU' ) {
106
        $row{'printtitle'} = 1;
107
        $row{'title'}      = $accts->[$i]{'title'};
108
    }
109
110
    push( @accountrows, \%row );
111
}
112
113
$template->param( adultborrower => 1 ) if ( $data->{'category_type'} eq 'A' );
114
115
my ( $picture, $dberror ) = GetPatronImage( $data->{'borrowernumber'} );
116
$template->param( picture => 1 ) if $picture;
117
118
$template->param(
119
    finesview      => 1,
120
    firstname      => $data->{'firstname'},
121
    surname        => $data->{'surname'},
122
    borrowernumber => $borrowernumber,
123
    cardnumber     => $data->{'cardnumber'},
124
    categorycode   => $data->{'categorycode'},
125
    category_type  => $data->{'category_type'},
126
    categoryname   => $data->{'description'},
127
    address        => $data->{'address'},
128
    address2       => $data->{'address2'},
129
    city           => $data->{'city'},
130
    zipcode        => $data->{'zipcode'},
131
    country        => $data->{'country'},
132
    phone          => $data->{'phone'},
133
    email          => $data->{'email'},
134
    branchcode     => $data->{'branchcode'},
135
    branchname     => GetBranchName( $data->{'branchcode'} ),
136
    total          => sprintf( "%.2f", $total ),
137
    totalcredit    => $totalcredit,
138
    is_child       => ( $data->{'category_type'} eq 'C' ),
139
    accounts       => \@accountrows
140
);
141
142
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/misc/cronjobs/create_koc_db.pl (-40 / +1 lines)
Lines 256-265 SELECT borrowernumber, Link Here
256
       city,
256
       city,
257
       phone,
257
       phone,
258
       dateofbirth,
258
       dateofbirth,
259
       sum( accountlines.amountoutstanding ) as total_fines
259
       account_balance as total_fines
260
FROM borrowers
260
FROM borrowers
261
LEFT JOIN accountlines USING (borrowernumber)
262
GROUP BY borrowernumber;
263
END_SQL
261
END_SQL
264
262
265
    my $fields_count = $sth_mysql->execute();
263
    my $fields_count = $sth_mysql->execute();
Lines 278-320 END_SQL Link Here
278
    }
276
    }
279
    $dbh_sqlite->commit();
277
    $dbh_sqlite->commit();
280
    print "inserted $count borrowers\n" if $verbose;
278
    print "inserted $count borrowers\n" if $verbose;
281
    # add_fines_to_borrowers_table();
282
}
283
284
=head2 add_fines_to_borrowers_table
285
286
Import the fines from koha.accountlines into the sqlite db
287
288
=cut
289
290
sub add_fines_to_borrowers_table {
291
292
    print "preparing to update borrowers\n" if $verbose;
293
    my $sth_mysql = $dbh_mysql->prepare(
294
        "SELECT DISTINCT borrowernumber, SUM( amountoutstanding ) AS total_fines
295
                                    FROM accountlines
296
                                    GROUP BY borrowernumber"
297
    );
298
    $sth_mysql->execute();
299
    my $count;
300
    while ( my $result = $sth_mysql->fetchrow_hashref() ) {
301
        $count++;
302
        if ( $verbose ) {
303
            print '.' unless ( $count % 10 );
304
            print "$count\n" unless ( $count % 1000 );
305
        }
306
307
        my $borrowernumber = $result->{'borrowernumber'};
308
        my $total_fines    = $result->{'total_fines'};
309
310
        # warn "Fines for Borrower # $borrowernumber are \$ $total_fines \n" if $verbose;
311
        my $sql = "UPDATE borrowers SET total_fines = ? WHERE borrowernumber = ?";
312
313
        my $sth_sqlite = $dbh_sqlite->prepare($sql);
314
        $sth_sqlite->execute( $total_fines, $borrowernumber );
315
        $sth_sqlite->finish();
316
    }
317
    print "updated $count borrowers\n" if ( $verbose && $count );
318
}
279
}
319
280
320
=head2 create_issue_table
281
=head2 create_issue_table
(-)a/misc/cronjobs/fines.pl (-3 / +7 lines)
Lines 127-135 for my $overdue ( @{$overdues} ) { Link Here
127
    if ( $mode eq 'production' && !$is_holiday{$branchcode} ) {
127
    if ( $mode eq 'production' && !$is_holiday{$branchcode} ) {
128
        if ( $amount > 0 ) {
128
        if ( $amount > 0 ) {
129
            UpdateFine(
129
            UpdateFine(
130
                $overdue->{itemnumber},
130
                {
131
                $overdue->{borrowernumber},
131
                    itemnumber     => $overdue->{itemnumber},
132
                $amount, $type, output_pref($datedue)
132
                    borrowernumber => $overdue->{borrowernumber},
133
                    amount         => $amount,
134
                    due            => output_pref($datedue),
135
                    issue_id       => $overdue->{issue_id}
136
                }
133
            );
137
            );
134
        }
138
        }
135
    }
139
    }
(-)a/misc/maintenance/fix_accountlines_date.pl (-171 lines)
Lines 1-171 Link Here
1
#!/usr/bin/perl
2
#
3
# Copyright (C) 2008 LibLime
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 2 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, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use strict;
21
use warnings;
22
BEGIN {
23
    # find Koha's Perl modules
24
    # test carefully before changing this
25
    use FindBin;
26
    eval { require "$FindBin::Bin/../kohalib.pl" };
27
}
28
29
use C4::Context;
30
use C4::Dates;
31
use Getopt::Long;
32
use Pod::Usage;
33
34
=head1 NAME
35
36
fix_accountlines_date.pl - Fix date code in the description of fines
37
38
=head1 SYNOPSIS
39
40
fix_accountlines_date.pl -m date_format [ -n fines_to_process ] [ -d ] [ --help or -h ]
41
42
 Options:
43
   --help or -h                Brief usage message
44
   --man                       Full documentation
45
   -n fines_to_process         How many fines to process; if left off will
46
                               process all
47
   -m date_format              What format the dates are currently in; 'us'
48
                               or 'metric' (REQUIRED)
49
   -d                          Run in debugging mode
50
51
=head1 DESCRIPTION
52
53
This script fixes the date code in the description of fines. Previously, the
54
format of this was determined by which script you were using to update fines (see the -m option)
55
56
=over 8
57
58
=item B<--help>
59
60
Prints a brief usage message and exits.
61
62
=item B<--man>
63
64
Prints a full manual page and exits.
65
66
=item B<-n>
67
68
Process only a certain amount of fines. If this option is left off, this script
69
will process everything.
70
71
=item B<-m>
72
73
This required option tells the script what format your dates are currently in.
74
If you were previously using the fines2.pl or fines-sanop.pl script to update 
75
your fines, they will be in 'metric' format. If you were using the fines-ll.pl
76
script, they will be in 'us' format. After this script is finished, they will
77
be in whatever format your 'dateformat' system preference specifies.
78
79
=item B<-d>
80
81
Run in debugging mode; this prints out a lot of information and should be used
82
only if there is a problem and with the '-n' option.
83
84
=back
85
86
=cut
87
88
my $mode = '';
89
my $want_help = 0;
90
my $limit = -1;
91
my $done = 0;
92
my $DEBUG = 0;
93
94
# Regexes for the two date formats
95
our $US_DATE = '((0\d|1[0-2])\/([0-2]\d|3[01])\/(\d{4}))';
96
our $METRIC_DATE = '(([0-2]\d|3[01])\/(0\d|1[0-2])\/(\d{4}))';
97
98
sub print_usage {
99
    print <<_USAGE_
100
$0: Fix the date code in the description of fines
101
102
Due to the multiple scripts used to update fines in earlier versions of Koha,
103
this script should be used to change the format of the date codes in the
104
accountlines table before you start using Koha 3.0.
105
106
Parameters:
107
  --mode or -m        This should be 'us' or 'metric', and tells the script
108
                      what format your old dates are in.
109
  --debug or -d       Run this script in debug mode.
110
  --limit or -n       How many accountlines rows to fix; useful for testing.
111
  --help or -h        Print out this help message.
112
_USAGE_
113
}
114
115
my $result = GetOptions(
116
    'm=s' => \$mode,
117
    'd'  => \$DEBUG,
118
    'n=i'  => \$limit, 
119
    'help|h'   => \$want_help,
120
);
121
122
if (not $result or $want_help or ($mode ne 'us' and $mode ne 'metric')) {
123
    print_usage();
124
    exit 0;
125
}
126
127
our $dbh = C4::Context->dbh;
128
$dbh->{AutoCommit} = 0;
129
my $sth = $dbh->prepare("
130
SELECT borrowernumber, itemnumber, accountno, description
131
  FROM accountlines
132
  WHERE accounttype in ('FU', 'F', 'O', 'M')
133
;");
134
$sth->execute();
135
136
my $update_sth = $dbh->prepare('
137
UPDATE accountlines
138
  SET description = ?
139
  WHERE borrowernumber = ? AND itemnumber = ? AND accountno = ?
140
;');
141
142
143
while (my $accountline = $sth->fetchrow_hashref) {
144
    my $description = $accountline->{'description'};
145
    my $updated = 0;
146
147
    if ($mode eq 'us') {
148
        if ($description =~ /$US_DATE/) { # mm/dd/yyyy
149
            my $date = C4::Dates->new($1, 'us');
150
            print "Converting $1 (us) to " . $date->output() . "\n" if $DEBUG;
151
            $description =~ s/$US_DATE/$date->output()/;
152
            $updated = 1;
153
        }
154
    } elsif ($mode eq 'metric') {
155
        if ($description =~ /$METRIC_DATE/) { # dd/mm/yyyy
156
            my $date = C4::Dates->new($1, 'metric');
157
            print "Converting $1 (metric) to " . $date->output() . "\n" if $DEBUG;
158
            $description =~ s/$METRIC_DATE/$date->output()/;
159
            $updated = 2;
160
        }
161
    }
162
163
    print "Changing description from '" . $accountline->{'description'} . "' to '" . $description . "'\n" if $DEBUG;
164
    $update_sth->execute($description, $accountline->{'borrowernumber'}, $accountline->{'itemnumber'}, $accountline->{'accountno'});
165
166
    $done++;
167
168
    last if ($done == $limit); # $done can't be -1, so this works
169
}
170
171
$dbh->commit();
(-)a/misc/release_notes/release_notes_3_10_0.txt (-1 / +1 lines)
Lines 1762-1768 Staff Client Link Here
1762
	8996	normal	In result page items with negative notforloan are available
1762
	8996	normal	In result page items with negative notforloan are available
1763
	9017	normal	Quote of the day: Table footer not translated
1763
	9017	normal	Quote of the day: Table footer not translated
1764
	5312	minor	XHTML correction in authority summary
1764
	5312	minor	XHTML correction in authority summary
1765
	8009	minor	Item descriptive data not populated on pay.pl
1765
  8009	minor	Item descriptive data not populated on account_payment.pl
1766
	8593	minor	Add unique IDs to pending approval markup on staff client home page
1766
	8593	minor	Add unique IDs to pending approval markup on staff client home page
1767
	8646	minor	Certain search terms cause browser "script taking too long" error
1767
	8646	minor	Certain search terms cause browser "script taking too long" error
1768
	8793	minor	Fix materialTypeCode/typeOf008 icons for NORMARC XSLT
1768
	8793	minor	Fix materialTypeCode/typeOf008 icons for NORMARC XSLT
(-)a/misc/release_notes/release_notes_3_12_0.txt (-1 / +1 lines)
Lines 579-585 Architecture, internals, and plumbing Link Here
579
	8429	minor	Unnecessary use of Exporter in SIP/ILS objects
579
	8429	minor	Unnecessary use of Exporter in SIP/ILS objects
580
	9292	minor	Remove dead code related to 'publictype'
580
	9292	minor	Remove dead code related to 'publictype'
581
	9401	minor	Javascript used for tags handling wants access to CGISESSID cookie
581
	9401	minor	Javascript used for tags handling wants access to CGISESSID cookie
582
	9582	minor	Unused code in members/pay.pl
582
 9582	minor	Unused code in members/account_payment.pl
583
	10054	minor	When SingleBranchMode is enabled, allow superlibrarians to set logged in library
583
	10054	minor	When SingleBranchMode is enabled, allow superlibrarians to set logged in library
584
	10143	minor	Fix FSF address in license headers
584
	10143	minor	Fix FSF address in license headers
585
	9609	trivial	Rebuild zebra reports double numbers for exported records with -z option
585
	9609	trivial	Rebuild zebra reports double numbers for exported records with -z option
(-)a/opac/opac-account.pl (-34 / +14 lines)
Lines 18-24 Link Here
18
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# with Koha; if not, write to the Free Software Foundation, Inc.,
19
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
20
21
22
use strict;
21
use strict;
23
use CGI;
22
use CGI;
24
use C4::Members;
23
use C4::Members;
Lines 30-36 use warnings; Link Here
30
my $query = new CGI;
29
my $query = new CGI;
31
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
30
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
32
    {
31
    {
33
        template_name   => "opac-account.tmpl",
32
        template_name   => "opac-account.tt",
34
        query           => $query,
33
        query           => $query,
35
        type            => "opac",
34
        type            => "opac",
36
        authnotrequired => 0,
35
        authnotrequired => 0,
Lines 39-78 my ( $template, $borrowernumber, $cookie ) = get_template_and_user( Link Here
39
    }
38
    }
40
);
39
);
41
40
42
# get borrower information ....
41
my @debits = Koha::Database->new()->schema->resultset('AccountDebit')->search(
43
my $borr = GetMemberDetails( $borrowernumber );
42
    { 'me.borrowernumber' => $borrowernumber },
44
my @bordat;
43
    { prefetch            => { account_offsets => 'credit' } }
45
$bordat[0] = $borr;
44
);
46
47
$template->param( BORROWER_INFO => \@bordat );
48
49
#get account details
50
my ( $total , $accts, $numaccts) = GetMemberAccountRecords( $borrowernumber );
51
52
for ( my $i = 0 ; $i < $numaccts ; $i++ ) {
53
    $accts->[$i]{'amount'} = sprintf( "%.2f", $accts->[$i]{'amount'} || '0.00');
54
    if ( $accts->[$i]{'amount'} >= 0 ) {
55
        $accts->[$i]{'amountcredit'} = 1;
56
    }
57
    $accts->[$i]{'amountoutstanding'} =
58
      sprintf( "%.2f", $accts->[$i]{'amountoutstanding'} || '0.00' );
59
    if ( $accts->[$i]{'amountoutstanding'} >= 0 ) {
60
        $accts->[$i]{'amountoutstandingcredit'} = 1;
61
    }
62
}
63
45
64
# add the row parity
46
my @credits = Koha::Database->new()->schema->resultset('AccountCredit')->search(
65
my $num = 0;
47
    { 'me.borrowernumber' => $borrowernumber },
66
foreach my $row (@$accts) {
48
    { prefetch            => { account_offsets => 'debit' } }
67
    $row->{'even'} = 1 if $num % 2 == 0;
49
);
68
    $row->{'odd'}  = 1 if $num % 2 == 1;
69
    $num++;
70
}
71
50
72
$template->param (
51
$template->param(
73
    ACCOUNT_LINES => $accts,
52
    borrower    => GetMemberDetails($borrowernumber),
74
    total => sprintf( "%.2f", $total ),
53
    debits      => \@debits,
75
	accountview => 1
54
    credits     => \@credits,
55
    accountview => 1
76
);
56
);
77
57
78
output_html_with_http_headers $query, $cookie, $template->output;
58
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/opac/opac-user.pl (-13 / +1 lines)
Lines 162-180 if ($issues){ Link Here
162
            $issue->{'reserved'} = 1;
162
            $issue->{'reserved'} = 1;
163
        }
163
        }
164
164
165
        my ( $total , $accts, $numaccts) = GetMemberAccountRecords( $borrowernumber );
165
        $issue->{'charges'} = $borr->{account_balance};
166
        my $charges = 0;
167
        foreach my $ac (@$accts) {
168
            if ( $ac->{'itemnumber'} == $issue->{'itemnumber'} ) {
169
                $charges += $ac->{'amountoutstanding'}
170
                  if $ac->{'accounttype'} eq 'F';
171
                $charges += $ac->{'amountoutstanding'}
172
                  if $ac->{'accounttype'} eq 'FU';
173
                $charges += $ac->{'amountoutstanding'}
174
                  if $ac->{'accounttype'} eq 'L';
175
            }
176
        }
177
        $issue->{'charges'} = $charges;
178
        $issue->{'subtitle'} = GetRecordValue('subtitle', GetMarcBiblio($issue->{'biblionumber'}), GetFrameworkCode($issue->{'biblionumber'}));
166
        $issue->{'subtitle'} = GetRecordValue('subtitle', GetMarcBiblio($issue->{'biblionumber'}), GetFrameworkCode($issue->{'biblionumber'}));
179
        # check if item is renewable
167
        # check if item is renewable
180
        my ($status,$renewerror) = CanBookBeRenewed( $borrowernumber, $issue->{'itemnumber'} );
168
        my ($status,$renewerror) = CanBookBeRenewed( $borrowernumber, $issue->{'itemnumber'} );
(-)a/t/db_dependent/Accounts.t (-3 / +186 lines)
Lines 1-16 Link Here
1
#!/usr/bin/perl
1
#!/usr/bin/perl
2
#
2
#
3
# This Koha test module is a stub!  
3
# This Koha test module is a stub!
4
# Add more tests here!!!
4
# Add more tests here!!!
5
5
6
use strict;
6
use strict;
7
use warnings;
7
use warnings;
8
8
9
use Test::More tests => 1;
9
use Test::More tests => 19;
10
11
use C4::Context;
10
12
11
BEGIN {
13
BEGIN {
12
        use_ok('C4::Accounts');
14
    use_ok('Koha::Database');
15
    use_ok('Koha::Accounts');
16
    use_ok('Koha::Accounts::DebitTypes');
17
    use_ok('Koha::Accounts::CreditTypes');
13
}
18
}
14
19
20
## Intial Setup ##
21
my $borrower = Koha::Database->new()->schema->resultset('Borrower')->create(
22
    {
23
        surname         => 'Test',
24
        categorycode    => 'S',
25
        branchcode      => 'MPL',
26
        account_balance => 0,
27
    }
28
);
29
30
my $biblio =
31
  Koha::Database->new()->schema->resultset('Biblio')
32
  ->create( { title => "Test Record" } );
33
my $biblioitem =
34
  Koha::Database->new()->schema->resultset('Biblioitem')
35
  ->create( { biblionumber => $biblio->biblionumber() } );
36
my $item = Koha::Database->new()->schema->resultset('Item')->create(
37
    {
38
        biblionumber     => $biblio->biblionumber(),
39
        biblioitemnumber => $biblioitem->biblioitemnumber(),
40
        replacementprice => 25.00,
41
        barcode          => q{TEST_ITEM_BARCODE}
42
    }
43
);
44
45
my $issue = Koha::Database->new()->schema->resultset('Issue')->create(
46
    {
47
        borrowernumber => $borrower->borrowernumber(),
48
        itemnumber     => $item->itemnumber(),
49
    }
50
);
51
## END initial setup
52
53
ok( Koha::Accounts::DebitTypes::Fine eq 'FINE', 'Test DebitTypes::Fine' );
54
ok( Koha::Accounts::DebitTypes::Lost eq 'LOST', 'Test DebitTypes::Lost' );
55
ok(
56
    Koha::Accounts::DebitTypes::IsValid('FINE'),
57
    'Test DebitTypes::IsValid with valid debit type'
58
);
59
ok(
60
    !Koha::Accounts::DebitTypes::IsValid('Not A Valid Fee Type'),
61
    'Test DebitTypes::IsValid with an invalid debit type'
62
);
63
my $authorised_value =
64
  Koha::Database->new()->schema->resultset('AuthorisedValue')->create(
65
    {
66
        category         => 'MANUAL_INV',
67
        authorised_value => 'TEST',
68
        lib              => 'Test',
69
    }
70
  );
71
ok( Koha::Accounts::DebitTypes::IsValid('TEST'),
72
    'Test DebitTypes::IsValid with valid authorised value debit type' );
73
$authorised_value->delete();
74
75
my $debit = AddDebit(
76
    {
77
        borrower   => $borrower,
78
        amount     => 5.00,
79
        type       => Koha::Accounts::DebitTypes::Fine,
80
        branchcode => 'MPL',
81
    }
82
);
83
ok( $debit, "AddDebit returned a valid debit id " . $debit->id() );
84
85
ok(
86
    $borrower->account_balance() == 5.00,
87
    "Borrower's account balance updated correctly"
88
);
89
90
my $debit2 = AddDebit(
91
    {
92
        borrower   => $borrower,
93
        amount     => 7.00,
94
        type       => Koha::Accounts::DebitTypes::Fine,
95
        branchcode => 'MPL',
96
    }
97
);
98
99
my $credit = AddCredit(
100
    {
101
        borrower   => $borrower,
102
        type       => Koha::Accounts::CreditTypes::Payment,
103
        amount     => 9.00,
104
        branchcode => 'MPL',
105
    }
106
);
107
108
RecalculateAccountBalance( { borrower => $borrower } );
109
ok(
110
    sprintf( "%.2f", $borrower->account_balance() ) eq "3.00",
111
    "RecalculateAccountBalance updated balance correctly."
112
);
113
114
Koha::Database->new()->schema->resultset('AccountCredit')->create(
115
    {
116
        borrowernumber   => $borrower->borrowernumber(),
117
        type             => Koha::Accounts::CreditTypes::Payment,
118
        amount_paid      => 3.00,
119
        amount_remaining => 3.00,
120
    }
121
);
122
NormalizeBalances( { borrower => $borrower } );
123
ok(
124
    $borrower->account_balance() == 0.00,
125
    "NormalizeBalances updated balance correctly."
126
);
127
128
# Adding advance credit with no balance due
129
$credit = AddCredit(
130
    {
131
        borrower   => $borrower,
132
        type       => Koha::Accounts::CreditTypes::Payment,
133
        amount     => 9.00,
134
        branchcode => 'MPL',
135
    }
136
);
137
ok(
138
    $borrower->account_balance() == -9,
139
'Adding a $9 credit for borrower with 0 balance results in a -9 dollar account balance'
140
);
141
142
my $debit3 = AddDebit(
143
    {
144
        borrower   => $borrower,
145
        amount     => 5.00,
146
        type       => Koha::Accounts::DebitTypes::Fine,
147
        branchcode => 'MPL',
148
    }
149
);
150
ok(
151
    $borrower->account_balance() == -4,
152
'Adding a $5 debit when the balance is negative results in the debit being automatically paid, resulting in a balance of -4'
153
);
154
155
my $debit4 = AddDebit(
156
    {
157
        borrower   => $borrower,
158
        amount     => 6.00,
159
        type       => Koha::Accounts::DebitTypes::Fine,
160
        branchcode => 'MPL',
161
    }
162
);
163
ok(
164
    $borrower->account_balance() == 2,
165
'Adding another debit ( 6.00 ) more than the negative account balance results in a partial credit and a balance due of 2.00'
166
);
167
$credit = AddCredit(
168
    {
169
        borrower   => $borrower,
170
        type       => Koha::Accounts::CreditTypes::WriteOff,
171
        amount     => 2.00,
172
        branchcode => 'MPL',
173
        debit_id   => $debit4->debit_id(),
174
    }
175
);
176
ok( $borrower->account_balance() == 0,
177
    'WriteOff of remaining 2.00 balance succeeds' );
178
179
my $debit5 = DebitLostItem(
180
    {
181
        borrower => $borrower,
182
        issue    => $issue,
183
    }
184
);
185
ok( $borrower->account_balance() == 25,
186
    'DebitLostItem adds debit for replacement price of item' );
15
187
188
my $lost_credit =
189
  CreditLostItem( { borrower => $borrower, debit => $debit5 } );
190
ok(
191
    $borrower->account_balance() == 0,
192
    'CreditLostItem adds credit for same about as the debit for the lost tiem'
193
);
16
194
195
## Post test cleanup ##
196
$issue->delete();
197
$item->delete();
198
$biblio->delete();
199
$borrower->delete();
(-)a/t/db_dependent/Circulation.t (-4 / +18 lines)
Lines 302-309 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
302
    C4::Context->set_preference('WhenLostForgiveFine','1');
302
    C4::Context->set_preference('WhenLostForgiveFine','1');
303
    C4::Context->set_preference('WhenLostChargeReplacementFee','1');
303
    C4::Context->set_preference('WhenLostChargeReplacementFee','1');
304
304
305
    C4::Overdues::UpdateFine( $itemnumber, $renewing_borrower->{borrowernumber},
305
    C4::Overdues::UpdateFine(
306
        15.00, q{}, Koha::DateUtils::output_pref($datedue) );
306
        {
307
            itemnumber     => $itemnumber,
308
            borrowernumber => $renewing_borrower->{borrowernumber},
309
            amount         => 15.00,
310
            due            => Koha::DateUtils::output_pref($datedue),
311
            issue_id       => GetItemIssue($itemnumber)->{issue_id}
312
        }
313
    );
307
314
308
    LostItem( $itemnumber, 1 );
315
    LostItem( $itemnumber, 1 );
309
316
Lines 319-326 C4::Context->dbh->do("DELETE FROM accountlines"); Link Here
319
    C4::Context->set_preference('WhenLostForgiveFine','0');
326
    C4::Context->set_preference('WhenLostForgiveFine','0');
320
    C4::Context->set_preference('WhenLostChargeReplacementFee','0');
327
    C4::Context->set_preference('WhenLostChargeReplacementFee','0');
321
328
322
    C4::Overdues::UpdateFine( $itemnumber2, $renewing_borrower->{borrowernumber},
329
    C4::Overdues::UpdateFine(
323
        15.00, q{}, Koha::DateUtils::output_pref($datedue) );
330
        {
331
            itemnumber     => $itemnumber2,
332
            borrowernumber => $renewing_borrower->{borrowernumber},
333
            amount         => 15.00,
334
            due            => Koha::DateUtils::output_pref($datedue),
335
            issue_id       => GetItemIssue($itemnumber2)->{issue_id},
336
        }
337
    );
324
338
325
    LostItem( $itemnumber2, 1 );
339
    LostItem( $itemnumber2, 1 );
326
340
(-)a/t/db_dependent/Members/AddEnrolmentFeeIfNeeded.t (-4 / +3 lines)
Lines 40-56 my %borrower_data = ( Link Here
40
my $borrowernumber = C4::Members::AddMember( %borrower_data );
40
my $borrowernumber = C4::Members::AddMember( %borrower_data );
41
$borrower_data{borrowernumber} = $borrowernumber;
41
$borrower_data{borrowernumber} = $borrowernumber;
42
42
43
my ( $total ) = C4::Members::GetMemberAccountRecords( $borrowernumber );
43
my ( $total ) = C4::Members::GetMemberAccountBalance( $borrowernumber );
44
is( $total, $enrolmentfee_K, "New kid pay $enrolmentfee_K" );
44
is( $total, $enrolmentfee_K, "New kid pay $enrolmentfee_K" );
45
45
46
$borrower_data{categorycode} = 'J';
46
$borrower_data{categorycode} = 'J';
47
C4::Members::ModMember( %borrower_data );
47
C4::Members::ModMember( %borrower_data );
48
( $total ) = C4::Members::GetMemberAccountRecords( $borrowernumber );
48
( $total ) = C4::Members::GetMemberAccountBalance( $borrowernumber );
49
is( $total, $enrolmentfee_K + $enrolmentfee_J, "Kid growing and become a juvenile, he should pay " . ( $enrolmentfee_K + $enrolmentfee_J ) );
49
is( $total, $enrolmentfee_K + $enrolmentfee_J, "Kid growing and become a juvenile, he should pay " . ( $enrolmentfee_K + $enrolmentfee_J ) );
50
50
51
# Check with calling directly AddEnrolmentFeeIfNeeded
51
# Check with calling directly AddEnrolmentFeeIfNeeded
52
C4::Members::AddEnrolmentFeeIfNeeded( 'YA', $borrowernumber );
52
C4::Members::AddEnrolmentFeeIfNeeded( 'YA', $borrowernumber );
53
( $total ) = C4::Members::GetMemberAccountRecords( $borrowernumber );
53
( $total ) = C4::Members::GetMemberAccountBalance( $borrowernumber );
54
is( $total, $enrolmentfee_K + $enrolmentfee_J + $enrolmentfee_YA, "Juvenile growing and become an young adult, he should pay " . ( $enrolmentfee_K + $enrolmentfee_J + $enrolmentfee_YA ) );
54
is( $total, $enrolmentfee_K + $enrolmentfee_J + $enrolmentfee_YA, "Juvenile growing and become an young adult, he should pay " . ( $enrolmentfee_K + $enrolmentfee_J + $enrolmentfee_YA ) );
55
55
56
$dbh->rollback;
56
$dbh->rollback;
57
- 

Return to bug 6427