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

(-)a/C4/Accounts.pm (-834 lines)
Lines 1-834 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, $sip_paytype);
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. C<$sip_paytype> is an optional flag to indicate this
78
payment was made over a SIP2 interface, rather than the staff client. The
79
value passed is the SIP2 payment type value (message 37, characters 21-22)
80
81
Amounts owed are paid off oldest first. That is, if the patron has a
82
$1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
83
of $1.50, then the oldest fine will be paid off in full, and $0.50
84
will be credited to the next one.
85
86
=cut
87
88
#'
89
sub recordpayment {
90
91
    #here we update the account lines
92
    my ( $borrowernumber, $data, $sip_paytype ) = @_;
93
    my $dbh        = C4::Context->dbh;
94
    my $newamtos   = 0;
95
    my $accdata    = "";
96
    my $branch     = C4::Context->userenv->{'branch'};
97
    my $amountleft = $data;
98
    my $manager_id = 0;
99
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
100
101
    # begin transaction
102
    my $nextaccntno = getnextacctno($borrowernumber);
103
104
    # get lines with outstanding amounts to offset
105
    my $sth = $dbh->prepare(
106
        "SELECT * FROM accountlines
107
  WHERE (borrowernumber = ?) AND (amountoutstanding<>0)
108
  ORDER BY date"
109
    );
110
    $sth->execute($borrowernumber);
111
112
    # offset transactions
113
    my @ids;
114
    while ( ( $accdata = $sth->fetchrow_hashref ) and ( $amountleft > 0 ) ) {
115
        if ( $accdata->{'amountoutstanding'} < $amountleft ) {
116
            $newamtos = 0;
117
            $amountleft -= $accdata->{'amountoutstanding'};
118
        }
119
        else {
120
            $newamtos   = $accdata->{'amountoutstanding'} - $amountleft;
121
            $amountleft = 0;
122
        }
123
        my $thisacct = $accdata->{accountlines_id};
124
        my $usth     = $dbh->prepare(
125
            "UPDATE accountlines SET amountoutstanding= ?
126
     WHERE (accountlines_id = ?)"
127
        );
128
        $usth->execute( $newamtos, $thisacct );
129
130
        if ( C4::Context->preference("FinesLog") ) {
131
            $accdata->{'amountoutstanding_new'} = $newamtos;
132
            logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
133
                action                => 'fee_payment',
134
                borrowernumber        => $accdata->{'borrowernumber'},
135
                old_amountoutstanding => $accdata->{'amountoutstanding'},
136
                new_amountoutstanding => $newamtos,
137
                amount_paid           => $accdata->{'amountoutstanding'} - $newamtos,
138
                accountlines_id       => $accdata->{'accountlines_id'},
139
                accountno             => $accdata->{'accountno'},
140
                manager_id            => $manager_id,
141
            }));
142
            push( @ids, $accdata->{'accountlines_id'} );
143
        }
144
    }
145
146
    # create new line
147
    my $usth = $dbh->prepare(
148
        "INSERT INTO accountlines
149
  (borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding,manager_id)
150
  VALUES (?,?,now(),?,'',?,?,?)"
151
    );
152
153
    my $paytype = "Pay";
154
    $paytype .= $sip_paytype if defined $sip_paytype;
155
    $usth->execute( $borrowernumber, $nextaccntno, 0 - $data, $paytype, 0 - $amountleft, $manager_id );
156
    $usth->finish;
157
158
    UpdateStats({
159
                branch => $branch,
160
                type =>'payment',
161
                amount => $data,
162
                borrowernumber => $borrowernumber,
163
                accountno => $nextaccntno }
164
    );
165
166
    if ( C4::Context->preference("FinesLog") ) {
167
        $accdata->{'amountoutstanding_new'} = $newamtos;
168
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
169
            action            => 'create_payment',
170
            borrowernumber    => $borrowernumber,
171
            accountno         => $nextaccntno,
172
            amount            => $data * -1,
173
            amountoutstanding => $amountleft * -1,
174
            accounttype       => 'Pay',
175
            accountlines_paid => \@ids,
176
            manager_id        => $manager_id,
177
        }));
178
    }
179
180
}
181
182
=head2 makepayment
183
184
  &makepayment($accountlines_id, $borrowernumber, $acctnumber, $amount, $branchcode);
185
186
Records the fact that a patron has paid off the entire amount he or
187
she owes.
188
189
C<$borrowernumber> is the patron's borrower number. C<$acctnumber> is
190
the account that was credited. C<$amount> is the amount paid (this is
191
only used to record the payment. It is assumed to be equal to the
192
amount owed). C<$branchcode> is the code of the branch where payment
193
was made.
194
195
=cut
196
197
#'
198
# FIXME - I'm not at all sure about the above, because I don't
199
# understand what the acct* tables in the Koha database are for.
200
sub makepayment {
201
202
    #here we update both the accountoffsets and the account lines
203
    #updated to check, if they are paying off a lost item, we return the item
204
    # from their card, and put a note on the item record
205
    my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
206
    my $dbh = C4::Context->dbh;
207
    my $manager_id = 0;
208
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; 
209
210
    # begin transaction
211
    my $nextaccntno = getnextacctno($borrowernumber);
212
    my $newamtos    = 0;
213
    my $sth         = $dbh->prepare("SELECT * FROM accountlines WHERE accountlines_id=?");
214
    $sth->execute( $accountlines_id );
215
    my $data = $sth->fetchrow_hashref;
216
217
    my $payment;
218
    if ( $data->{'accounttype'} eq "Pay" ){
219
        my $udp = 		
220
            $dbh->prepare(
221
                "UPDATE accountlines
222
                    SET amountoutstanding = 0
223
                    WHERE accountlines_id = ?
224
                "
225
            );
226
        $udp->execute($accountlines_id);
227
    }else{
228
        my $udp = 		
229
            $dbh->prepare(
230
                "UPDATE accountlines
231
                    SET amountoutstanding = 0
232
                    WHERE accountlines_id = ?
233
                "
234
            );
235
        $udp->execute($accountlines_id);
236
237
         # create new line
238
        my $payment = 0 - $amount;
239
        $payment_note //= "";
240
        
241
        my $ins = 
242
            $dbh->prepare( 
243
                "INSERT 
244
                    INTO accountlines (borrowernumber, accountno, date, amount, itemnumber, description, accounttype, amountoutstanding, manager_id, note)
245
                    VALUES ( ?, ?, now(), ?, ?, '', 'Pay', 0, ?, ?)"
246
            );
247
        $ins->execute($borrowernumber, $nextaccntno, $payment, $data->{'itemnumber'}, $manager_id, $payment_note);
248
    }
249
250
    if ( C4::Context->preference("FinesLog") ) {
251
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
252
            action                => 'fee_payment',
253
            borrowernumber        => $borrowernumber,
254
            old_amountoutstanding => $data->{'amountoutstanding'},
255
            new_amountoutstanding => 0,
256
            amount_paid           => $data->{'amountoutstanding'},
257
            accountlines_id       => $data->{'accountlines_id'},
258
            accountno             => $data->{'accountno'},
259
            manager_id            => $manager_id,
260
        }));
261
262
263
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
264
            action            => 'create_payment',
265
            borrowernumber    => $borrowernumber,
266
            accountno         => $nextaccntno,
267
            amount            => $payment,
268
            amountoutstanding => 0,,
269
            accounttype       => 'Pay',
270
            accountlines_paid => [$data->{'accountlines_id'}],
271
            manager_id        => $manager_id,
272
        }));
273
    }
274
275
    UpdateStats({
276
                branch => $user,
277
                type => 'payment',
278
                amount => $amount,
279
                borrowernumber => $borrowernumber,
280
                accountno => $accountno}
281
    );
282
283
    #check to see what accounttype
284
    if ( $data->{'accounttype'} eq 'Rep' || $data->{'accounttype'} eq 'L' ) {
285
        C4::Circulation::ReturnLostItem( $borrowernumber, $data->{'itemnumber'} );
286
    }
287
    my $sthr = $dbh->prepare("SELECT max(accountlines_id) AS lastinsertid FROM accountlines");
288
    $sthr->execute();
289
    my $datalastinsertid = $sthr->fetchrow_hashref;
290
    return $datalastinsertid->{'lastinsertid'};
291
}
292
293
=head2 getnextacctno
294
295
  $nextacct = &getnextacctno($borrowernumber);
296
297
Returns the next unused account number for the patron with the given
298
borrower number.
299
300
=cut
301
302
#'
303
# FIXME - Okay, so what does the above actually _mean_?
304
sub getnextacctno {
305
    my ($borrowernumber) = shift or return;
306
    my $sth = C4::Context->dbh->prepare(
307
        "SELECT accountno+1 FROM accountlines
308
            WHERE    (borrowernumber = ?)
309
            ORDER BY accountno DESC
310
            LIMIT 1"
311
    );
312
    $sth->execute($borrowernumber);
313
    return ($sth->fetchrow || 1);
314
}
315
316
=head2 fixaccounts (removed)
317
318
  &fixaccounts($accountlines_id, $borrowernumber, $accountnumber, $amount);
319
320
#'
321
# FIXME - I don't understand what this function does.
322
sub fixaccounts {
323
    my ( $accountlines_id, $borrowernumber, $accountno, $amount ) = @_;
324
    my $dbh = C4::Context->dbh;
325
    my $sth = $dbh->prepare(
326
        "SELECT * FROM accountlines WHERE accountlines_id=?"
327
    );
328
    $sth->execute( $accountlines_id );
329
    my $data = $sth->fetchrow_hashref;
330
331
    # FIXME - Error-checking
332
    my $diff        = $amount - $data->{'amount'};
333
    my $outstanding = $data->{'amountoutstanding'} + $diff;
334
    $sth->finish;
335
336
    $dbh->do(<<EOT);
337
        UPDATE  accountlines
338
        SET     amount = '$amount',
339
                amountoutstanding = '$outstanding'
340
        WHERE   accountlines_id = $accountlines_id
341
EOT
342
	# FIXME: exceedingly bad form.  Use prepare with placholders ("?") in query and execute args.
343
}
344
345
=cut
346
347
sub chargelostitem{
348
# lost ==1 Lost, lost==2 longoverdue, lost==3 lost and paid for
349
# FIXME: itemlost should be set to 3 after payment is made, should be a warning to the interface that
350
# a charge has been added
351
# FIXME : if no replacement price, borrower just doesn't get charged?
352
    my $dbh = C4::Context->dbh();
353
    my ($borrowernumber, $itemnumber, $amount, $description) = @_;
354
355
    # first make sure the borrower hasn't already been charged for this item
356
    my $sth1=$dbh->prepare("SELECT * from accountlines
357
    WHERE borrowernumber=? AND itemnumber=? and accounttype='L'");
358
    $sth1->execute($borrowernumber,$itemnumber);
359
    my $existing_charge_hashref=$sth1->fetchrow_hashref();
360
361
    # OK, they haven't
362
    unless ($existing_charge_hashref) {
363
        my $manager_id = 0;
364
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
365
        # This item is on issue ... add replacement cost to the borrower's record and mark it returned
366
        #  Note that we add this to the account even if there's no replacement price, allowing some other
367
        #  process (or person) to update it, since we don't handle any defaults for replacement prices.
368
        my $accountno = getnextacctno($borrowernumber);
369
        my $sth2=$dbh->prepare("INSERT INTO accountlines
370
        (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding,itemnumber,manager_id)
371
        VALUES (?,?,now(),?,?,'L',?,?,?)");
372
        $sth2->execute($borrowernumber,$accountno,$amount,
373
        $description,$amount,$itemnumber,$manager_id);
374
375
        if ( C4::Context->preference("FinesLog") ) {
376
            logaction("FINES", 'CREATE', $borrowernumber, Dumper({
377
                action            => 'create_fee',
378
                borrowernumber    => $borrowernumber,
379
                accountno         => $accountno,
380
                amount            => $amount,
381
                amountoutstanding => $amount,
382
                description       => $description,
383
                accounttype       => 'L',
384
                itemnumber        => $itemnumber,
385
                manager_id        => $manager_id,
386
            }));
387
        }
388
389
    }
390
}
391
392
=head2 manualinvoice
393
394
  &manualinvoice($borrowernumber, $itemnumber, $description, $type,
395
                 $amount, $note);
396
397
C<$borrowernumber> is the patron's borrower number.
398
C<$description> is a description of the transaction.
399
C<$type> may be one of C<CS>, C<CB>, C<CW>, C<CF>, C<CL>, C<N>, C<L>,
400
or C<REF>.
401
C<$itemnumber> is the item involved, if pertinent; otherwise, it
402
should be the empty string.
403
404
=cut
405
406
#'
407
# FIXME: In Koha 3.0 , the only account adjustment 'types' passed to this function
408
# are :  
409
# 		'C' = CREDIT
410
# 		'FOR' = FORGIVEN  (Formerly 'F', but 'F' is taken to mean 'FINE' elsewhere)
411
# 		'N' = New Card fee
412
# 		'F' = Fine
413
# 		'A' = Account Management fee
414
# 		'M' = Sundry
415
# 		'L' = Lost Item
416
#
417
418
sub manualinvoice {
419
    my ( $borrowernumber, $itemnum, $desc, $type, $amount, $note ) = @_;
420
    my $manager_id = 0;
421
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
422
    my $dbh      = C4::Context->dbh;
423
    my $notifyid = 0;
424
    my $insert;
425
    my $accountno  = getnextacctno($borrowernumber);
426
    my $amountleft = $amount;
427
428
    if (   ( $type eq 'L' )
429
        or ( $type eq 'F' )
430
        or ( $type eq 'A' )
431
        or ( $type eq 'N' )
432
        or ( $type eq 'M' ) )
433
    {
434
        $notifyid = 1;
435
    }
436
437
    if ( $itemnum ) {
438
        $desc .= ' ' . $itemnum;
439
        my $sth = $dbh->prepare(
440
            'INSERT INTO  accountlines
441
                        (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber,notify_id, note, manager_id)
442
        VALUES (?, ?, now(), ?,?, ?,?,?,?,?,?)');
443
     $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $itemnum,$notifyid, $note, $manager_id) || return $sth->errstr;
444
  } else {
445
    my $sth=$dbh->prepare("INSERT INTO  accountlines
446
            (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding,notify_id, note, manager_id)
447
            VALUES (?, ?, now(), ?, ?, ?, ?,?,?,?)"
448
        );
449
        $sth->execute( $borrowernumber, $accountno, $amount, $desc, $type,
450
            $amountleft, $notifyid, $note, $manager_id );
451
    }
452
453
    if ( C4::Context->preference("FinesLog") ) {
454
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
455
            action            => 'create_fee',
456
            borrowernumber    => $borrowernumber,
457
            accountno         => $accountno,
458
            amount            => $amount,
459
            description       => $desc,
460
            accounttype       => $type,
461
            amountoutstanding => $amountleft,
462
            notify_id         => $notifyid,
463
            note              => $note,
464
            itemnumber        => $itemnum,
465
            manager_id        => $manager_id,
466
        }));
467
    }
468
469
    return 0;
470
}
471
472
sub getcharges {
473
	my ( $borrowerno, $timestamp, $accountno ) = @_;
474
	my $dbh        = C4::Context->dbh;
475
	my $timestamp2 = $timestamp - 1;
476
	my $query      = "";
477
	my $sth = $dbh->prepare(
478
			"SELECT * FROM accountlines WHERE borrowernumber=? AND accountno = ?"
479
          );
480
	$sth->execute( $borrowerno, $accountno );
481
	
482
    my @results;
483
    while ( my $data = $sth->fetchrow_hashref ) {
484
		push @results,$data;
485
	}
486
    return (@results);
487
}
488
489
sub ModNote {
490
    my ( $accountlines_id, $note ) = @_;
491
    my $dbh = C4::Context->dbh;
492
    my $sth = $dbh->prepare('UPDATE accountlines SET note = ? WHERE accountlines_id = ?');
493
    $sth->execute( $note, $accountlines_id );
494
}
495
496
sub getcredits {
497
	my ( $date, $date2 ) = @_;
498
	my $dbh = C4::Context->dbh;
499
	my $sth = $dbh->prepare(
500
			        "SELECT * FROM accountlines,borrowers
501
      WHERE amount < 0 AND accounttype not like 'Pay%' AND accountlines.borrowernumber = borrowers.borrowernumber
502
	  AND timestamp >=TIMESTAMP(?) AND timestamp < TIMESTAMP(?)"
503
      );  
504
505
    $sth->execute( $date, $date2 );                                                                                                              
506
    my @results;          
507
    while ( my $data = $sth->fetchrow_hashref ) {
508
		$data->{'date'} = $data->{'timestamp'};
509
		push @results,$data;
510
	}
511
    return (@results);
512
} 
513
514
515
sub getrefunds {
516
	my ( $date, $date2 ) = @_;
517
	my $dbh = C4::Context->dbh;
518
	
519
	my $sth = $dbh->prepare(
520
			        "SELECT *,timestamp AS datetime                                                                                      
521
                  FROM accountlines,borrowers
522
                  WHERE (accounttype = 'REF'
523
					  AND accountlines.borrowernumber = borrowers.borrowernumber
524
					                  AND date  >=?  AND date  <?)"
525
    );
526
527
    $sth->execute( $date, $date2 );
528
529
    my @results;
530
    while ( my $data = $sth->fetchrow_hashref ) {
531
		push @results,$data;
532
		
533
	}
534
    return (@results);
535
}
536
537
sub ReversePayment {
538
    my ( $accountlines_id ) = @_;
539
    my $dbh = C4::Context->dbh;
540
541
    my $sth = $dbh->prepare('SELECT * FROM accountlines WHERE accountlines_id = ?');
542
    $sth->execute( $accountlines_id );
543
    my $row = $sth->fetchrow_hashref();
544
    my $amount_outstanding = $row->{'amountoutstanding'};
545
546
    if ( $amount_outstanding <= 0 ) {
547
        $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = amount * -1, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
548
        $sth->execute( $accountlines_id );
549
    } else {
550
        $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = 0, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
551
        $sth->execute( $accountlines_id );
552
    }
553
554
    if ( C4::Context->preference("FinesLog") ) {
555
        my $manager_id = 0;
556
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
557
558
        if ( $amount_outstanding <= 0 ) {
559
            $row->{'amountoutstanding'} *= -1;
560
        } else {
561
            $row->{'amountoutstanding'} = '0';
562
        }
563
        $row->{'description'} .= ' Reversed -';
564
        logaction("FINES", 'MODIFY', $row->{'borrowernumber'}, Dumper({
565
            action                => 'reverse_fee_payment',
566
            borrowernumber        => $row->{'borrowernumber'},
567
            old_amountoutstanding => $row->{'amountoutstanding'},
568
            new_amountoutstanding => 0 - $amount_outstanding,,
569
            accountlines_id       => $row->{'accountlines_id'},
570
            accountno             => $row->{'accountno'},
571
            manager_id            => $manager_id,
572
        }));
573
574
    }
575
576
}
577
578
=head2 recordpayment_selectaccts
579
580
  recordpayment_selectaccts($borrowernumber, $payment,$accts);
581
582
Record payment by a patron. C<$borrowernumber> is the patron's
583
borrower number. C<$payment> is a floating-point number, giving the
584
amount that was paid. C<$accts> is an array ref to a list of
585
accountnos which the payment can be recorded against
586
587
Amounts owed are paid off oldest first. That is, if the patron has a
588
$1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
589
of $1.50, then the oldest fine will be paid off in full, and $0.50
590
will be credited to the next one.
591
592
=cut
593
594
sub recordpayment_selectaccts {
595
    my ( $borrowernumber, $amount, $accts, $note ) = @_;
596
597
    my $dbh        = C4::Context->dbh;
598
    my $newamtos   = 0;
599
    my $accdata    = q{};
600
    my $branch     = C4::Context->userenv->{branch};
601
    my $amountleft = $amount;
602
    my $manager_id = 0;
603
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
604
    my $sql = 'SELECT * FROM accountlines WHERE (borrowernumber = ?) ' .
605
    'AND (amountoutstanding<>0) ';
606
    if (@{$accts} ) {
607
        $sql .= ' AND accountno IN ( ' .  join ',', @{$accts};
608
        $sql .= ' ) ';
609
    }
610
    $sql .= ' ORDER BY date';
611
    # begin transaction
612
    my $nextaccntno = getnextacctno($borrowernumber);
613
614
    # get lines with outstanding amounts to offset
615
    my $rows = $dbh->selectall_arrayref($sql, { Slice => {} }, $borrowernumber);
616
617
    # offset transactions
618
    my $sth     = $dbh->prepare('UPDATE accountlines SET amountoutstanding= ? ' .
619
        'WHERE accountlines_id=?');
620
621
    my @ids;
622
    for my $accdata ( @{$rows} ) {
623
        if ($amountleft == 0) {
624
            last;
625
        }
626
        if ( $accdata->{amountoutstanding} < $amountleft ) {
627
            $newamtos = 0;
628
            $amountleft -= $accdata->{amountoutstanding};
629
        }
630
        else {
631
            $newamtos   = $accdata->{amountoutstanding} - $amountleft;
632
            $amountleft = 0;
633
        }
634
        my $thisacct = $accdata->{accountlines_id};
635
        $sth->execute( $newamtos, $thisacct );
636
637
        if ( C4::Context->preference("FinesLog") ) {
638
            logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
639
                action                => 'fee_payment',
640
                borrowernumber        => $borrowernumber,
641
                old_amountoutstanding => $accdata->{'amountoutstanding'},
642
                new_amountoutstanding => $newamtos,
643
                amount_paid           => $accdata->{'amountoutstanding'} - $newamtos,
644
                accountlines_id       => $accdata->{'accountlines_id'},
645
                accountno             => $accdata->{'accountno'},
646
                manager_id            => $manager_id,
647
            }));
648
            push( @ids, $accdata->{'accountlines_id'} );
649
        }
650
651
    }
652
653
    # create new line
654
    $sql = 'INSERT INTO accountlines ' .
655
    '(borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding,manager_id,note) ' .
656
    q|VALUES (?,?,now(),?,'','Pay',?,?,?)|;
657
    $dbh->do($sql,{},$borrowernumber, $nextaccntno, 0 - $amount, 0 - $amountleft, $manager_id, $note );
658
    UpdateStats({
659
                branch => $branch,
660
                type => 'payment',
661
                amount => $amount,
662
                borrowernumber => $borrowernumber,
663
                accountno => $nextaccntno}
664
    );
665
666
    if ( C4::Context->preference("FinesLog") ) {
667
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
668
            action            => 'create_payment',
669
            borrowernumber    => $borrowernumber,
670
            accountno         => $nextaccntno,
671
            amount            => 0 - $amount,
672
            amountoutstanding => 0 - $amountleft,
673
            accounttype       => 'Pay',
674
            accountlines_paid => \@ids,
675
            manager_id        => $manager_id,
676
        }));
677
    }
678
679
    return;
680
}
681
682
# makepayment needs to be fixed to handle partials till then this separate subroutine
683
# fills in
684
sub makepartialpayment {
685
    my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
686
    my $manager_id = 0;
687
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
688
    if (!$amount || $amount < 0) {
689
        return;
690
    }
691
    $payment_note //= "";
692
    my $dbh = C4::Context->dbh;
693
694
    my $nextaccntno = getnextacctno($borrowernumber);
695
    my $newamtos    = 0;
696
697
    my $data = $dbh->selectrow_hashref(
698
        'SELECT * FROM accountlines WHERE  accountlines_id=?',undef,$accountlines_id);
699
    my $new_outstanding = $data->{amountoutstanding} - $amount;
700
701
    my $update = 'UPDATE  accountlines SET amountoutstanding = ?  WHERE   accountlines_id = ? ';
702
    $dbh->do( $update, undef, $new_outstanding, $accountlines_id);
703
704
    if ( C4::Context->preference("FinesLog") ) {
705
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
706
            action                => 'fee_payment',
707
            borrowernumber        => $borrowernumber,
708
            old_amountoutstanding => $data->{'amountoutstanding'},
709
            new_amountoutstanding => $new_outstanding,
710
            amount_paid           => $data->{'amountoutstanding'} - $new_outstanding,
711
            accountlines_id       => $data->{'accountlines_id'},
712
            accountno             => $data->{'accountno'},
713
            manager_id            => $manager_id,
714
        }));
715
    }
716
717
    # create new line
718
    my $insert = 'INSERT INTO accountlines (borrowernumber, accountno, date, amount, '
719
    .  'description, accounttype, amountoutstanding, itemnumber, manager_id, note) '
720
    . ' VALUES (?, ?, now(), ?, ?, ?, 0, ?, ?, ?)';
721
722
    $dbh->do(  $insert, undef, $borrowernumber, $nextaccntno, $amount,
723
        "Payment, thanks - $user", 'Pay', $data->{'itemnumber'}, $manager_id, $payment_note);
724
725
    UpdateStats({
726
                branch => $user,
727
                type => 'payment',
728
                amount => $amount,
729
                borrowernumber => $borrowernumber,
730
                accountno => $accountno}
731
    );
732
733
    if ( C4::Context->preference("FinesLog") ) {
734
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
735
            action            => 'create_payment',
736
            borrowernumber    => $user,
737
            accountno         => $nextaccntno,
738
            amount            => 0 - $amount,
739
            accounttype       => 'Pay',
740
            itemnumber        => $data->{'itemnumber'},
741
            accountlines_paid => [ $data->{'accountlines_id'} ],
742
            manager_id        => $manager_id,
743
        }));
744
    }
745
746
    return;
747
}
748
749
=head2 WriteOffFee
750
751
  WriteOffFee( $borrowernumber, $accountline_id, $itemnum, $accounttype, $amount, $branch, $payment_note );
752
753
Write off a fine for a patron.
754
C<$borrowernumber> is the patron's borrower number.
755
C<$accountline_id> is the accountline_id of the fee to write off.
756
C<$itemnum> is the itemnumber of of item whose fine is being written off.
757
C<$accounttype> is the account type of the fine being written off.
758
C<$amount> is a floating-point number, giving the amount that is being written off.
759
C<$branch> is the branchcode of the library where the writeoff occurred.
760
C<$payment_note> is the note to attach to this payment
761
762
=cut
763
764
sub WriteOffFee {
765
    my ( $borrowernumber, $accountlines_id, $itemnum, $accounttype, $amount, $branch, $payment_note ) = @_;
766
    $payment_note //= "";
767
    $branch ||= C4::Context->userenv->{branch};
768
    my $manager_id = 0;
769
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
770
771
    # if no item is attached to fine, make sure to store it as a NULL
772
    $itemnum ||= undef;
773
774
    my ( $sth, $query );
775
    my $dbh = C4::Context->dbh();
776
777
    $query = "
778
        UPDATE accountlines SET amountoutstanding = 0
779
        WHERE accountlines_id = ? AND borrowernumber = ?
780
    ";
781
    $sth = $dbh->prepare( $query );
782
    $sth->execute( $accountlines_id, $borrowernumber );
783
784
    if ( C4::Context->preference("FinesLog") ) {
785
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
786
            action                => 'fee_writeoff',
787
            borrowernumber        => $borrowernumber,
788
            accountlines_id       => $accountlines_id,
789
            manager_id            => $manager_id,
790
        }));
791
    }
792
793
    $query ="
794
        INSERT INTO accountlines
795
        ( borrowernumber, accountno, itemnumber, date, amount, description, accounttype, manager_id, note )
796
        VALUES ( ?, ?, ?, NOW(), ?, 'Writeoff', 'W', ?, ? )
797
    ";
798
    $sth = $dbh->prepare( $query );
799
    my $acct = getnextacctno($borrowernumber);
800
    $sth->execute( $borrowernumber, $acct, $itemnum, $amount, $manager_id, $payment_note );
801
802
    if ( C4::Context->preference("FinesLog") ) {
803
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
804
            action            => 'create_writeoff',
805
            borrowernumber    => $borrowernumber,
806
            accountno         => $acct,
807
            amount            => 0 - $amount,
808
            accounttype       => 'W',
809
            itemnumber        => $itemnum,
810
            accountlines_paid => [ $accountlines_id ],
811
            manager_id        => $manager_id,
812
        }));
813
    }
814
815
    UpdateStats({
816
                branch => $branch,
817
                type => 'writeoff',
818
                amount => $amount,
819
                borrowernumber => $borrowernumber}
820
    );
821
822
}
823
824
END { }    # module clean-up code here (global destructor)
825
826
1;
827
__END__
828
829
=head1 SEE ALSO
830
831
DBI(3)
832
833
=cut
834
(-)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     => "SET NULL",
212
    on_update     => "SET NULL",
213
  },
214
);
215
216
217
# Created by DBIx::Class::Schema::Loader v0.07039 @ 2014-07-11 09:26:55
218
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:jUiCeLLPg5228rNEBW0w2g
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/circ/stats.pl (-189 lines)
Lines 1-189 Link Here
1
#!/usr/bin/perl
2
3
4
#written 14/1/2000
5
#script to display reports
6
7
# Copyright 2000-2002 Katipo Communications
8
#
9
# This file is part of Koha.
10
#
11
# Koha is free software; you can redistribute it and/or modify it under the
12
# terms of the GNU General Public License as published by the Free Software
13
# Foundation; either version 2 of the License, or (at your option) any later
14
# version.
15
#
16
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License along
21
# with Koha; if not, write to the Free Software Foundation, Inc.,
22
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
24
use strict;
25
#use warnings; FIXME - Bug 2505
26
use CGI;
27
use C4::Context;
28
use C4::Output;
29
use C4::Auth;
30
use Date::Manip;
31
use C4::Stats;
32
use C4::Debug;
33
34
use vars qw($debug);
35
36
my $input = new CGI;
37
my $time  = $input->param('time') || '';
38
39
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
40
    {
41
        template_name   => "circ/stats.tt",
42
        query           => $input,
43
        type            => "intranet",
44
        authnotrequired => 0,
45
        flagsrequired   => { reports => 1 },
46
        debug           => 1,
47
    }
48
);
49
50
my $date;
51
my $date2;
52
if ( $time eq 'yesterday' ) {
53
    $date  = ParseDate('yesterday');
54
    $date2 = ParseDate('today');
55
}
56
elsif ( $time eq 'today' ) {
57
    $date  = ParseDate('today');
58
    $date2 = ParseDate('tomorrow');
59
}
60
elsif ( $time eq 'daybefore' ) {
61
    $date  = ParseDate('2 days ago');
62
    $date2 = ParseDate('yesterday');
63
}
64
elsif ( $time eq 'month' ) {
65
    $date  = ParseDate('1 month ago');
66
    $date2 = ParseDate('today');
67
}
68
elsif ( $time =~ /\// ) {
69
    $date  = ParseDate($time);
70
    $date2 = ParseDateDelta('+ 1 day');
71
    $date2 = DateCalc( $date, $date2 );
72
} else {
73
    $template->param(notime => '1');    # TODO: add error feedback if time sent, but unrecognized
74
    output_html_with_http_headers $input, $cookie, $template->output;
75
    exit;
76
}
77
78
$debug and warn "d : $date // d2 : $date2";
79
$date  = UnixDate( $date,  '%Y-%m-%d' );
80
$date2 = UnixDate( $date2, '%Y-%m-%d' );
81
$debug and warn "d : $date // d2 : $date2";
82
my @payments = TotalPaid( $date, $date2 );
83
my $count    = @payments;
84
my $total    = 0;
85
my $totalw   = 0;
86
my $oldtime;
87
my @loop;
88
my %row;
89
my $i = 0;
90
91
while ( $i < $count ) {
92
    $debug and warn " pay : " . $payments[$i]{'timestamp'};
93
    my $time     = $payments[$i]{'datetime'};
94
    my $payments = $payments[$i]{'value'};
95
    my $charge   = 0;
96
    my @temp     = split(/ /, $payments[$i]{'datetime'});
97
    my $date     = $temp[0];
98
    my @charges  =
99
      getcharges( $payments[$i]{'borrowernumber'}, $payments[$i]{'timestamp'} );
100
    my $count        = @charges;
101
    my $temptotalf   = 0;
102
    my $temptotalr   = 0;
103
    my $temptotalres = 0;
104
    my $temptotalren = 0;
105
    my $temptotalw   = 0;
106
107
    # FIXME: way too much logic to live only here in a report script
108
    for ( my $i2 = 0 ; $i2 < $count ; $i2++ ) {
109
        $charge += $charges[$i2]->{'amount'};
110
        %row = (
111
            name   => $charges[$i2]->{'description'},
112
            type   => $charges[$i2]->{'accounttype'},
113
            time   => $charges[$i2]->{'timestamp'},
114
            amount => $charges[$i2]->{'amount'},
115
            branch => $charges[$i2]->{'amountoutstanding'}
116
        );
117
        push( @loop, \%row );
118
        if ( $payments[$i]{'accountytpe'} ne 'W' ) {
119
            if ( $charges[$i2]->{'accounttype'} eq 'Rent' ) {
120
                $temptotalr +=
121
                  $charges[$i2]->{'amount'} -
122
                  $charges[$i2]->{'amountoutstanding'};
123
            }
124
            if (   $charges[$i2]->{'accounttype'} eq 'F'
125
                || $charges[$i2]->{'accounttype'} eq 'FU'
126
                || $charges[$i2]->{'accounttype'} eq 'FN' )
127
            {
128
                $temptotalf +=
129
                  $charges[$i2]->{'amount'} -
130
                  $charges[$i2]->{'amountoutstanding'};
131
            }
132
            if ( $charges[$i2]->{'accounttype'} eq 'Res' ) {
133
                $temptotalres +=
134
                  $charges[$i2]->{'amount'} -
135
                  $charges[$i2]->{'amountoutstanding'};
136
            }
137
            if ( $charges[$i2]->{'accounttype'} eq 'R' ) {
138
                $temptotalren +=
139
                  $charges[$i2]->{'amount'} -
140
                  $charges[$i2]->{'amountoutstanding'};
141
            }
142
        }
143
    }
144
    my $time2 = $payments[$i]{'date'};
145
    my $branch = Getpaidbranch( $time2, $payments[$i]{'borrowernumber'} );
146
    my $borrowernumber = $payments[$i]{'borrowernumber'};
147
    my $oldtime        = $payments[$i]{'timestamp'};
148
    my $oldtype        = $payments[$i]{'accounttype'};
149
150
    while ($borrowernumber eq $payments[$i]{'borrowernumber'}
151
        && $oldtype == $payments[$i]{'accounttype'}
152
        && $oldtime eq $payments[$i]{'timestamp'} )
153
    {
154
        my $xtime2 = $payments[$i]{'date'};
155
        my $branch = Getpaidbranch( $xtime2, $payments[$i]{'borrowernumber'} );
156
        if ( $payments[$i]{'accounttype'} eq 'W' ) {
157
            $totalw += $payments[$i]{'amount'};
158
        }
159
        else {
160
            $payments[$i]{'amount'} = $payments[$i]{'amount'} * -1;
161
            $total += $payments[$i]{'amount'};
162
        }
163
164
        #FIXME: display layer HTML
165
        %row = (
166
            name => "<b>"
167
              . $payments[$i]{'firstname'}
168
              . $payments[$i]{'surname'} . "</b>",
169
            type   => $payments[$i]{'accounttype'},
170
            time   => $payments[$i]{'date'},
171
            amount => $payments[$i]{'amount'},
172
            branch => $branch
173
        );
174
        push( @loop, \%row );
175
        $oldtype        = $payments[$i]{'accounttype'};
176
        $oldtime        = $payments[$i]{'timestamp'};
177
        $borrowernumber = $payments[$i]{'borrowernumber'};
178
        $i++;
179
    }
180
}
181
182
$template->param(
183
    loop1  => \@loop,
184
    totalw => $totalw,
185
    total  => $total
186
);
187
188
output_html_with_http_headers $input, $cookie, $template->output;
189
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/stats.tt (-55 lines)
Lines 1-55 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Circulation &rsaquo; Statistics</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
</head>
5
<body id="circ_stats" class="circ">
6
[% INCLUDE 'header.inc' %]
7
[% INCLUDE 'circ-search.inc' %]
8
9
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a>  &rsaquo; Statistics</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
17
    [% IF ( notime ) %]
18
        <h1>Display statistics for:</h1>
19
        <ul>
20
            <li><a href="/cgi-bin/koha/circ/stats.pl?time=yesterday">yesterday</a></li>
21
            <li><a href="/cgi-bin/koha/circ/stats.pl?time=today">today</a></li>
22
    [% ELSE %]
23
    	[% IF ( loop1 ) %]
24
    	<table>
25
    	<caption>Statistics</caption>
26
    		<tr>
27
    			<th>Name</th>
28
    			<th>Type</th>
29
    			<th>Date/time</th>
30
    			<th>Amount</th>
31
    			<th>Library</th>
32
    		<tr>
33
    		[% FOREACH loop IN loop1 %]
34
    		<tr>
35
    			<td>[% loop.name %]</td>
36
    			<td>[% loop.type %]</td>
37
    			<td>[% loop.time %]</td>
38
    			<td>[% loop.amount %]</td>
39
    			<td>[% loop.branch %]</td>
40
    		</tr>
41
    		[% END %]
42
    		</table>
43
    		<p>Total paid: [% total %]<br />Total written off: [% totalw %]</p>
44
    	[% ELSE %]
45
    	<h3>No statistics to report</h3>
46
    	[% END %]
47
	
48
    [% END %]
49
</div>
50
</div>
51
<div class="yui-b">
52
[% INCLUDE 'circ-menu.inc' %]
53
</div>
54
</div>
55
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt (-122 lines)
Lines 1-122 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 'Pay00' %]Payment, thanks (cash via SIP2)
51
          [% CASE 'Pay01' %]Payment, thanks (VISA via SIP2)
52
          [% CASE 'Pay02' %]Payment, thanks (credit card via SIP2)
53
          [% CASE 'N' %]New card
54
          [% CASE 'F' %]Fine
55
          [% CASE 'A' %]Account management fee
56
          [% CASE 'M' %]Sundry
57
          [% CASE 'L' %]Lost item
58
          [% CASE 'W' %]Writeoff
59
          [% CASE 'FU' %]Accruing fine
60
          [% CASE 'Rent' %]Rental fee
61
          [% CASE 'FOR' %]Forgiven
62
          [% CASE 'LR' %]Lost item fee refund
63
          [% CASE 'PAY' %]Payment
64
          [% CASE 'WO' %]Writeoff
65
          [% CASE 'C' %]Credit
66
          [% CASE 'CR' %]Credit
67
          [% CASE %][% account.accounttype %]
68
        [%- END -%]
69
        [%- IF account.description %], [% account.description %][% END %]
70
        &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>
71
      <td>[% account.note | html_line_break %]</td>
72
      [% IF ( account.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amount %]</td>
73
      [% IF ( account.amountoutstandingcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amountoutstanding %]</td>
74
    [% IF ( reverse_col ) %]
75
      <td>
76
	[% IF ( account.payment ) %]
77
		<a href="boraccount.pl?action=reverse&amp;accountlines_id=[% account.accountlines_id %]&amp;borrowernumber=[% account.borrowernumber %]">Reverse</a>
78
	[% ELSE %]
79
		&nbsp;
80
	[% END %]
81
      </td>
82
	[% END %]
83
<td>
84
	[% IF ( account.payment ) %]
85
		<a target="_blank" href="printfeercpt.pl?action=print&amp;accountlines_id=[% account.accountlines_id %]&amp;borrowernumber=[% account.borrowernumber %]">Print</a>
86
	[% ELSE %]
87
		<a target="_blank" href="printinvoice.pl?action=print&amp;accountlines_id=[% account.accountlines_id %]&amp;borrowernumber=[% account.borrowernumber %]">Print</a>
88
	[% END %]
89
      </td>
90
    </tr>
91
92
  [% END %]
93
<tfoot>
94
  <tr>
95
    <td colspan="4">Total due</td>
96
    [% IF ( totalcredit ) %]
97
      [% IF ( reverse_col ) %]
98
        <td colspan="3" class="credit">
99
      [% ELSE %]
100
        <td colspan="2" class="credit">
101
      [% END %]
102
    [% ELSE %]
103
      [% IF ( reverse_col ) %]
104
        <td colspan="3" class="debit">
105
      [% ELSE %]
106
        <td colspan="2" class="credit">
107
      [% END %]
108
    [% END %]
109
    [% total %]</td>
110
  </tr>
111
  </tfoot>
112
</table>
113
</div></div>
114
115
</div>
116
</div>
117
118
<div class="yui-b">
119
[% INCLUDE 'circ-menu.inc' %]
120
</div>
121
</div>
122
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/mancredit.tt (-63 lines)
Lines 1-63 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Patrons &rsaquo; Create manual credit</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
<script type="text/javascript">
5
//<![CDATA[
6
$(document).ready(function(){
7
        $('#mancredit').preventDoubleFormSubmit();
8
        $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit");
9
});
10
//]]>
11
</script>
12
</head>
13
<body id="pat_mancredit" 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 credit</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><a href="/cgi-bin/koha/members/maninvoice.pl?borrowernumber=[% borrowernumber %]" >Create manual invoice</a></li>
32
    <li class="active"><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% borrowernumber %]" >Create manual credit</a></li>
33
</ul>
34
<div class="tabs-container">
35
36
<form action="/cgi-bin/koha/members/mancredit.pl" method="post" id="mancredit">
37
<input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrowernumber %]" />
38
39
<fieldset class="rows">
40
<legend>Manual credit</legend><ol>
41
	<li><label for="type">Credit type: </label><select name="type" id="type">
42
<option value="C">Credit</option>
43
<option value="FOR">Forgiven</option>
44
</select></li>
45
	<li><label for="barcode">Barcode: </label><input type="text" name="barcode" id="barcode" /></li>
46
	<li><label for="desc">Description: </label><input type="text" name="desc" size="50" id="desc" /></li>
47
    <li><label for="note">Note: </label><input type="text" name="note" size="50" id="note" /></li>
48
	<li><label for="amount">Amount: </label><input type="text" name="amount" id="amount" /> Example: 5.00</li>
49
</ol></fieldset>
50
51
<fieldset class="action"><input type="submit" name="add" value="Add credit" /> <a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrowernumber %]">Cancel</a></fieldset>
52
</form>
53
54
</div></div>
55
56
</div>
57
</div>
58
59
<div class="yui-b">
60
[% INCLUDE 'circ-menu.inc' %]
61
</div>
62
</div>
63
[% 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; Patrons &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, fieldset.rows select").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 (-178 lines)
Lines 1-178 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="[% interface %]/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!").format( "[% total | format('%.2f') %]" );
20
            var answer = confirm(msg);
21
                if (!answer){
22
                    event.preventDefault();
23
                }
24
        });
25
        $('#CheckAll').click(function(){
26
            $("#finest").checkCheckboxes();
27
            enableCheckboxActions();
28
            return false;
29
        });
30
        $('#CheckNone').click(function(){
31
            $("#finest").unCheckCheckboxes();
32
            enableCheckboxActions();
33
            return false;
34
        });
35
        $(".cb").change(function(){
36
            enableCheckboxActions();
37
        });
38
        enableCheckboxActions();
39
    });
40
//]]>
41
</script>
42
</head>
43
<body id="pat_pay" class="pat">
44
[% INCLUDE 'header.inc' %]
45
[% INCLUDE 'patron-search.inc' %]
46
47
<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>
48
49
<div id="doc3" class="yui-t2">
50
   
51
   <div id="bd">
52
	<div id="yui-main">
53
	<div class="yui-b">
54
[% INCLUDE 'members-toolbar.inc' borrowernumber=borrower.borrowernumber %]
55
56
<!-- The manual invoice and credit buttons -->
57
<div class="statictabs">
58
<ul>
59
	<li><a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrower.borrowernumber %]">Account</a></li>
60
    <li class="active"><a href="/cgi-bin/koha/members/pay.pl?borrowernumber=[% borrower.borrowernumber %]" >Pay fines</a></li>
61
	<li><a href="/cgi-bin/koha/members/maninvoice.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual invoice</a></li>
62
	<li><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=[% borrower.borrowernumber %]" >Create manual credit</a></li>
63
</ul>
64
<div class="tabs-container">
65
66
[% IF ( accounts ) %]
67
    <form action="/cgi-bin/koha/members/pay.pl" method="post" id="pay-fines-form">
68
	<input type="hidden" name="borrowernumber" id="borrowernumber" value="[% borrower.borrowernumber %]" />
69
<p><span class="checkall"><a id="CheckAll" href="#">Select all</a></span> | <span class="clearall"><a id="CheckNone" href="#">Clear all</a></span></p>
70
<table id="finest">
71
<thead>
72
<tr>
73
    <th>&nbsp;</th>
74
    <th>Fines &amp; charges</th>
75
    <th>Description</th>
76
    <th>Payment note</th>
77
    <th>Account type</th>
78
    <th>Notify id</th>
79
    <th>Level</th>
80
    <th>Amount</th>
81
    <th>Amount outstanding</th>
82
</tr>
83
</thead>
84
<tfoot>
85
<tr>
86
    <td class="total" colspan="8">Total due:</td>
87
    <td>[% total | format('%.2f') %]</td>
88
</tr>
89
</tfoot>
90
<tbody>
91
[% FOREACH account_grp IN accounts %]
92
    [% FOREACH line IN account_grp.accountlines %]
93
<tr>
94
    <td>
95
    [% IF ( line.amountoutstanding > 0 ) %]
96
        <input class="cb" type="checkbox" checked="checked" name="incl_par_[% line.accountno %]" />
97
    [% END %]
98
    </td>
99
    <td>
100
    [% IF ( line.amountoutstanding > 0 ) %]
101
        <input type="submit" name="pay_indiv_[% line.accountno %]" value="Pay" />
102
        [% IF CAN_user_updatecharges_writeoff %]<input type="submit" name="wo_indiv_[% line.accountno %]" value="Write off" />[% END %]
103
    [% END %]
104
    <input type="hidden" name="itemnumber[% line.accountno %]" value="[% line.itemnumber %]" />
105
    <input type="hidden" name="description[% line.accountno %]" value="[% line.description %]" />
106
    <input type="hidden" name="accounttype[% line.accountno %]" value="[% line.accounttype %]" />
107
    <input type="hidden" name="amount[% line.accountno %]" value="[% line.amount %]" />
108
    <input type="hidden" name="accountlines_id[% line.accountno %]" value="[% line.accountlines_id %]" />
109
    <input type="hidden" name="amountoutstanding[% line.accountno %]" value="[% line.amountoutstanding %]" />
110
    <input type="hidden" name="borrowernumber[% line.accountno %]" value="[% line.borrowernumber %]" />
111
    <input type="hidden" name="accountno[% line.accountno %]" value="[% line.accountno %]" />
112
    <input type="hidden" name="notify_id[% line.accountno %]" value="[% line.notify_id %]" />
113
    <input type="hidden" name="notify_level[% line.accountno %]" value="[% line.notify_level %]" />
114
    <input type="hidden" name="totals[% line.accountno %]" value="[% line.totals %]" />
115
    </td>
116
    <td>
117
        [% SWITCH line.accounttype %]
118
          [% CASE 'Pay' %]Payment, thanks
119
          [% CASE 'Pay00' %]Payment, thanks (cash via SIP2)
120
          [% CASE 'Pay01' %]Payment, thanks (VISA via SIP2)
121
          [% CASE 'Pay02' %]Payment, thanks (credit card via SIP2)
122
          [% CASE 'N' %]New card
123
          [% CASE 'F' %]Fine
124
          [% CASE 'A' %]Account management fee
125
          [% CASE 'M' %]Sundry
126
          [% CASE 'L' %]Lost item
127
          [% CASE 'W' %]Writeoff
128
          [% CASE 'FU' %]Accruing fine
129
          [% CASE 'Rent' %]Rental fee
130
          [% CASE 'FOR' %]Forgiven
131
          [% CASE 'LR' %]Lost item fee refund
132
          [% CASE 'PAY' %]Payment
133
          [% CASE 'WO' %]Writeoff
134
          [% CASE 'C' %]Credit
135
          [% CASE 'CR' %]Credit
136
          [% CASE %][% line.accounttype %]
137
        [%- END -%]
138
        [%- IF line.description %], [% line.description %][% END %]
139
        [% IF line.title %]([% line.title |html_entity %])[% END %]
140
    </td>
141
    <td><input type="text" name="payment_note_[% line.accountno %]" /></td>
142
    <td>[% line.accounttype %]</td>
143
    <td>[% line.notify_id %]</td>
144
    <td>[% line.notify_level %]</td>
145
    <td class="debit">[% line.amount | format('%.2f') %]</td>
146
    <td class="debit">[% line.amountoutstanding | format('%.2f') %]</td>
147
</tr>
148
[% END %]
149
[% IF ( account_grp.total ) %]
150
<tr>
151
152
    <td class="total" colspan="8">Sub total:</td>
153
    <td>[% account_grp.total | format('%.2f') %]</td>
154
</tr>
155
[% END %]
156
[% END %]
157
</tbody>
158
</table>
159
<fieldset class="action">
160
<input type="submit" id="paycollect" name="paycollect"  value="Pay amount" class="submit" />
161
[% IF CAN_user_updatecharges_writeoff %]<input type="submit" name="woall"  id="woall" value="Write off all" class="submit" />[% END %]
162
<input type="submit" id="payselected" name="payselected"  value="Pay selected" class="submit" />
163
<a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=[% borrower.borrowernumber %]">Cancel</a>
164
</fieldset>
165
</form>
166
[% ELSE %]
167
    <p>[% borrower.firstname %] [% borrower.surname %] has no outstanding fines.</p>
168
[% END %]
169
</div></div>
170
171
</div>
172
</div>
173
174
<div class="yui-b">
175
[% INCLUDE 'circ-menu.tt' %]
176
</div>
177
</div>
178
[% 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 (-59 lines)
Lines 1-59 Link Here
1
[% USE Koha %]
2
[% INCLUDE 'doc-head-open.inc' %]
3
<title>Print Receipt for [% cardnumber %]</title>
4
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
<link rel="shortcut icon" href="[% IF ( IntranetFavicon ) %][% IntranetFavicon %][% ELSE %][% interface %]/[% theme %]/img/favicon.ico[% END %]" type="image/x-icon" />
6
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/printreceiptinvoice.css" />
7
[% INCLUDE 'slip-print.inc' #printThenClose %]
8
</head>
9
<body id="pat_printfeercpt" class="pat" onload="printThenClose();">
10
11
<div id="receipt">
12
<!-- The table with the account items -->
13
<table>
14
[% IF ( LibraryName ) %]
15
 <tr>
16
	<th colspan=3 class="centerednames">
17
		<h3>[% LibraryName %]</h3>
18
	</th>
19
 </tr>
20
[% END %]
21
 <tr>
22
	<th colspan=3 class="centerednames">
23
        <h2><u>Fee receipt</u></h2>
24
	</th>
25
 </tr>
26
 <tr>
27
	<th colspan=3 class="centerednames">
28
		[% IF ( branchname ) %]<h2>[% branchname %]</h2>[% END %]
29
	</th>
30
 </tr>
31
 <tr>
32
	<th colspan=3 >
33
		Received with thanks from  [% firstname %] [% surname %] <br />
34
        Card number : [% cardnumber %]<br />
35
	</th>
36
 </tr>
37
  <tr>
38
	<th>Date</th>
39
    <th>Description of charges</th>
40
    <th>Amount</th>
41
 </tr>
42
43
  [% FOREACH account IN accounts %]
44
<tr class="highlight">
45
      <td>[% account.date %]</td>
46
      <td>[% account.description %]</td>
47
      [% IF ( account.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amount %]</td>
48
    </tr>
49
50
  [% END %]
51
<tfoot>
52
  <tr>
53
    <td colspan="2">Total outstanding dues as on date : </td>
54
    [% IF ( totalcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% total %]</td>
55
  </tr>
56
  </tfoot>
57
</table>
58
</div>
59
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/printinvoice.tt (-61 lines)
Lines 1-61 Link Here
1
[% USE Koha %]
2
[% INCLUDE 'doc-head-open.inc' %]
3
<title>Print Receipt for [% cardnumber %]</title>
4
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
<link rel="shortcut icon" href="[% IF ( IntranetFavicon ) %][% IntranetFavicon %][% ELSE %][% interface %]/[% theme %]/img/favicon.ico[% END %]" type="image/x-icon" />
6
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/printreceiptinvoice.css" />
7
[% INCLUDE 'slip-print.inc' #printThenClose %]
8
</head>
9
<body id="printinvoice" class="pat" onload="printThenClose();">
10
11
<div id="receipt">
12
<!-- The table with the account items -->
13
<table>
14
[% IF ( LibraryName ) %]
15
  <tr>
16
    <th colspan="4" class="centerednames">
17
		<h3>[% LibraryName %]</h3>
18
	</th>
19
  </tr>
20
[% END %]
21
  <tr>
22
    <th colspan="4" class="centerednames">
23
		<h2><u>INVOICE</u></h2>
24
	</th>
25
  </tr>
26
  <tr>
27
    <th colspan="4" class="centerednames">
28
		[% IF ( branchname ) %]<h2>[% branchname %]</h2>[% END %]
29
	</th>
30
  </tr>
31
  <tr>
32
    <th colspan="4" >
33
        Bill to: [% firstname %] [% surname %] <br />
34
        Card number: [% cardnumber %]<br />
35
	</th>
36
  </tr>
37
  <tr>
38
	<th>Date</th>
39
    <th>Description of charges</th>
40
    <th style="text-align:right;">Amount</th>
41
    <th style="text-align:right;">Amount outstanding</th>
42
 </tr>
43
44
  [% FOREACH account IN accounts %]
45
<tr class="highlight">
46
      <td>[% account.date %]</td>
47
      <td>[% account.description %]</td>
48
      [% IF ( account.amountcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amount %]</td>
49
      [% IF ( account.amountoutstandingcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% account.amountoutstanding %]</td>
50
    </tr>
51
52
  [% END %]
53
<tfoot>
54
  <tr>
55
    <td colspan="3">Total outstanding dues as on date: </td>
56
    [% IF ( totalcredit ) %]<td class="credit">[% ELSE %]<td class="debit">[% END %][% total %]</td>
57
  </tr>
58
  </tfoot>
59
</table>
60
</div>
61
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reports/stats_screen.tt (-131 lines)
Lines 1-131 Link Here
1
[% INCLUDE 'doc-head-open.inc' %] 
2
<title>Koha &rsaquo; Reports &rsaquo; Till reconciliation</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
[% INCLUDE 'calendar.inc' %]
5
</head>
6
<body id="rep_stats_screen" class="rep">
7
[% INCLUDE 'header.inc' %]
8
[% INCLUDE 'circ-search.inc' %]
9
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/reports/reports-home.pl">Reports</a> &rsaquo; Till reconciliation
10
</div>
11
12
<div id="doc3" class="yui-t2">
13
   
14
   <div id="bd">
15
	<div id="yui-main">
16
	<div class="yui-b">
17
18
<h1>Till reconciliation</h1>
19
20
<fieldset><legend>Search between two dates</legend>
21
<form action="stats.screen.pl" method="post">
22
  <label for="from">Start Date: </label>
23
  <input type="text" name="time" size="10" value="[% IF ( date ) %][% date %][% ELSE %]today[% END %]" id="from" class="datepickerfrom" />
24
  <label for="to">End Date: </label>
25
  <input type="text" name="time2" size="10" value="[% IF ( date2 ) %][% date2 %][% ELSE %]tomorrow[% END %]" class="datepickerto" id="to" />
26
  <input type="submit" value="To screen" name="submit" class="submit" />
27
<!--  <input type="submit" value="To Excel" name="submit" class="button"> --></fieldset>
28
</form>
29
30
<h2>Payments</h2>
31
32
        <table>
33
                <tr>
34
                        <th>Library</th>
35
                        <th>Date/time</th>
36
                        <th>Surname</th>
37
                        <th>First name</th>
38
                        <th>Description</th>
39
                        <th>Charge type</th>
40
                        <th>Invoice amount</th>
41
                        <th>Payment type</th>
42
                        <th>Payment amount</th>
43
                </tr>
44
45
                [% FOREACH loop IN loop1 %]
46
                <tr>
47
                     <td>[% loop.branch %]</td>
48
                        <td>[% loop.datetime %]</td>
49
                        <td>[% loop.surname %]</td>
50
                        <td>[% loop.firstname %]</td>
51
                        <td>[% loop.description %]</td>
52
                        <td>[% loop.accounttype %]</td>
53
                        <td>[% loop.amount %]</td>
54
                        <td>[% loop.type %]</td>
55
                        <td>[% loop.value %]</td>
56
                </tr>
57
                [% END %]
58
        </table>
59
60
<p>
61
        <b>Total amount paid: [% totalpaid %]</b>
62
</p>
63
64
65
<h2>Credits</h2>
66
67
        <table>
68
                <tr>
69
                        <th>Library</th>
70
                        <th>Date/time</th>
71
                        <th>Surname</th>
72
                        <th>First name</th>
73
                        <th>Description</th>
74
                        <th>Charge type</th>
75
                        <th>Invoice amount</th>
76
                </tr>
77
78
                [% FOREACH loop IN loop2 %]
79
                <tr>
80
                     <td>[% loop.creditbranch %]</td>
81
                        <td>[% loop.creditdate %]</td>
82
                        <td>[% loop.creditsurname %]</td>
83
                        <td>[% loop.creditfirstname %]</td>
84
                        <td>[% loop.creditdescription %]</td>
85
                        <td>[% loop.creditaccounttype %]</td>
86
                        <td>[% loop.creditamount %]</td>
87
                </tr>
88
                [% END %]
89
        </table>
90
<p>
91
       <ul><li> <b>Total amount credits: [% totalcredits %]</b></li>
92
        <li><b>Total number written off: [% totalwritten %] charges</b></li></ul>
93
</p>
94
95
96
<h2>Refunds</h2>
97
98
        <table>
99
                <tr>
100
                        <th>Library</th>
101
                        <th>Date/time</th>
102
                        <th>Surname</th>
103
                        <th>First name</th>
104
                        <th>Description</th>
105
                        <th>Charge type</th>
106
                        <th>Invoice amount</th>
107
                </tr>
108
109
                [% FOREACH loop IN loop3 %]
110
                <tr>
111
                     <td>[% loop.refundbranch %]</td>
112
                        <td>[% loop.refunddate %]</td>
113
                        <td>[% loop.refundsurname %]</td>
114
                        <td>[% loop.refundfirstname %]</td>
115
                        <td>[% loop.refunddescription %]</td>
116
                        <td>[% loop.refundaccounttype %]</td>
117
                        <td>[% loop.refundamount %]</td>
118
                </tr>
119
                [% END %]
120
        </table>
121
<p>
122
        <ul><li><b>Total amount refunds: [% totalrefund %]</b></li>
123
        <li><b>Total amount of cash collected: [% totalcash %] </b></li></ul>
124
</p>
125
</div>
126
</div>
127
<div class="yui-b">
128
[% INCLUDE 'reports-menu.inc' %]
129
</div>
130
</div>
131
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/members/boraccount.pl (-145 lines)
Lines 1-145 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) = get_template_and_user(
41
    {
42
        template_name   => "members/boraccount.tt",
43
        query           => $input,
44
        type            => "intranet",
45
        authnotrequired => 0,
46
        flagsrequired   => { borrowers     => 1,
47
                             updatecharges => 'remaining_permissions'},
48
        debug           => 1,
49
    }
50
);
51
52
my $borrowernumber=$input->param('borrowernumber');
53
my $action = $input->param('action') || '';
54
55
#get borrower details
56
my $data=GetMember('borrowernumber' => $borrowernumber);
57
58
if ( $action eq 'reverse' ) {
59
  ReversePayment( $input->param('accountlines_id') );
60
}
61
62
if ( $data->{'category_type'} eq 'C') {
63
   my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
64
   my $cnt = scalar(@$catcodes);
65
   $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
66
   $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
67
}
68
69
#get account details
70
my ($total,$accts,undef)=GetMemberAccountRecords($borrowernumber);
71
my $totalcredit;
72
if($total <= 0){
73
        $totalcredit = 1;
74
}
75
76
my $reverse_col = 0; # Flag whether we need to show the reverse column
77
foreach my $accountline ( @{$accts}) {
78
    $accountline->{amount} += 0.00;
79
    if ($accountline->{amount} <= 0 ) {
80
        $accountline->{amountcredit} = 1;
81
    }
82
    $accountline->{amountoutstanding} += 0.00;
83
    if ( $accountline->{amountoutstanding} <= 0 ) {
84
        $accountline->{amountoutstandingcredit} = 1;
85
    }
86
87
    $accountline->{date} = format_date($accountline->{date});
88
    $accountline->{amount} = sprintf '%.2f', $accountline->{amount};
89
    $accountline->{amountoutstanding} = sprintf '%.2f', $accountline->{amountoutstanding};
90
    if ($accountline->{accounttype} =~ /^Pay/) {
91
        $accountline->{payment} = 1;
92
        $reverse_col = 1;
93
    }
94
}
95
96
$template->param( adultborrower => 1 ) if ( $data->{'category_type'} eq 'A' );
97
98
my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
99
$template->param( picture => 1 ) if $picture;
100
101
if (C4::Context->preference('ExtendedPatronAttributes')) {
102
    my $attributes = GetBorrowerAttributes($borrowernumber);
103
    $template->param(
104
        ExtendedPatronAttributes => 1,
105
        extendedattributes => $attributes
106
    );
107
}
108
109
# Computes full borrower address
110
my $roadtype = C4::Koha::GetAuthorisedValueByCode( 'ROADTYPE', $data->{streettype} );
111
my $address = $data->{'streetnumber'} . " $roadtype " . $data->{'address'};
112
113
$template->param(
114
    finesview           => 1,
115
    firstname           => $data->{'firstname'},
116
    surname             => $data->{'surname'},
117
    othernames          => $data->{'othernames'},
118
    borrowernumber      => $borrowernumber,
119
    cardnumber          => $data->{'cardnumber'},
120
    categorycode        => $data->{'categorycode'},
121
    category_type       => $data->{'category_type'},
122
    categoryname		=> $data->{'description'},
123
    address             => $address,
124
    address2            => $data->{'address2'},
125
    city                => $data->{'city'},
126
    state               => $data->{'state'},
127
    zipcode             => $data->{'zipcode'},
128
    country             => $data->{'country'},
129
    phone               => $data->{'phone'},
130
    phonepro            => $data->{'phonepro'},
131
    mobile              => $data->{'mobile'},
132
    email               => $data->{'email'},
133
    emailpro            => $data->{'emailpro'},
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
    reverse_col         => $reverse_col,
140
    accounts            => $accts,
141
	activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
142
    RoutingSerials => C4::Context->preference('RoutingSerials'),
143
);
144
145
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/members/mancredit.pl (-126 lines)
Lines 1-126 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) = get_template_and_user(
64
        {
65
            template_name   => "members/mancredit.tt",
66
            query           => $input,
67
            type            => "intranet",
68
            authnotrequired => 0,
69
            flagsrequired   => { borrowers     => 1,
70
                                 updatecharges => 'remaining_permissions' },
71
            debug           => 1,
72
        }
73
    );
74
					  
75
    if ( $data->{'category_type'} eq 'C') {
76
        my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
77
        my $cnt = scalar(@$catcodes);
78
        $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
79
        $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
80
    }
81
82
    $template->param( adultborrower => 1 ) if ( $data->{category_type} eq 'A' );
83
    my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
84
    $template->param( picture => 1 ) if $picture;
85
86
if (C4::Context->preference('ExtendedPatronAttributes')) {
87
    my $attributes = GetBorrowerAttributes($borrowernumber);
88
    $template->param(
89
        ExtendedPatronAttributes => 1,
90
        extendedattributes => $attributes
91
    );
92
}
93
94
# Computes full borrower address
95
my $roadtype = C4::Koha::GetAuthorisedValueByCode( 'ROADTYPE', $data->{streettype} );
96
my $address = $data->{'streetnumber'} . " $roadtype " . $data->{'address'};
97
98
    $template->param(
99
        finesview => 1,
100
        borrowernumber => $borrowernumber,
101
        firstname => $data->{'firstname'},
102
        surname  => $data->{'surname'},
103
        othernames => $data->{'othernames'},
104
		    cardnumber => $data->{'cardnumber'},
105
		    categorycode => $data->{'categorycode'},
106
		    category_type => $data->{'category_type'},
107
		    categoryname  => $data->{'description'},
108
            address => $address,
109
		    address2 => $data->{'address2'},
110
		    city => $data->{'city'},
111
		    state => $data->{'state'},
112
		    zipcode => $data->{'zipcode'},
113
		    country => $data->{'country'},
114
		    phone => $data->{'phone'},
115
            phonepro => $data->{'phonepro'},
116
            mobile => $data->{'mobile'},
117
		    email => $data->{'email'},
118
            emailpro => $data->{'emailpro'},
119
		    branchcode => $data->{'branchcode'},
120
		    branchname => GetBranchName($data->{'branchcode'}),
121
		    is_child        => ($data->{'category_type'} eq 'C'),
122
			activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
123
            RoutingSerials => C4::Context->preference('RoutingSerials'),
124
        );
125
    output_html_with_http_headers $input, $cookie, $template->output;
126
}
(-)a/members/maninvoice.pl (-152 lines)
Lines 1-152 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.tt",
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) = get_template_and_user({
82
        template_name   => "members/maninvoice.tt",
83
        query           => $input,
84
        type            => "intranet",
85
        authnotrequired => 0,
86
        flagsrequired   => { borrowers => 1,
87
                             updatecharges => 'remaining_permissions' },
88
        debug           => 1,
89
    });
90
					
91
  # get authorised values with type of MANUAL_INV
92
  my @invoice_types;
93
  my $dbh = C4::Context->dbh;
94
  my $sth = $dbh->prepare('SELECT * FROM authorised_values WHERE category = "MANUAL_INV"');
95
  $sth->execute();
96
  while ( my $row = $sth->fetchrow_hashref() ) {
97
    push @invoice_types, $row;
98
  }
99
  $template->param( invoice_types_loop => \@invoice_types );
100
101
    if ( $data->{'category_type'} eq 'C') {
102
        my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
103
        my $cnt = scalar(@$catcodes);
104
        $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
105
        $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
106
    }
107
108
    $template->param( adultborrower => 1 ) if ( $data->{'category_type'} eq 'A' );
109
    my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
110
    $template->param( picture => 1 ) if $picture;
111
112
if (C4::Context->preference('ExtendedPatronAttributes')) {
113
    my $attributes = GetBorrowerAttributes($borrowernumber);
114
    $template->param(
115
        ExtendedPatronAttributes => 1,
116
        extendedattributes => $attributes
117
    );
118
}
119
120
# Computes full borrower address
121
my $roadtype = C4::Koha::GetAuthorisedValueByCode( 'ROADTYPE', $data->{streettype} );
122
my $address = $data->{'streetnumber'} . " $roadtype " . $data->{'address'};
123
124
	$template->param(
125
                finesview => 1,
126
                borrowernumber => $borrowernumber,
127
		firstname => $data->{'firstname'},
128
                surname  => $data->{'surname'},
129
        othernames => $data->{'othernames'},
130
		cardnumber => $data->{'cardnumber'},
131
		categorycode => $data->{'categorycode'},
132
		category_type => $data->{'category_type'},
133
		categoryname  => $data->{'description'},
134
        address => $address,
135
		address2 => $data->{'address2'},
136
		city => $data->{'city'},
137
		state => $data->{'state'},
138
		zipcode => $data->{'zipcode'},
139
		country => $data->{'country'},
140
		phone => $data->{'phone'},
141
        phonepro => $data->{'phonepro'},
142
        mobile => $data->{'mobile'},
143
		email => $data->{'email'},
144
        emailpro => $data->{'emailpro'},
145
		branchcode => $data->{'branchcode'},
146
		branchname => GetBranchName($data->{'branchcode'}),
147
		is_child        => ($data->{'category_type'} eq 'C'),
148
		activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
149
        RoutingSerials => C4::Context->preference('RoutingSerials'),
150
    );
151
    output_html_with_http_headers $input, $cookie, $template->output;
152
}
(-)a/members/pay.pl (-267 lines)
Lines 1-267 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
my $updatecharges_permissions = $input->param('woall') ? 'writeoff' : 'remaining_permissions';
48
our ( $template, $loggedinuser, $cookie ) = get_template_and_user(
49
    {   template_name   => 'members/pay.tt',
50
        query           => $input,
51
        type            => 'intranet',
52
        authnotrequired => 0,
53
        flagsrequired   => { borrowers => 1, updatecharges => $updatecharges_permissions },
54
        debug           => 1,
55
    }
56
);
57
58
my @names = $input->param;
59
60
our $borrowernumber = $input->param('borrowernumber');
61
if ( !$borrowernumber ) {
62
    $borrowernumber = $input->param('borrowernumber0');
63
}
64
65
# get borrower details
66
our $borrower = GetMember( borrowernumber => $borrowernumber );
67
our $user = $input->remote_user;
68
$user ||= q{};
69
70
my $branches = GetBranches();
71
our $branch = GetBranch( $input, $branches );
72
73
my $writeoff_item = $input->param('confirm_writeoff');
74
my $paycollect    = $input->param('paycollect');
75
if ($paycollect) {
76
    print $input->redirect(
77
        "/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber");
78
}
79
my $payselected = $input->param('payselected');
80
if ($payselected) {
81
    payselected(@names);
82
}
83
84
my $writeoff_all = $input->param('woall');    # writeoff all fines
85
if ($writeoff_all) {
86
    writeoff_all(@names);
87
} elsif ($writeoff_item) {
88
    my $accountlines_id = $input->param('accountlines_id');
89
    my $itemno       = $input->param('itemnumber');
90
    my $account_type = $input->param('accounttype');
91
    my $amount       = $input->param('amountoutstanding');
92
    my $payment_note = $input->param("payment_note");
93
    WriteOffFee( $borrowernumber, $accountlines_id, $itemno, $account_type, $amount, $branch, $payment_note );
94
}
95
96
for (@names) {
97
    if (/^pay_indiv_(\d+)$/) {
98
        my $line_no = $1;
99
        redirect_to_paycollect( 'pay_individual', $line_no );
100
    } elsif (/^wo_indiv_(\d+)$/) {
101
        my $line_no = $1;
102
        redirect_to_paycollect( 'writeoff_individual', $line_no );
103
    }
104
}
105
106
$template->param(
107
    finesview => 1,
108
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
109
    RoutingSerials => C4::Context->preference('RoutingSerials'),
110
);
111
112
add_accounts_to_template();
113
114
output_html_with_http_headers $input, $cookie, $template->output;
115
116
sub add_accounts_to_template {
117
118
    my ( $total, undef, undef ) = GetMemberAccountRecords($borrowernumber);
119
    my $accounts = [];
120
    my @notify   = NumberNotifyId($borrowernumber);
121
122
    my $notify_groups = [];
123
    for my $notify_id (@notify) {
124
        my ( $acct_total, $accountlines, undef ) =
125
          GetBorNotifyAcctRecord( $borrowernumber, $notify_id );
126
        if ( @{$accountlines} ) {
127
            my $totalnotify = AmountNotify( $notify_id, $borrowernumber );
128
            push @{$accounts},
129
              { accountlines => $accountlines,
130
                notify       => $notify_id,
131
                total        => $totalnotify,
132
              };
133
        }
134
    }
135
    borrower_add_additional_fields($borrower);
136
    $template->param(
137
        accounts => $accounts,
138
        borrower => $borrower,
139
        total    => $total,
140
    );
141
    return;
142
143
}
144
145
sub get_for_redirect {
146
    my ( $name, $name_in, $money ) = @_;
147
    my $s     = q{&} . $name . q{=};
148
    my $value = $input->param($name_in);
149
    if ( !defined $value ) {
150
        $value = ( $money == 1 ) ? 0 : q{};
151
    }
152
    if ($money) {
153
        $s .= sprintf '%.2f', $value;
154
    } else {
155
        $s .= $value;
156
    }
157
    return $s;
158
}
159
160
sub redirect_to_paycollect {
161
    my ( $action, $line_no ) = @_;
162
    my $redirect =
163
      "/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber";
164
    $redirect .= q{&};
165
    $redirect .= "$action=1";
166
    $redirect .= get_for_redirect( 'accounttype', "accounttype$line_no", 0 );
167
    $redirect .= get_for_redirect( 'amount', "amount$line_no", 1 );
168
    $redirect .=
169
      get_for_redirect( 'amountoutstanding', "amountoutstanding$line_no", 1 );
170
    $redirect .= get_for_redirect( 'accountno',    "accountno$line_no",    0 );
171
    $redirect .= get_for_redirect( 'title',        "title$line_no",        0 );
172
    $redirect .= get_for_redirect( 'itemnumber',   "itemnumber$line_no",   0 );
173
    $redirect .= get_for_redirect( 'notify_id',    "notify_id$line_no",    0 );
174
    $redirect .= get_for_redirect( 'notify_level', "notify_level$line_no", 0 );
175
    $redirect .= get_for_redirect( 'accountlines_id', "accountlines_id$line_no", 0 );
176
    $redirect .= q{&} . 'payment_note' . q{=} . uri_escape( $input->param("payment_note_$line_no") );
177
    $redirect .= '&remote_user=';
178
    $redirect .= $user;
179
    return print $input->redirect($redirect);
180
}
181
182
sub writeoff_all {
183
    my @params = @_;
184
    my @wo_lines = grep { /^accountno\d+$/ } @params;
185
    for (@wo_lines) {
186
        if (/(\d+)/) {
187
            my $value       = $1;
188
            my $accounttype = $input->param("accounttype$value");
189
190
            #    my $borrowernum    = $input->param("borrowernumber$value");
191
            my $itemno    = $input->param("itemnumber$value");
192
            my $amount    = $input->param("amountoutstanding$value");
193
            my $accountno = $input->param("accountno$value");
194
            my $accountlines_id = $input->param("accountlines_id$value");
195
            my $payment_note = $input->param("payment_note_$value");
196
            WriteOffFee( $borrowernumber, $accountlines_id, $itemno, $accounttype, $amount, $branch, $payment_note );
197
        }
198
    }
199
200
    $borrowernumber = $input->param('borrowernumber');
201
    print $input->redirect(
202
        "/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber");
203
    return;
204
}
205
206
sub borrower_add_additional_fields {
207
    my $b_ref = shift;
208
209
# some borrower info is not returned in the standard call despite being assumed
210
# in a number of templates. It should not be the business of this script but in lieu of
211
# a revised api here it is ...
212
    if ( $b_ref->{category_type} eq 'C' ) {
213
        my ( $catcodes, $labels ) =
214
          GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
215
        if ( @{$catcodes} ) {
216
            if ( @{$catcodes} > 1 ) {
217
                $b_ref->{CATCODE_MULTI} = 1;
218
            } elsif ( @{$catcodes} == 1 ) {
219
                $b_ref->{catcode} = $catcodes->[0];
220
            }
221
        }
222
    } elsif ( $b_ref->{category_type} eq 'A' ) {
223
        $b_ref->{adultborrower} = 1;
224
    }
225
    my ( $picture, $dberror ) = GetPatronImage( $b_ref->{borrowernumber} );
226
    if ($picture) {
227
        $b_ref->{has_picture} = 1;
228
    }
229
230
    # Computes full borrower address
231
    my $roadtype = C4::Koha::GetAuthorisedValueByCode( 'ROADTYPE', $borrower->{streettype} );
232
    $b_ref->{address} = $borrower->{'streetnumber'} . " $roadtype " . $borrower->{'address'};
233
234
    if (C4::Context->preference('ExtendedPatronAttributes')) {
235
        $b_ref->{extendedattributes} = GetBorrowerAttributes($borrowernumber);
236
        $template->param(
237
            ExtendedPatronAttributes => 1,
238
        );
239
    }
240
241
    $b_ref->{branchname} = GetBranchName( $b_ref->{branchcode} );
242
    return;
243
}
244
245
sub payselected {
246
    my @params = @_;
247
    my $amt    = 0;
248
    my @lines_to_pay;
249
    foreach (@params) {
250
        if (/^incl_par_(\d+)$/) {
251
            my $index = $1;
252
            push @lines_to_pay, $input->param("accountno$index");
253
            $amt += $input->param("amountoutstanding$index");
254
        }
255
    }
256
    $amt = '&amt=' . $amt;
257
    my $sel = '&selected=' . join ',', @lines_to_pay;
258
    my $notes = '&notes=' . join("%0A", map { $input->param("payment_note_$_") } @lines_to_pay );
259
    my $redirect =
260
        "/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber"
261
      . $amt
262
      . $sel
263
      . $notes;
264
265
    print $input->redirect($redirect);
266
    return;
267
}
(-)a/members/paycollect.pl (-192 lines)
Lines 1-192 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::Members::Attributes qw(GetBorrowerAttributes);
29
use C4::Accounts;
30
use C4::Koha;
31
use C4::Branch;
32
33
my $input = CGI->new();
34
35
my $updatecharges_permissions = $input->param('writeoff_individual') ? 'writeoff' : 'remaining_permissions';
36
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
37
    {   template_name   => 'members/paycollect.tt',
38
        query           => $input,
39
        type            => 'intranet',
40
        authnotrequired => 0,
41
        flagsrequired   => { borrowers => 1, updatecharges => $updatecharges_permissions },
42
        debug           => 1,
43
    }
44
);
45
46
# get borrower details
47
my $borrowernumber = $input->param('borrowernumber');
48
my $borrower       = GetMember( borrowernumber => $borrowernumber );
49
my $user           = $input->remote_user;
50
51
# get account details
52
my $branch = GetBranch( $input, GetBranches() );
53
54
my ( $total_due, $accts, $numaccts ) = GetMemberAccountRecords($borrowernumber);
55
my $total_paid = $input->param('paid');
56
57
my $individual   = $input->param('pay_individual');
58
my $writeoff     = $input->param('writeoff_individual');
59
my $select_lines = $input->param('selected');
60
my $select       = $input->param('selected_accts');
61
my $payment_note = uri_unescape $input->param('payment_note');
62
my $accountno;
63
my $accountlines_id;
64
if ( $individual || $writeoff ) {
65
    if ($individual) {
66
        $template->param( pay_individual => 1 );
67
    } elsif ($writeoff) {
68
        $template->param( writeoff_individual => 1 );
69
    }
70
    my $accounttype       = $input->param('accounttype');
71
    $accountlines_id       = $input->param('accountlines_id');
72
    my $amount            = $input->param('amount');
73
    my $amountoutstanding = $input->param('amountoutstanding');
74
    $accountno = $input->param('accountno');
75
    my $itemnumber  = $input->param('itemnumber');
76
    my $description  = $input->param('description');
77
    my $title        = $input->param('title');
78
    my $notify_id    = $input->param('notify_id');
79
    my $notify_level = $input->param('notify_level');
80
    $total_due = $amountoutstanding;
81
    $template->param(
82
        accounttype       => $accounttype,
83
        accountlines_id    => $accountlines_id,
84
        accountno         => $accountno,
85
        amount            => $amount,
86
        amountoutstanding => $amountoutstanding,
87
        title             => $title,
88
        itemnumber        => $itemnumber,
89
        description       => $description,
90
        notify_id         => $notify_id,
91
        notify_level      => $notify_level,
92
        payment_note    => $payment_note,
93
    );
94
} elsif ($select_lines) {
95
    $total_due = $input->param('amt');
96
    $template->param(
97
        selected_accts => $select_lines,
98
        amt            => $total_due,
99
        selected_accts_notes => $input->param('notes'),
100
    );
101
}
102
103
if ( $total_paid and $total_paid ne '0.00' ) {
104
    if ( $total_paid < 0 or $total_paid > $total_due ) {
105
        $template->param(
106
            error_over => 1,
107
            total_due => $total_due
108
        );
109
    } else {
110
        if ($individual) {
111
            if ( $total_paid == $total_due ) {
112
                makepayment( $accountlines_id, $borrowernumber, $accountno, $total_paid, $user,
113
                    $branch, $payment_note );
114
            } else {
115
                makepartialpayment( $accountlines_id, $borrowernumber, $accountno, $total_paid,
116
                    $user, $branch, $payment_note );
117
            }
118
            print $input->redirect(
119
                "/cgi-bin/koha/members/pay.pl?borrowernumber=$borrowernumber");
120
        } else {
121
            if ($select) {
122
                if ( $select =~ /^([\d,]*).*/ ) {
123
                    $select = $1;    # ensure passing no junk
124
                }
125
                my @acc = split /,/, $select;
126
                my $note = $input->param('selected_accts_notes');
127
                recordpayment_selectaccts( $borrowernumber, $total_paid, \@acc, $note );
128
            } else {
129
                recordpayment( $borrowernumber, $total_paid );
130
            }
131
132
# recordpayment does not return success or failure so lets redisplay the boraccount
133
134
            print $input->redirect(
135
"/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber"
136
            );
137
        }
138
    }
139
} else {
140
    $total_paid = '0.00';    #TODO not right with pay_individual
141
}
142
143
borrower_add_additional_fields($borrower);
144
145
$template->param(
146
    borrowernumber => $borrowernumber,    # some templates require global
147
    borrower      => $borrower,
148
    total         => $total_due,
149
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
150
    RoutingSerials => C4::Context->preference('RoutingSerials'),
151
);
152
153
output_html_with_http_headers $input, $cookie, $template->output;
154
155
sub borrower_add_additional_fields {
156
    my $b_ref = shift;
157
158
# some borrower info is not returned in the standard call despite being assumed
159
# in a number of templates. It should not be the business of this script but in lieu of
160
# a revised api here it is ...
161
    if ( $b_ref->{category_type} eq 'C' ) {
162
        my ( $catcodes, $labels ) =
163
          GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
164
        if ( @{$catcodes} ) {
165
            if ( @{$catcodes} > 1 ) {
166
                $b_ref->{CATCODE_MULTI} = 1;
167
            } elsif ( @{$catcodes} == 1 ) {
168
                $b_ref->{catcode} = $catcodes->[0];
169
            }
170
        }
171
    } elsif ( $b_ref->{category_type} eq 'A' ) {
172
        $b_ref->{adultborrower} = 1;
173
    }
174
    my ( $picture, $dberror ) = GetPatronImage( $b_ref->{borrowernumber} );
175
    if ($picture) {
176
        $b_ref->{has_picture} = 1;
177
    }
178
179
    if (C4::Context->preference('ExtendedPatronAttributes')) {
180
        $b_ref->{extendedattributes} = GetBorrowerAttributes($borrowernumber);
181
        $template->param(
182
            ExtendedPatronAttributes => 1,
183
        );
184
    }
185
186
    # Computes full borrower address
187
    my $roadtype = C4::Koha::GetAuthorisedValueByCode( 'ROADTYPE', $borrower->{streettype} );
188
    $b_ref->{address} = $borrower->{'streetnumber'} . " $roadtype " . $borrower->{'address'};
189
190
    $b_ref->{branchname} = GetBranchName( $b_ref->{branchcode} );
191
    return;
192
}
(-)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.tt",
41
                            query => $input,
42
                            type => "intranet",
43
                            authnotrequired => 0,
44
                            flagsrequired => {borrowers => 1, updatecharges => 'remaining_permissions'},
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'} =~ /^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.tt",
38
        query           => $input,
39
        type            => "intranet",
40
        authnotrequired => 0,
41
        flagsrequired => { borrowers => 1, updatecharges => 'remaining_permissions' },
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'} =~ /^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 (-171 lines)
Lines 1-171 Link Here
1
#!/usr/bin/perl
2
#
3
# Copyright (C) 2008 LibLime
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use strict;
21
use warnings;
22
BEGIN {
23
    # find Koha's Perl modules
24
    # test carefully before changing this
25
    use FindBin;
26
    eval { require "$FindBin::Bin/../kohalib.pl" };
27
}
28
29
use C4::Context;
30
use C4::Dates;
31
use Getopt::Long;
32
use Pod::Usage;
33
34
=head1 NAME
35
36
fix_accountlines_date.pl - Fix date code in the description of fines
37
38
=head1 SYNOPSIS
39
40
fix_accountlines_date.pl -m date_format [ -n fines_to_process ] [ -d ] [ --help or -h ]
41
42
 Options:
43
   --help or -h                Brief usage message
44
   --man                       Full documentation
45
   -n fines_to_process         How many fines to process; if left off will
46
                               process all
47
   -m date_format              What format the dates are currently in; 'us'
48
                               or 'metric' (REQUIRED)
49
   -d                          Run in debugging mode
50
51
=head1 DESCRIPTION
52
53
This script fixes the date code in the description of fines. Previously, the
54
format of this was determined by which script you were using to update fines (see the -m option)
55
56
=over 8
57
58
=item B<--help>
59
60
Prints a brief usage message and exits.
61
62
=item B<--man>
63
64
Prints a full manual page and exits.
65
66
=item B<-n>
67
68
Process only a certain amount of fines. If this option is left off, this script
69
will process everything.
70
71
=item B<-m>
72
73
This required option tells the script what format your dates are currently in.
74
If you were previously using the fines2.pl or fines-sanop.pl script to update 
75
your fines, they will be in 'metric' format. If you were using the fines-ll.pl
76
script, they will be in 'us' format. After this script is finished, they will
77
be in whatever format your 'dateformat' system preference specifies.
78
79
=item B<-d>
80
81
Run in debugging mode; this prints out a lot of information and should be used
82
only if there is a problem and with the '-n' option.
83
84
=back
85
86
=cut
87
88
my $mode = '';
89
my $want_help = 0;
90
my $limit = -1;
91
my $done = 0;
92
my $DEBUG = 0;
93
94
# Regexes for the two date formats
95
our $US_DATE = '((0\d|1[0-2])\/([0-2]\d|3[01])\/(\d{4}))';
96
our $METRIC_DATE = '(([0-2]\d|3[01])\/(0\d|1[0-2])\/(\d{4}))';
97
98
sub print_usage {
99
    print <<_USAGE_
100
$0: Fix the date code in the description of fines
101
102
Due to the multiple scripts used to update fines in earlier versions of Koha,
103
this script should be used to change the format of the date codes in the
104
accountlines table before you start using Koha 3.0.
105
106
Parameters:
107
  --mode or -m        This should be 'us' or 'metric', and tells the script
108
                      what format your old dates are in.
109
  --debug or -d       Run this script in debug mode.
110
  --limit or -n       How many accountlines rows to fix; useful for testing.
111
  --help or -h        Print out this help message.
112
_USAGE_
113
}
114
115
my $result = GetOptions(
116
    'm=s' => \$mode,
117
    'd'  => \$DEBUG,
118
    'n=i'  => \$limit, 
119
    'help|h'   => \$want_help,
120
);
121
122
if (not $result or $want_help or ($mode ne 'us' and $mode ne 'metric')) {
123
    print_usage();
124
    exit 0;
125
}
126
127
our $dbh = C4::Context->dbh;
128
$dbh->{AutoCommit} = 0;
129
my $sth = $dbh->prepare("
130
SELECT borrowernumber, itemnumber, accountno, description
131
  FROM accountlines
132
  WHERE accounttype in ('FU', 'F', 'O', 'M')
133
;");
134
$sth->execute();
135
136
my $update_sth = $dbh->prepare('
137
UPDATE accountlines
138
  SET description = ?
139
  WHERE borrowernumber = ? AND itemnumber = ? AND accountno = ?
140
;');
141
142
143
while (my $accountline = $sth->fetchrow_hashref) {
144
    my $description = $accountline->{'description'};
145
    my $updated = 0;
146
147
    if ($mode eq 'us') {
148
        if ($description =~ /$US_DATE/) { # mm/dd/yyyy
149
            my $date = C4::Dates->new($1, 'us');
150
            print "Converting $1 (us) to " . $date->output() . "\n" if $DEBUG;
151
            $description =~ s/$US_DATE/$date->output()/;
152
            $updated = 1;
153
        }
154
    } elsif ($mode eq 'metric') {
155
        if ($description =~ /$METRIC_DATE/) { # dd/mm/yyyy
156
            my $date = C4::Dates->new($1, 'metric');
157
            print "Converting $1 (metric) to " . $date->output() . "\n" if $DEBUG;
158
            $description =~ s/$METRIC_DATE/$date->output()/;
159
            $updated = 2;
160
        }
161
    }
162
163
    print "Changing description from '" . $accountline->{'description'} . "' to '" . $description . "'\n" if $DEBUG;
164
    $update_sth->execute($description, $accountline->{'borrowernumber'}, $accountline->{'itemnumber'}, $accountline->{'accountno'});
165
166
    $done++;
167
168
    last if ($done == $limit); # $done can't be -1, so this works
169
}
170
171
$dbh->commit();
(-)a/reports/stats.print.pl (-178 lines)
Lines 1-178 Link Here
1
#!/usr/bin/perl
2
3
use strict;
4
#use warnings; FIXME - Bug 2505
5
use CGI;
6
use C4::Output;
7
8
use C4::Auth;
9
use C4::Context;
10
use Date::Manip;
11
use C4::Stats;
12
use Text::CSV_XS;
13
&Date_Init("DateFormat=non-US"); # set non-USA date, eg:19/08/2005
14
15
my $csv = Text::CSV_XS->new(
16
    {
17
        'quote_char'  => '"',
18
        'escape_char' => '"',
19
        'sep_char'    => ',',
20
        'binary'      => 1
21
    }
22
);
23
24
my $input=new CGI;
25
my $time=$input->param('time');
26
my $time2=$input->param('time2');
27
28
my @loop1;
29
my @loop2;
30
my $date;
31
my $date2;
32
if ($time eq 'yesterday'){
33
        $date=ParseDate('yesterday');
34
        $date2=ParseDate('today');
35
}
36
if ($time eq 'today'){
37
        $date=ParseDate('today');
38
        $date2=ParseDate('tomorrow');
39
}
40
if ($time eq 'daybefore'){
41
        $date=ParseDate('2 days ago');
42
        $date2=ParseDate('yesterday');
43
}
44
if ($time eq 'month') {
45
        $date = ParseDate('1 month ago');
46
        $date2 = ParseDate('today');
47
48
}
49
if ($time=~ /\//){
50
        $date=ParseDate($time);
51
        $date2=ParseDateDelta('+ 1 day');
52
        $date2=DateCalc($date,$date2);
53
}
54
55
if ($time eq ''){
56
        $date=ParseDate('today');
57
        $date2=ParseDate('tomorrow');
58
}
59
60
if ($time2 ne ''){
61
            $date=ParseDate($time);
62
            $date2=ParseDate($time2);
63
}
64
65
my $date=UnixDate($date,'%Y-%m-%d');
66
my $date2=UnixDate($date2,'%Y-%m-%d');
67
68
#warn "MASON: DATE: $date, $date2";
69
70
#get a list of every payment
71
my @payments=TotalPaid($date,$date2);
72
73
my $count=@payments;
74
# print "MASON: number of payments=$count\n";
75
76
my $i=0;
77
my $totalcharges=0;
78
my $totalcredits=0;
79
my $totalpaid=0;
80
my $totalwritten=0;
81
82
# lets get a a list of all individual item charges paid for by that payment
83
while ($i<$count ){
84
85
       my $count;
86
       my @charges;
87
88
       if ($payments[$i]{'type'} ne 'writeoff'){         # lets ignore writeoff payments!.
89
           @charges=getcharges($payments[$i]{'borrowernumber'}, $payments[$i]{'timestamp'}, $payments[$i]{'proccode'});
90
           $totalcharges++;
91
           $count=@charges;
92
93
           # getting each of the charges and putting them into a array to be printed out
94
           #this loops per charge per person
95
           for (my $i2=0;$i2<$count;$i2++){
96
97
               my $hour=substr($payments[$i]{'timestamp'},8,2);
98
               my $min=substr($payments[$i]{'timestamp'},10,2);
99
               my $sec=substr($payments[$i]{'timestamp'},12,2);
100
               my $time="$hour:$min:$sec";
101
               my $time2="$payments[$i]{'date'}";
102
#               my $branch=Getpaidbranch($time2,$payments[$i]{'borrowernumber'});
103
	       my $branch=$payments[$i]{'branch'};
104
105
               my @rows1 = ($branch,          # lets build up a row
106
                            $payments[$i]->{'datetime'},
107
                            $payments[$i]->{'surname'},
108
                            $payments[$i]->{'firstname'},
109
                            $charges[$i2]->{'description'},
110
                            $charges[$i2]->{'accounttype'},
111
   # rounding amounts to 2dp and adding dollar sign to make excel read it as currency format
112
                            "\$".sprintf("%.2f", $charges[$i2]->{'amount'}), 
113
                            $payments[$i]->{'type'},
114
                            "\$".$payments[$i]->{'value'});
115
116
               push (@loop1, \@rows1);
117
	       $totalpaid = $totalpaid + $payments[$i]->{'value'};
118
           }
119
       } else {
120
         ++$totalwritten;
121
       }
122
123
       $i++; #increment the while loop
124
}
125
126
#get credits and append to the bottom of payments
127
my @credits=getcredits($date,$date2);
128
129
my $count=@credits;
130
my $i=0;
131
132
while ($i<$count ){
133
134
       my @rows2 = ($credits[$i]->{'branchcode'},
135
                    $credits[$i]->{'date'},
136
                    $credits[$i]->{'surname'},
137
                    $credits[$i]->{'firstname'},
138
                    $credits[$i]->{'description'},
139
                    $credits[$i]->{'accounttype'},
140
                    "\$".$credits[$i]->{'amount'});
141
142
       push (@loop2, \@rows2);
143
       $totalcredits = $totalcredits + $credits[$i]->{'amount'};
144
       $i++;
145
}
146
147
#takes off first char minus sign "-100.00"
148
$totalcredits = substr($totalcredits, 1);
149
150
print $input->header(
151
    -type       => 'application/vnd.ms-excel',
152
    -attachment => "stats.csv",
153
);
154
print "Branch, Datetime, Surname, Firstnames, Description, Type, Invoice amount, Payment type, Payment Amount\n";
155
156
157
for my $row ( @loop1 ) {
158
159
    $csv->combine(@$row);
160
    my $string = $csv->string;
161
    print $string, "\n";
162
}
163
164
print ",,,,,,,\n";
165
166
for my $row ( @loop2 ) {
167
168
    $csv->combine(@$row);
169
    my $string = $csv->string;
170
    print $string, "\n";
171
}
172
173
print ",,,,,,,\n";
174
print ",,,,,,,\n";
175
print ",,Total Amount Paid, $totalpaid\n";
176
print ",,Total Number Written, $totalwritten\n";
177
print ",,Total Amount Credits, $totalcredits\n";
178
(-)a/reports/stats.screen.pl (-266 lines)
Lines 1-265 Link Here
1
#!/usr/bin/perl
2
3
# Copyright Katipo Communications 2006
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 CGI;
24
use C4::Output;
25
use C4::Auth;
26
use C4::Context;
27
use C4::Stats;
28
use C4::Accounts;
29
use C4::Debug;
30
use Date::Manip;
31
32
my $input = new CGI;
33
my $time  = $input->param('time');
34
my $time2 = $input->param('time2');
35
my $op    = $input->param('submit');
36
37
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
38
    {
39
        template_name   => "reports/stats_screen.tt",
40
        query           => $input,
41
        type            => "intranet",
42
        flagsrequired   => { reports => '*' },
43
    }
44
);
45
46
( $time  = "today" )    if !$time;
47
( $time2 = "tomorrow" ) if !$time2;
48
49
my $date  = ParseDate($time);
50
my $date2 = ParseDate($time2);
51
$date  = UnixDate( $date,  '%Y-%m-%d' );
52
$date2 = UnixDate( $date2, '%Y-%m-%d' );
53
$debug and warn "MASON: TIME: $time, $time2";
54
$debug and warn "MASON: DATE: $date, $date2";
55
56
# get a list of every payment
57
my @payments = TotalPaid( $date, $date2 );
58
59
my $count = @payments;
60
61
$debug and warn "MASON: number of payments=$count\n";
62
63
my $i            = 0;
64
my $totalcharges = 0;
65
my $totalcredits = 0;
66
my $totalpaid    = 0;
67
my $totalwritten = 0;
68
my @loop1;
69
my @loop2;
70
71
# lets get a a list of all individual item charges paid for by that payment
72
73
foreach my $payment (@payments) {
74
75
    my @charges;
76
    if ( $payment->{'type'} ne 'writeoff' ) {
77
78
        @charges = getcharges(
79
            $payment->{'borrowernumber'},
80
            $payment->{'timestamp'},
81
            $payment->{'proccode'}
82
        );
83
        $totalcharges++;
84
        my $count = @charges;
85
86
   # getting each of the charges and putting them into a array to be printed out
87
   #this loops per charge per person
88
        for ( my $i2 = 0 ; $i2 < $count ; $i2++ ) {
89
            my $hour = substr( $payment->{'timestamp'}, 8,  2 );
90
            my $min  = substr( $payment->{'timestamp'}, 10, 2 );
91
            my $sec  = substr( $payment->{'timestamp'}, 12, 2 );
92
            my $time = "$hour:$min:$sec";
93
            my $time2 = "$payment->{'date'}";
94
95
  #               my $branch=Getpaidbranch($time2,$payment->{'borrowernumber'});
96
            my $branch = $payment->{'branch'};
97
98
            # lets build up a row
99
            my %rows1 = (
100
                branch      => $branch,
101
                datetime    => $payment->{'datetime'},
102
                surname     => $payment->{'surname'},
103
                firstname   => $payment->{'firstname'},
104
                description => $charges[$i2]->{'description'},
105
                accounttype => $charges[$i2]->{'accounttype'},
106
                amount      => sprintf( "%.2f", $charges[$i2]->{'amount'} )
107
                ,    # rounding amounts to 2dp
108
                type  => $payment->{'type'},
109
                value => sprintf( "%.2f", $payment->{'value'} )
110
            );       # rounding amounts to 2dp
111
112
            push( @loop1, \%rows1 );
113
114
        }
115
            $totalpaid = $totalpaid + $payment->{'value'};
116
			$debug and warn "totalpaid = $totalpaid";		
117
    }
118
    else {
119
        ++$totalwritten;
120
    }
121
122
}
123
124
#get credits and append to the bottom of payments
125
my @credits = getcredits( $date, $date2 );
126
127
my $count = @credits;
128
my $i     = 0;
129
130
while ( $i < $count ) {
131
132
    my %rows2 = (
133
        creditbranch      => $credits[$i]->{'branchcode'},
134
        creditdate        => $credits[$i]->{'date'},
135
        creditsurname     => $credits[$i]->{'surname'},
136
        creditfirstname   => $credits[$i]->{'firstname'},
137
        creditdescription => $credits[$i]->{'description'},
138
        creditaccounttype => $credits[$i]->{'accounttype'},
139
        creditamount      => sprintf( "%.2f", $credits[$i]->{'amount'} )
140
    );
141
142
    push( @loop2, \%rows2 );
143
    $totalcredits = $totalcredits + $credits[$i]->{'amount'};
144
    $i++;    #increment the while loop
145
}
146
147
#takes off first char minus sign "-100.00"
148
$totalcredits = substr( $totalcredits, 1 );
149
150
my $totalrefunds = 0;
151
my @loop3;
152
my @refunds = getrefunds( $date, $date2 );
153
$count = @refunds;
154
$i     = 0;
155
156
while ( $i < $count ) {
157
158
    my %rows3 = (
159
        refundbranch      => $refunds[$i]->{'branchcode'},
160
        refunddate        => $refunds[$i]->{'datetime'},
161
        refundsurname     => $refunds[$i]->{'surname'},
162
        refundfirstname   => $refunds[$i]->{'firstname'},
163
        refunddescription => $refunds[$i]->{'description'},
164
        refundaccounttype => $refunds[$i]->{'accounttype'},
165
        refundamount      => sprintf( "%.2f", $refunds[$i]->{'amount'} )
166
    );
167
168
    push( @loop3, \%rows3 );
169
    $totalrefunds = $totalrefunds + $refunds[$i]->{'amount'};
170
    $i++;    #increment the while loop
171
}
172
173
my $totalcash = $totalpaid - $totalrefunds;
174
175
if ( $op eq 'To Excel' ) {
176
177
    my $csv = Text::CSV_XS->new(
178
        {
179
            'quote_char'  => '"',
180
            'escape_char' => '"',
181
            'sep_char'    => ',',
182
            'binary'      => 1
183
        }
184
    );
185
186
    print $input->header(
187
        -type       => 'application/vnd.ms-excel',
188
        -attachment => "stats.csv",
189
    );
190
    print
191
"Branch, Datetime, Surname, Firstnames, Description, Type, Invoice amount, Payment type, Payment Amount\n";
192
193
    $DB::single = 1;
194
195
    for my $row (@loop1) {
196
        my @array = (
197
            $row->{'branch'},      $row->{'datetime'},
198
            $row->{'surname'},     $row->{'firstname'},
199
            $row->{'description'}, $row->{'accounttype'},
200
            $row->{'amount'},      $row->{'type'},
201
            $row->{'value'}
202
        );
203
204
        $csv->combine(@array);
205
        my $string = $csv->string(@array);
206
        print $string, "\n";
207
    }
208
    print ",,,,,,,\n";
209
    print
210
"Branch, Date/time, Surname, Firstname, Description, Charge Type, Invoice Amount\n";
211
212
    for my $row (@loop2) {
213
214
        my @array = (
215
            $row->{'creditbranch'},      $row->{'creditdate'},
216
            $row->{'creditsurname'},     $row->{'creditfirstname'},
217
            $row->{'creditdescription'}, $row->{'creditaccounttype'},
218
            $row->{'creditamount'}
219
        );
220
221
        $csv->combine(@array);
222
        my $string = $csv->string(@array);
223
        print $string, "\n";
224
    }
225
    print ",,,,,,,\n";
226
    print
227
"Branch, Date/time, Surname, Firstname, Description, Charge Type, Invoice Amount\n";
228
229
    for my $row (@loop3) {
230
        my @array = (
231
            $row->{'refundbranch'},      $row->{'refunddate'},
232
            $row->{'refundsurname'},     $row->{'refundfirstname'},
233
            $row->{'refunddescription'}, $row->{'refundaccounttype'},
234
            $row->{'refundamount'}
235
        );
236
237
        $csv->combine(@array);
238
        my $string = $csv->string(@array);
239
        print $string, "\n";
240
241
    }
242
243
    print ",,,,,,,\n";
244
    print ",,,,,,,\n";
245
    print ",,Total Amount Paid, $totalpaid\n";
246
    print ",,Total Number Written, $totalwritten\n";
247
    print ",,Total Amount Credits, $totalcredits\n";
248
    print ",,Total Amount Refunds, $totalrefunds\n";
249
}
250
else {
251
    $template->param(
252
        date         => $time,
253
        date2        => $time2,
254
        loop1        => \@loop1,
255
        loop2        => \@loop2,
256
        loop3        => \@loop3,
257
        totalpaid    => $totalpaid,
258
        totalcredits => $totalcredits,
259
        totalwritten => $totalwritten,
260
        totalrefund  => $totalrefunds,
261
        totalcash    => $totalcash,
262
    );
263
    output_html_with_http_headers $input, $cookie, $template->output;
264
}
265
266
- 

Return to bug 6427