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

(-)a/C4/Accounts.pm (-804 lines)
Lines 1-804 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(),?,'','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
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(), ?, ?, '', '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 'L' )
416
        or ( $type eq 'F' )
417
        or ( $type eq 'A' )
418
        or ( $type eq 'N' )
419
        or ( $type eq 'M' ) )
420
    {
421
        $notifyid = 1;
422
    }
423
424
    if ( $itemnum ) {
425
        $desc .= ' ' . $itemnum;
426
        my $sth = $dbh->prepare(
427
            'INSERT INTO  accountlines
428
                        (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber,notify_id, note, manager_id)
429
        VALUES (?, ?, now(), ?,?, ?,?,?,?,?,?)');
430
     $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $itemnum,$notifyid, $note, $manager_id) || return $sth->errstr;
431
  } else {
432
    my $sth=$dbh->prepare("INSERT INTO  accountlines
433
            (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding,notify_id, note, manager_id)
434
            VALUES (?, ?, now(), ?, ?, ?, ?,?,?,?)"
435
        );
436
        $sth->execute( $borrowernumber, $accountno, $amount, $desc, $type,
437
            $amountleft, $notifyid, $note, $manager_id );
438
    }
439
440
    if ( C4::Context->preference("FinesLog") ) {
441
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
442
            action            => 'create_fee',
443
            borrowernumber    => $borrowernumber,
444
            accountno         => $accountno,
445
            amount            => $amount,
446
            description       => $desc,
447
            accounttype       => $type,
448
            amountoutstanding => $amountleft,
449
            notify_id         => $notifyid,
450
            note              => $note,
451
            itemnumber        => $itemnum,
452
            manager_id        => $manager_id,
453
        }));
454
    }
455
456
    return 0;
457
}
458
459
sub getcharges {
460
	my ( $borrowerno, $timestamp, $accountno ) = @_;
461
	my $dbh        = C4::Context->dbh;
462
	my $timestamp2 = $timestamp - 1;
463
	my $query      = "";
464
	my $sth = $dbh->prepare(
465
			"SELECT * FROM accountlines WHERE borrowernumber=? AND accountno = ?"
466
          );
467
	$sth->execute( $borrowerno, $accountno );
468
	
469
    my @results;
470
    while ( my $data = $sth->fetchrow_hashref ) {
471
		push @results,$data;
472
	}
473
    return (@results);
474
}
475
476
sub ModNote {
477
    my ( $accountlines_id, $note ) = @_;
478
    my $dbh = C4::Context->dbh;
479
    my $sth = $dbh->prepare('UPDATE accountlines SET note = ? WHERE accountlines_id = ?');
480
    $sth->execute( $note, $accountlines_id );
481
}
482
483
sub getcredits {
484
	my ( $date, $date2 ) = @_;
485
	my $dbh = C4::Context->dbh;
486
	my $sth = $dbh->prepare(
487
			        "SELECT * FROM accountlines,borrowers
488
      WHERE amount < 0 AND accounttype <> 'Pay' AND accountlines.borrowernumber = borrowers.borrowernumber
489
	  AND timestamp >=TIMESTAMP(?) AND timestamp < TIMESTAMP(?)"
490
      );  
491
492
    $sth->execute( $date, $date2 );                                                                                                              
493
    my @results;          
494
    while ( my $data = $sth->fetchrow_hashref ) {
495
		$data->{'date'} = $data->{'timestamp'};
496
		push @results,$data;
497
	}
498
    return (@results);
499
} 
500
501
502
sub getrefunds {
503
	my ( $date, $date2 ) = @_;
504
	my $dbh = C4::Context->dbh;
505
	
506
	my $sth = $dbh->prepare(
507
			        "SELECT *,timestamp AS datetime                                                                                      
508
                  FROM accountlines,borrowers
509
                  WHERE (accounttype = 'REF'
510
					  AND accountlines.borrowernumber = borrowers.borrowernumber
511
					                  AND date  >=?  AND date  <?)"
512
    );
513
514
    $sth->execute( $date, $date2 );
515
516
    my @results;
517
    while ( my $data = $sth->fetchrow_hashref ) {
518
		push @results,$data;
519
		
520
	}
521
    return (@results);
522
}
523
524
sub ReversePayment {
525
    my ( $accountlines_id ) = @_;
526
    my $dbh = C4::Context->dbh;
527
528
    my $sth = $dbh->prepare('SELECT * FROM accountlines WHERE accountlines_id = ?');
529
    $sth->execute( $accountlines_id );
530
    my $row = $sth->fetchrow_hashref();
531
    my $amount_outstanding = $row->{'amountoutstanding'};
532
533
    if ( $amount_outstanding <= 0 ) {
534
        $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = amount * -1, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
535
        $sth->execute( $accountlines_id );
536
    } else {
537
        $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = 0, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
538
        $sth->execute( $accountlines_id );
539
    }
540
541
    if ( C4::Context->preference("FinesLog") ) {
542
        my $manager_id = 0;
543
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
544
545
        if ( $amount_outstanding <= 0 ) {
546
            $row->{'amountoutstanding'} *= -1;
547
        } else {
548
            $row->{'amountoutstanding'} = '0';
549
        }
550
        $row->{'description'} .= ' Reversed -';
551
        logaction("FINES", 'MODIFY', $row->{'borrowernumber'}, Dumper({
552
            action                => 'reverse_fee_payment',
553
            borrowernumber        => $row->{'borrowernumber'},
554
            old_amountoutstanding => $row->{'amountoutstanding'},
555
            new_amountoutstanding => 0 - $amount_outstanding,,
556
            accountlines_id       => $row->{'accountlines_id'},
557
            accountno             => $row->{'accountno'},
558
            manager_id            => $manager_id,
559
        }));
560
561
    }
562
563
}
564
565
=head2 recordpayment_selectaccts
566
567
  recordpayment_selectaccts($borrowernumber, $payment,$accts);
568
569
Record payment by a patron. C<$borrowernumber> is the patron's
570
borrower number. C<$payment> is a floating-point number, giving the
571
amount that was paid. C<$accts> is an array ref to a list of
572
accountnos which the payment can be recorded against
573
574
Amounts owed are paid off oldest first. That is, if the patron has a
575
$1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
576
of $1.50, then the oldest fine will be paid off in full, and $0.50
577
will be credited to the next one.
578
579
=cut
580
581
sub recordpayment_selectaccts {
582
    my ( $borrowernumber, $amount, $accts, $note ) = @_;
583
584
    my $dbh        = C4::Context->dbh;
585
    my $newamtos   = 0;
586
    my $accdata    = q{};
587
    my $branch     = C4::Context->userenv->{branch};
588
    my $amountleft = $amount;
589
    my $manager_id = 0;
590
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
591
    my $sql = 'SELECT * FROM accountlines WHERE (borrowernumber = ?) ' .
592
    'AND (amountoutstanding<>0) ';
593
    if (@{$accts} ) {
594
        $sql .= ' AND accountno IN ( ' .  join ',', @{$accts};
595
        $sql .= ' ) ';
596
    }
597
    $sql .= ' ORDER BY date';
598
    # begin transaction
599
    my $nextaccntno = getnextacctno($borrowernumber);
600
601
    # get lines with outstanding amounts to offset
602
    my $rows = $dbh->selectall_arrayref($sql, { Slice => {} }, $borrowernumber);
603
604
    # offset transactions
605
    my $sth     = $dbh->prepare('UPDATE accountlines SET amountoutstanding= ? ' .
606
        'WHERE accountlines_id=?');
607
608
    my @ids;
609
    for my $accdata ( @{$rows} ) {
610
        if ($amountleft == 0) {
611
            last;
612
        }
613
        if ( $accdata->{amountoutstanding} < $amountleft ) {
614
            $newamtos = 0;
615
            $amountleft -= $accdata->{amountoutstanding};
616
        }
617
        else {
618
            $newamtos   = $accdata->{amountoutstanding} - $amountleft;
619
            $amountleft = 0;
620
        }
621
        my $thisacct = $accdata->{accountlines_id};
622
        $sth->execute( $newamtos, $thisacct );
623
624
        if ( C4::Context->preference("FinesLog") ) {
625
            logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
626
                action                => 'fee_payment',
627
                borrowernumber        => $borrowernumber,
628
                old_amountoutstanding => $accdata->{'amountoutstanding'},
629
                new_amountoutstanding => $newamtos,
630
                amount_paid           => $accdata->{'amountoutstanding'} - $newamtos,
631
                accountlines_id       => $accdata->{'accountlines_id'},
632
                accountno             => $accdata->{'accountno'},
633
                manager_id            => $manager_id,
634
            }));
635
            push( @ids, $accdata->{'accountlines_id'} );
636
        }
637
638
    }
639
640
    # create new line
641
    $sql = 'INSERT INTO accountlines ' .
642
    '(borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding,manager_id,note) ' .
643
    q|VALUES (?,?,now(),?,'','Pay',?,?,?)|;
644
    $dbh->do($sql,{},$borrowernumber, $nextaccntno, 0 - $amount, 0 - $amountleft, $manager_id, $note );
645
    UpdateStats( $branch, 'payment', $amount, '', '', '', $borrowernumber, $nextaccntno );
646
647
    if ( C4::Context->preference("FinesLog") ) {
648
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
649
            action            => 'create_payment',
650
            borrowernumber    => $borrowernumber,
651
            accountno         => $nextaccntno,
652
            amount            => 0 - $amount,
653
            amountoutstanding => 0 - $amountleft,
654
            accounttype       => 'Pay',
655
            accountlines_paid => \@ids,
656
            manager_id        => $manager_id,
657
        }));
658
    }
659
660
    return;
661
}
662
663
# makepayment needs to be fixed to handle partials till then this separate subroutine
664
# fills in
665
sub makepartialpayment {
666
    my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
667
    my $manager_id = 0;
668
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
669
    if (!$amount || $amount < 0) {
670
        return;
671
    }
672
    $payment_note //= "";
673
    my $dbh = C4::Context->dbh;
674
675
    my $nextaccntno = getnextacctno($borrowernumber);
676
    my $newamtos    = 0;
677
678
    my $data = $dbh->selectrow_hashref(
679
        'SELECT * FROM accountlines WHERE  accountlines_id=?',undef,$accountlines_id);
680
    my $new_outstanding = $data->{amountoutstanding} - $amount;
681
682
    my $update = 'UPDATE  accountlines SET amountoutstanding = ?  WHERE   accountlines_id = ? ';
683
    $dbh->do( $update, undef, $new_outstanding, $accountlines_id);
684
685
    if ( C4::Context->preference("FinesLog") ) {
686
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
687
            action                => 'fee_payment',
688
            borrowernumber        => $borrowernumber,
689
            old_amountoutstanding => $data->{'amountoutstanding'},
690
            new_amountoutstanding => $new_outstanding,
691
            amount_paid           => $data->{'amountoutstanding'} - $new_outstanding,
692
            accountlines_id       => $data->{'accountlines_id'},
693
            accountno             => $data->{'accountno'},
694
            manager_id            => $manager_id,
695
        }));
696
    }
697
698
    # create new line
699
    my $insert = 'INSERT INTO accountlines (borrowernumber, accountno, date, amount, '
700
    .  'description, accounttype, amountoutstanding, itemnumber, manager_id, note) '
701
    . ' VALUES (?, ?, now(), ?, ?, ?, 0, ?, ?, ?)';
702
703
    $dbh->do(  $insert, undef, $borrowernumber, $nextaccntno, $amount,
704
        "Payment, thanks - $user", 'Pay', $data->{'itemnumber'}, $manager_id, $payment_note);
705
706
    UpdateStats( $user, 'payment', $amount, '', '', '', $borrowernumber, $accountno );
707
708
    if ( C4::Context->preference("FinesLog") ) {
709
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
710
            action            => 'create_payment',
711
            borrowernumber    => $user,
712
            accountno         => $nextaccntno,
713
            amount            => 0 - $amount,
714
            accounttype       => 'Pay',
715
            itemnumber        => $data->{'itemnumber'},
716
            accountlines_paid => [ $data->{'accountlines_id'} ],
717
            manager_id        => $manager_id,
718
        }));
719
    }
720
721
    return;
722
}
723
724
=head2 WriteOffFee
725
726
  WriteOffFee( $borrowernumber, $accountline_id, $itemnum, $accounttype, $amount, $branch, $payment_note );
727
728
Write off a fine for a patron.
729
C<$borrowernumber> is the patron's borrower number.
730
C<$accountline_id> is the accountline_id of the fee to write off.
731
C<$itemnum> is the itemnumber of of item whose fine is being written off.
732
C<$accounttype> is the account type of the fine being written off.
733
C<$amount> is a floating-point number, giving the amount that is being written off.
734
C<$branch> is the branchcode of the library where the writeoff occurred.
735
C<$payment_note> is the note to attach to this payment
736
737
=cut
738
739
sub WriteOffFee {
740
    my ( $borrowernumber, $accountlines_id, $itemnum, $accounttype, $amount, $branch, $payment_note ) = @_;
741
    $payment_note //= "";
742
    $branch ||= C4::Context->userenv->{branch};
743
    my $manager_id = 0;
744
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
745
746
    # if no item is attached to fine, make sure to store it as a NULL
747
    $itemnum ||= undef;
748
749
    my ( $sth, $query );
750
    my $dbh = C4::Context->dbh();
751
752
    $query = "
753
        UPDATE accountlines SET amountoutstanding = 0
754
        WHERE accountlines_id = ? AND borrowernumber = ?
755
    ";
756
    $sth = $dbh->prepare( $query );
757
    $sth->execute( $accountlines_id, $borrowernumber );
758
759
    if ( C4::Context->preference("FinesLog") ) {
760
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
761
            action                => 'fee_writeoff',
762
            borrowernumber        => $borrowernumber,
763
            accountlines_id       => $accountlines_id,
764
            manager_id            => $manager_id,
765
        }));
766
    }
767
768
    $query ="
769
        INSERT INTO accountlines
770
        ( borrowernumber, accountno, itemnumber, date, amount, description, accounttype, manager_id, note )
771
        VALUES ( ?, ?, ?, NOW(), ?, 'Writeoff', 'W', ?, ? )
772
    ";
773
    $sth = $dbh->prepare( $query );
774
    my $acct = getnextacctno($borrowernumber);
775
    $sth->execute( $borrowernumber, $acct, $itemnum, $amount, $manager_id, $payment_note );
776
777
    if ( C4::Context->preference("FinesLog") ) {
778
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
779
            action            => 'create_writeoff',
780
            borrowernumber    => $borrowernumber,
781
            accountno         => $acct,
782
            amount            => 0 - $amount,
783
            accounttype       => 'W',
784
            itemnumber        => $itemnum,
785
            accountlines_paid => [ $accountlines_id ],
786
            manager_id        => $manager_id,
787
        }));
788
    }
789
790
    UpdateStats( $branch, 'writeoff', $amount, q{}, q{}, q{}, $borrowernumber );
791
792
}
793
794
END { }    # module clean-up code here (global destructor)
795
796
1;
797
__END__
798
799
=head1 SEE ALSO
800
801
DBI(3)
802
803
=cut
804
(-)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-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt (-111 lines)
Lines 1-111 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>
48
        [% SWITCH account.accounttype %]
49
          [% CASE 'Pay' %]Payment,thanks
50
          [% CASE 'N' %]New Card
51
          [% CASE 'F' %]Fine
52
          [% CASE 'A' %]Account management fee
53
          [% CASE 'M' %]Sundry
54
          [% CASE 'L' %]Lost Item
55
          [% CASE 'W' %]Writeoff
56
          [% CASE %][% account.accounttype %]
57
        [%- END -%]
58
        [%- IF account.description %], [% account.description %][% END %]
59
        &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>
60
      <td>[% account.note | html_line_break %]</td>
61
      [% IF ( account.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amount %]</td>
62
      [% IF ( account.amountoutstandingcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amountoutstanding %]</td>
63
    [% IF ( reverse_col ) %]
64
      <td>
65
	[% IF ( account.payment ) %]
66
		<a href="boraccount.pl?action=reverse&amp;accountlines_id=[% account.accountlines_id %]&amp;borrowernumber=[% account.borrowernumber %]">Reverse</a>
67
	[% ELSE %]
68
		&nbsp;
69
	[% END %]
70
      </td>
71
	[% END %]
72
<td>
73
	[% IF ( account.payment ) %]
74
		<a target="_blank" href="printfeercpt.pl?action=print&amp;accountlines_id=[% account.accountlines_id %]&amp;borrowernumber=[% account.borrowernumber %]">Print</a>
75
	[% ELSE %]
76
		<a target="_blank" href="printinvoice.pl?action=print&amp;accountlines_id=[% account.accountlines_id %]&amp;borrowernumber=[% account.borrowernumber %]">Print</a>
77
	[% END %]
78
      </td>
79
    </tr>
80
81
  [% END %]
82
<tfoot>
83
  <tr>
84
    <td colspan="4">Total due</td>
85
    [% IF ( totalcredit ) %]
86
      [% IF ( reverse_col ) %]
87
        <td colspan="3" class="credit">
88
      [% ELSE %]
89
        <td colspan="2" class="credit">
90
      [% END %]
91
    [% ELSE %]
92
      [% IF ( reverse_col ) %]
93
        <td colspan="3" class="debit">
94
      [% ELSE %]
95
        <td colspan="2" class="credit">
96
      [% END %]
97
    [% END %]
98
    [% total %]</td>
99
  </tr>
100
  </tfoot>
101
</table>
102
</div></div>
103
104
</div>
105
</div>
106
107
<div class="yui-b">
108
[% INCLUDE 'circ-menu.inc' %]
109
</div>
110
</div>
111
[% INCLUDE 'intranet-bottom.inc' %]
(-)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 (-168 lines)
Lines 1-168 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 msg = _("Are you sure you want to write off %s in outstanding fines? This cannot be undone!");
20
            msg = msg.replace( "%s", "[% total | format('%.2f') %]" );
21
            var answer = confirm(msg);
22
                if (!answer){
23
                    event.preventDefault();
24
                }
25
        });
26
        $('#CheckAll').click(function(){
27
            $("#finest").checkCheckboxes();
28
            enableCheckboxActions();
29
            return false;
30
        });
31
        $('#CheckNone').click(function(){
32
            $("#finest").unCheckCheckboxes();
33
            enableCheckboxActions();
34
            return false;
35
        });
36
        $(".cb").change(function(){
37
            enableCheckboxActions();
38
        });
39
        enableCheckboxActions();
40
    });
41
//]]>
42
</script>
43
</head>
44
<body id="pat_pay" class="pat">
45
[% INCLUDE 'header.inc' %]
46
[% INCLUDE 'patron-search.inc' %]
47
48
<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>
49
50
<div id="doc3" class="yui-t2">
51
   
52
   <div id="bd">
53
	<div id="yui-main">
54
	<div class="yui-b">
55
[% INCLUDE 'members-toolbar.inc' borrowernumber=borrower.borrowernumber %]
56
57
<!-- The manual invoice and credit buttons -->
58
<div class="statictabs">
59
<ul>
60
	<li><a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrower.borrowernumber %]">Account</a></li>
61
    <li class="active"><a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrower.borrowernumber %]" >Pay fines</a></li>
62
	<li><a href="/cgi-bin/koha/members/maninvoice.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual invoice</a></li>
63
	<li><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual credit</a></li>
64
</ul>
65
<div class="tabs-container">
66
67
[% IF ( accounts ) %]
68
    <form action="/cgi-bin/koha/members/pay.pl" method="post" id="pay-fines-form">
69
	<input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrower.borrowernumber %]" />
70
<p><span class="checkall"><a id="CheckAll" href="#">Select all</a></span> | <span class="clearall"><a id="CheckNone" href="#">Clear all</a></span></p>
71
<table id="finest">
72
<thead>
73
<tr>
74
    <th>&nbsp;</th>
75
    <th>Fines &amp; charges</th>
76
    <th>Description</th>
77
    <th>Payment note</th>
78
    <th>Account type</th>
79
    <th>Notify id</th>
80
    <th>Level</th>
81
    <th>Amount</th>
82
    <th>Amount outstanding</th>
83
</tr>
84
</thead>
85
<tfoot>
86
<tr>
87
    <td class="total" colspan="8">Total due:</td>
88
    <td>[% total | format('%.2f') %]</td>
89
</tr>
90
</tfoot>
91
<tbody>
92
[% FOREACH account_grp IN accounts %]
93
    [% FOREACH line IN account_grp.accountlines %]
94
<tr>
95
    <td>
96
    [% IF ( line.amountoutstanding > 0 ) %]
97
        <input class="cb" type="checkbox" checked="checked" name="incl_par_[% line.accountno %]" />
98
    [% END %]
99
    </td>
100
    <td>
101
    [% IF ( line.amountoutstanding > 0 ) %]
102
        <input type="submit" name="pay_indiv_[% line.accountno %]" value="Pay" />
103
        <input type="submit" name="wo_indiv_[% line.accountno %]" value="Write off" />
104
    [% END %]
105
    <input type="hidden" name="itemnumber[% line.accountno %]" value="[% line.itemnumber %]" />
106
    <input type="hidden" name="description[% line.accountno %]" value="[% line.description %]" />
107
    <input type="hidden" name="accounttype[% line.accountno %]" value="[% line.accounttype %]" />
108
    <input type="hidden" name="amount[% line.accountno %]" value="[% line.amount %]" />
109
    <input type="hidden" name="accountlines_id[% line.accountno %]" value="[% line.accountlines_id %]" />
110
    <input type="hidden" name="amountoutstanding[% line.accountno %]" value="[% line.amountoutstanding %]" />
111
    <input type="hidden" name="borrowernumber[% line.accountno %]" value="[% line.borrowernumber %]" />
112
    <input type="hidden" name="accountno[% line.accountno %]" value="[% line.accountno %]" />
113
    <input type="hidden" name="notify_id[% line.accountno %]" value="[% line.notify_id %]" />
114
    <input type="hidden" name="notify_level[% line.accountno %]" value="[% line.notify_level %]" />
115
    <input type="hidden" name="totals[% line.accountno %]" value="[% line.totals %]" />
116
    </td>
117
    <td>
118
        [% SWITCH line.accounttype %]
119
          [% CASE 'Pay' %]Payment,thanks
120
          [% CASE 'N' %]New Card
121
          [% CASE 'F' %]Fine
122
          [% CASE 'A' %]Account management fee
123
          [% CASE 'M' %]Sundry
124
          [% CASE 'L' %]Lost Item
125
          [% CASE 'W' %]Writeoff
126
          [% CASE %][% line.accounttype %]
127
        [%- END -%]
128
        [%- IF line.description %], [% line.description %][% END %]
129
        [% IF line.title %]([% line.title |html_entity %])[% END %]
130
    </td>
131
    <td><input type="text" name="payment_note_[% line.accountno %]" /></td>
132
    <td>[% line.accounttype %]</td>
133
    <td>[% line.notify_id %]</td>
134
    <td>[% line.notify_level %]</td>
135
    <td class="debit">[% line.amount | format('%.2f') %]</td>
136
    <td class="debit">[% line.amountoutstanding | format('%.2f') %]</td>
137
</tr>
138
[% END %]
139
[% IF ( account_grp.total ) %]
140
<tr>
141
142
    <td class="total" colspan="8">Sub total:</td>
143
    <td>[% account_grp.total | format('%.2f') %]</td>
144
</tr>
145
[% END %]
146
[% END %]
147
</tbody>
148
</table>
149
<fieldset class="action">
150
<input type="submit" id="paycollect" name="paycollect"  value="Pay amount" class="submit" />
151
<input type="submit" name="woall"  id="woall" value="Write off all" class="submit" />
152
<input type="submit" id="payselected" name="payselected"  value="Pay selected" class="submit" />
153
<a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrower.borrowernumber %]">Cancel</a>
154
</fieldset>
155
</form>
156
[% ELSE %]
157
    <p>[% borrower.firstname %] [% borrower.surname %] has no outstanding fines.</p>
158
[% END %]
159
</div></div>
160
161
</div>
162
</div>
163
164
<div class="yui-b">
165
[% INCLUDE 'circ-menu.tt' %]
166
</div>
167
</div>
168
[% 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/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/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/maintenance/fix_accountlines_date.pl (-172 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();
172
- 

Return to bug 6427