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

(-)a/C4/Accounts.pm (-810 lines)
Lines 1-810 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( $branch, 'payment', $data, '', '', '', $borrowernumber, $nextaccntno );
159
160
    if ( C4::Context->preference("FinesLog") ) {
161
        $accdata->{'amountoutstanding_new'} = $newamtos;
162
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
163
            action            => 'create_payment',
164
            borrowernumber    => $borrowernumber,
165
            accountno         => $nextaccntno,
166
            amount            => $data * -1,
167
            amountoutstanding => $amountleft * -1,
168
            accounttype       => 'Pay',
169
            accountlines_paid => \@ids,
170
            manager_id        => $manager_id,
171
        }));
172
    }
173
174
}
175
176
=head2 makepayment
177
178
  &makepayment($accountlines_id, $borrowernumber, $acctnumber, $amount, $branchcode);
179
180
Records the fact that a patron has paid off the entire amount he or
181
she owes.
182
183
C<$borrowernumber> is the patron's borrower number. C<$acctnumber> is
184
the account that was credited. C<$amount> is the amount paid (this is
185
only used to record the payment. It is assumed to be equal to the
186
amount owed). C<$branchcode> is the code of the branch where payment
187
was made.
188
189
=cut
190
191
#'
192
# FIXME - I'm not at all sure about the above, because I don't
193
# understand what the acct* tables in the Koha database are for.
194
sub makepayment {
195
196
    #here we update both the accountoffsets and the account lines
197
    #updated to check, if they are paying off a lost item, we return the item
198
    # from their card, and put a note on the item record
199
    my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
200
    my $dbh = C4::Context->dbh;
201
    my $manager_id = 0;
202
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv; 
203
204
    # begin transaction
205
    my $nextaccntno = getnextacctno($borrowernumber);
206
    my $newamtos    = 0;
207
    my $sth         = $dbh->prepare("SELECT * FROM accountlines WHERE accountlines_id=?");
208
    $sth->execute( $accountlines_id );
209
    my $data = $sth->fetchrow_hashref;
210
211
    my $payment;
212
    if ( $data->{'accounttype'} eq "Pay" ){
213
        my $udp = 		
214
            $dbh->prepare(
215
                "UPDATE accountlines
216
                    SET amountoutstanding = 0
217
                    WHERE accountlines_id = ?
218
                "
219
            );
220
        $udp->execute($accountlines_id);
221
    }else{
222
        my $udp = 		
223
            $dbh->prepare(
224
                "UPDATE accountlines
225
                    SET amountoutstanding = 0
226
                    WHERE accountlines_id = ?
227
                "
228
            );
229
        $udp->execute($accountlines_id);
230
231
         # create new line
232
        my $payment = 0 - $amount;
233
        $payment_note //= "";
234
        
235
        my $ins = 
236
            $dbh->prepare( 
237
                "INSERT 
238
                    INTO accountlines (borrowernumber, accountno, date, amount, itemnumber, description, accounttype, amountoutstanding, manager_id, note)
239
                    VALUES ( ?, ?, now(), ?, ?, '', 'Pay', 0, ?, ?)"
240
            );
241
        $ins->execute($borrowernumber, $nextaccntno, $payment, $data->{'itemnumber'}, $manager_id, $payment_note);
242
    }
243
244
    if ( C4::Context->preference("FinesLog") ) {
245
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
246
            action                => 'fee_payment',
247
            borrowernumber        => $borrowernumber,
248
            old_amountoutstanding => $data->{'amountoutstanding'},
249
            new_amountoutstanding => 0,
250
            amount_paid           => $data->{'amountoutstanding'},
251
            accountlines_id       => $data->{'accountlines_id'},
252
            accountno             => $data->{'accountno'},
253
            manager_id            => $manager_id,
254
        }));
255
256
257
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
258
            action            => 'create_payment',
259
            borrowernumber    => $borrowernumber,
260
            accountno         => $nextaccntno,
261
            amount            => $payment,
262
            amountoutstanding => 0,,
263
            accounttype       => 'Pay',
264
            accountlines_paid => [$data->{'accountlines_id'}],
265
            manager_id        => $manager_id,
266
        }));
267
    }
268
269
270
    # FIXME - The second argument to &UpdateStats is supposed to be the
271
    # branch code.
272
    # UpdateStats is now being passed $accountno too. MTJ
273
    UpdateStats( $user, 'payment', $amount, '', '', '', $borrowernumber,
274
        $accountno );
275
276
    #check to see what accounttype
277
    if ( $data->{'accounttype'} eq 'Rep' || $data->{'accounttype'} eq 'L' ) {
278
        C4::Circulation::ReturnLostItem( $borrowernumber, $data->{'itemnumber'} );
279
    }
280
    my $sthr = $dbh->prepare("SELECT max(accountlines_id) AS lastinsertid FROM accountlines");
281
    $sthr->execute();
282
    my $datalastinsertid = $sthr->fetchrow_hashref;
283
    return $datalastinsertid->{'lastinsertid'};
284
}
285
286
=head2 getnextacctno
287
288
  $nextacct = &getnextacctno($borrowernumber);
289
290
Returns the next unused account number for the patron with the given
291
borrower number.
292
293
=cut
294
295
#'
296
# FIXME - Okay, so what does the above actually _mean_?
297
sub getnextacctno {
298
    my ($borrowernumber) = shift or return;
299
    my $sth = C4::Context->dbh->prepare(
300
        "SELECT accountno+1 FROM accountlines
301
            WHERE    (borrowernumber = ?)
302
            ORDER BY accountno DESC
303
            LIMIT 1"
304
    );
305
    $sth->execute($borrowernumber);
306
    return ($sth->fetchrow || 1);
307
}
308
309
=head2 fixaccounts (removed)
310
311
  &fixaccounts($accountlines_id, $borrowernumber, $accountnumber, $amount);
312
313
#'
314
# FIXME - I don't understand what this function does.
315
sub fixaccounts {
316
    my ( $accountlines_id, $borrowernumber, $accountno, $amount ) = @_;
317
    my $dbh = C4::Context->dbh;
318
    my $sth = $dbh->prepare(
319
        "SELECT * FROM accountlines WHERE accountlines_id=?"
320
    );
321
    $sth->execute( $accountlines_id );
322
    my $data = $sth->fetchrow_hashref;
323
324
    # FIXME - Error-checking
325
    my $diff        = $amount - $data->{'amount'};
326
    my $outstanding = $data->{'amountoutstanding'} + $diff;
327
    $sth->finish;
328
329
    $dbh->do(<<EOT);
330
        UPDATE  accountlines
331
        SET     amount = '$amount',
332
                amountoutstanding = '$outstanding'
333
        WHERE   accountlines_id = $accountlines_id
334
EOT
335
	# FIXME: exceedingly bad form.  Use prepare with placholders ("?") in query and execute args.
336
}
337
338
=cut
339
340
sub chargelostitem{
341
# lost ==1 Lost, lost==2 longoverdue, lost==3 lost and paid for
342
# FIXME: itemlost should be set to 3 after payment is made, should be a warning to the interface that
343
# a charge has been added
344
# FIXME : if no replacement price, borrower just doesn't get charged?
345
    my $dbh = C4::Context->dbh();
346
    my ($borrowernumber, $itemnumber, $amount, $description) = @_;
347
348
    # first make sure the borrower hasn't already been charged for this item
349
    my $sth1=$dbh->prepare("SELECT * from accountlines
350
    WHERE borrowernumber=? AND itemnumber=? and accounttype='L'");
351
    $sth1->execute($borrowernumber,$itemnumber);
352
    my $existing_charge_hashref=$sth1->fetchrow_hashref();
353
354
    # OK, they haven't
355
    unless ($existing_charge_hashref) {
356
        my $manager_id = 0;
357
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
358
        # This item is on issue ... add replacement cost to the borrower's record and mark it returned
359
        #  Note that we add this to the account even if there's no replacement price, allowing some other
360
        #  process (or person) to update it, since we don't handle any defaults for replacement prices.
361
        my $accountno = getnextacctno($borrowernumber);
362
        my $sth2=$dbh->prepare("INSERT INTO accountlines
363
        (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding,itemnumber,manager_id)
364
        VALUES (?,?,now(),?,?,'L',?,?,?)");
365
        $sth2->execute($borrowernumber,$accountno,$amount,
366
        $description,$amount,$itemnumber,$manager_id);
367
368
        if ( C4::Context->preference("FinesLog") ) {
369
            logaction("FINES", 'CREATE', $borrowernumber, Dumper({
370
                action            => 'create_fee',
371
                borrowernumber    => $borrowernumber,
372
                accountno         => $accountno,
373
                amount            => $amount,
374
                amountoutstanding => $amount,
375
                description       => $description,
376
                accounttype       => 'L',
377
                itemnumber        => $itemnumber,
378
                manager_id        => $manager_id,
379
            }));
380
        }
381
382
    }
383
}
384
385
=head2 manualinvoice
386
387
  &manualinvoice($borrowernumber, $itemnumber, $description, $type,
388
                 $amount, $note);
389
390
C<$borrowernumber> is the patron's borrower number.
391
C<$description> is a description of the transaction.
392
C<$type> may be one of C<CS>, C<CB>, C<CW>, C<CF>, C<CL>, C<N>, C<L>,
393
or C<REF>.
394
C<$itemnumber> is the item involved, if pertinent; otherwise, it
395
should be the empty string.
396
397
=cut
398
399
#'
400
# FIXME: In Koha 3.0 , the only account adjustment 'types' passed to this function
401
# are :  
402
# 		'C' = CREDIT
403
# 		'FOR' = FORGIVEN  (Formerly 'F', but 'F' is taken to mean 'FINE' elsewhere)
404
# 		'N' = New Card fee
405
# 		'F' = Fine
406
# 		'A' = Account Management fee
407
# 		'M' = Sundry
408
# 		'L' = Lost Item
409
#
410
411
sub manualinvoice {
412
    my ( $borrowernumber, $itemnum, $desc, $type, $amount, $note ) = @_;
413
    my $manager_id = 0;
414
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
415
    my $dbh      = C4::Context->dbh;
416
    my $notifyid = 0;
417
    my $insert;
418
    my $accountno  = getnextacctno($borrowernumber);
419
    my $amountleft = $amount;
420
421
    if (   ( $type eq 'L' )
422
        or ( $type eq 'F' )
423
        or ( $type eq 'A' )
424
        or ( $type eq 'N' )
425
        or ( $type eq 'M' ) )
426
    {
427
        $notifyid = 1;
428
    }
429
430
    if ( $itemnum ) {
431
        $desc .= ' ' . $itemnum;
432
        my $sth = $dbh->prepare(
433
            'INSERT INTO  accountlines
434
                        (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber,notify_id, note, manager_id)
435
        VALUES (?, ?, now(), ?,?, ?,?,?,?,?,?)');
436
     $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $itemnum,$notifyid, $note, $manager_id) || return $sth->errstr;
437
  } else {
438
    my $sth=$dbh->prepare("INSERT INTO  accountlines
439
            (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding,notify_id, note, manager_id)
440
            VALUES (?, ?, now(), ?, ?, ?, ?,?,?,?)"
441
        );
442
        $sth->execute( $borrowernumber, $accountno, $amount, $desc, $type,
443
            $amountleft, $notifyid, $note, $manager_id );
444
    }
445
446
    if ( C4::Context->preference("FinesLog") ) {
447
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
448
            action            => 'create_fee',
449
            borrowernumber    => $borrowernumber,
450
            accountno         => $accountno,
451
            amount            => $amount,
452
            description       => $desc,
453
            accounttype       => $type,
454
            amountoutstanding => $amountleft,
455
            notify_id         => $notifyid,
456
            note              => $note,
457
            itemnumber        => $itemnum,
458
            manager_id        => $manager_id,
459
        }));
460
    }
461
462
    return 0;
463
}
464
465
sub getcharges {
466
	my ( $borrowerno, $timestamp, $accountno ) = @_;
467
	my $dbh        = C4::Context->dbh;
468
	my $timestamp2 = $timestamp - 1;
469
	my $query      = "";
470
	my $sth = $dbh->prepare(
471
			"SELECT * FROM accountlines WHERE borrowernumber=? AND accountno = ?"
472
          );
473
	$sth->execute( $borrowerno, $accountno );
474
	
475
    my @results;
476
    while ( my $data = $sth->fetchrow_hashref ) {
477
		push @results,$data;
478
	}
479
    return (@results);
480
}
481
482
sub ModNote {
483
    my ( $accountlines_id, $note ) = @_;
484
    my $dbh = C4::Context->dbh;
485
    my $sth = $dbh->prepare('UPDATE accountlines SET note = ? WHERE accountlines_id = ?');
486
    $sth->execute( $note, $accountlines_id );
487
}
488
489
sub getcredits {
490
	my ( $date, $date2 ) = @_;
491
	my $dbh = C4::Context->dbh;
492
	my $sth = $dbh->prepare(
493
			        "SELECT * FROM accountlines,borrowers
494
      WHERE amount < 0 AND accounttype not like 'Pay%' AND accountlines.borrowernumber = borrowers.borrowernumber
495
	  AND timestamp >=TIMESTAMP(?) AND timestamp < TIMESTAMP(?)"
496
      );  
497
498
    $sth->execute( $date, $date2 );                                                                                                              
499
    my @results;          
500
    while ( my $data = $sth->fetchrow_hashref ) {
501
		$data->{'date'} = $data->{'timestamp'};
502
		push @results,$data;
503
	}
504
    return (@results);
505
} 
506
507
508
sub getrefunds {
509
	my ( $date, $date2 ) = @_;
510
	my $dbh = C4::Context->dbh;
511
	
512
	my $sth = $dbh->prepare(
513
			        "SELECT *,timestamp AS datetime                                                                                      
514
                  FROM accountlines,borrowers
515
                  WHERE (accounttype = 'REF'
516
					  AND accountlines.borrowernumber = borrowers.borrowernumber
517
					                  AND date  >=?  AND date  <?)"
518
    );
519
520
    $sth->execute( $date, $date2 );
521
522
    my @results;
523
    while ( my $data = $sth->fetchrow_hashref ) {
524
		push @results,$data;
525
		
526
	}
527
    return (@results);
528
}
529
530
sub ReversePayment {
531
    my ( $accountlines_id ) = @_;
532
    my $dbh = C4::Context->dbh;
533
534
    my $sth = $dbh->prepare('SELECT * FROM accountlines WHERE accountlines_id = ?');
535
    $sth->execute( $accountlines_id );
536
    my $row = $sth->fetchrow_hashref();
537
    my $amount_outstanding = $row->{'amountoutstanding'};
538
539
    if ( $amount_outstanding <= 0 ) {
540
        $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = amount * -1, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
541
        $sth->execute( $accountlines_id );
542
    } else {
543
        $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = 0, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
544
        $sth->execute( $accountlines_id );
545
    }
546
547
    if ( C4::Context->preference("FinesLog") ) {
548
        my $manager_id = 0;
549
        $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
550
551
        if ( $amount_outstanding <= 0 ) {
552
            $row->{'amountoutstanding'} *= -1;
553
        } else {
554
            $row->{'amountoutstanding'} = '0';
555
        }
556
        $row->{'description'} .= ' Reversed -';
557
        logaction("FINES", 'MODIFY', $row->{'borrowernumber'}, Dumper({
558
            action                => 'reverse_fee_payment',
559
            borrowernumber        => $row->{'borrowernumber'},
560
            old_amountoutstanding => $row->{'amountoutstanding'},
561
            new_amountoutstanding => 0 - $amount_outstanding,,
562
            accountlines_id       => $row->{'accountlines_id'},
563
            accountno             => $row->{'accountno'},
564
            manager_id            => $manager_id,
565
        }));
566
567
    }
568
569
}
570
571
=head2 recordpayment_selectaccts
572
573
  recordpayment_selectaccts($borrowernumber, $payment,$accts);
574
575
Record payment by a patron. C<$borrowernumber> is the patron's
576
borrower number. C<$payment> is a floating-point number, giving the
577
amount that was paid. C<$accts> is an array ref to a list of
578
accountnos which the payment can be recorded against
579
580
Amounts owed are paid off oldest first. That is, if the patron has a
581
$1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
582
of $1.50, then the oldest fine will be paid off in full, and $0.50
583
will be credited to the next one.
584
585
=cut
586
587
sub recordpayment_selectaccts {
588
    my ( $borrowernumber, $amount, $accts, $note ) = @_;
589
590
    my $dbh        = C4::Context->dbh;
591
    my $newamtos   = 0;
592
    my $accdata    = q{};
593
    my $branch     = C4::Context->userenv->{branch};
594
    my $amountleft = $amount;
595
    my $manager_id = 0;
596
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
597
    my $sql = 'SELECT * FROM accountlines WHERE (borrowernumber = ?) ' .
598
    'AND (amountoutstanding<>0) ';
599
    if (@{$accts} ) {
600
        $sql .= ' AND accountno IN ( ' .  join ',', @{$accts};
601
        $sql .= ' ) ';
602
    }
603
    $sql .= ' ORDER BY date';
604
    # begin transaction
605
    my $nextaccntno = getnextacctno($borrowernumber);
606
607
    # get lines with outstanding amounts to offset
608
    my $rows = $dbh->selectall_arrayref($sql, { Slice => {} }, $borrowernumber);
609
610
    # offset transactions
611
    my $sth     = $dbh->prepare('UPDATE accountlines SET amountoutstanding= ? ' .
612
        'WHERE accountlines_id=?');
613
614
    my @ids;
615
    for my $accdata ( @{$rows} ) {
616
        if ($amountleft == 0) {
617
            last;
618
        }
619
        if ( $accdata->{amountoutstanding} < $amountleft ) {
620
            $newamtos = 0;
621
            $amountleft -= $accdata->{amountoutstanding};
622
        }
623
        else {
624
            $newamtos   = $accdata->{amountoutstanding} - $amountleft;
625
            $amountleft = 0;
626
        }
627
        my $thisacct = $accdata->{accountlines_id};
628
        $sth->execute( $newamtos, $thisacct );
629
630
        if ( C4::Context->preference("FinesLog") ) {
631
            logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
632
                action                => 'fee_payment',
633
                borrowernumber        => $borrowernumber,
634
                old_amountoutstanding => $accdata->{'amountoutstanding'},
635
                new_amountoutstanding => $newamtos,
636
                amount_paid           => $accdata->{'amountoutstanding'} - $newamtos,
637
                accountlines_id       => $accdata->{'accountlines_id'},
638
                accountno             => $accdata->{'accountno'},
639
                manager_id            => $manager_id,
640
            }));
641
            push( @ids, $accdata->{'accountlines_id'} );
642
        }
643
644
    }
645
646
    # create new line
647
    $sql = 'INSERT INTO accountlines ' .
648
    '(borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding,manager_id,note) ' .
649
    q|VALUES (?,?,now(),?,'','Pay',?,?,?)|;
650
    $dbh->do($sql,{},$borrowernumber, $nextaccntno, 0 - $amount, 0 - $amountleft, $manager_id, $note );
651
    UpdateStats( $branch, 'payment', $amount, '', '', '', $borrowernumber, $nextaccntno );
652
653
    if ( C4::Context->preference("FinesLog") ) {
654
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
655
            action            => 'create_payment',
656
            borrowernumber    => $borrowernumber,
657
            accountno         => $nextaccntno,
658
            amount            => 0 - $amount,
659
            amountoutstanding => 0 - $amountleft,
660
            accounttype       => 'Pay',
661
            accountlines_paid => \@ids,
662
            manager_id        => $manager_id,
663
        }));
664
    }
665
666
    return;
667
}
668
669
# makepayment needs to be fixed to handle partials till then this separate subroutine
670
# fills in
671
sub makepartialpayment {
672
    my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
673
    my $manager_id = 0;
674
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
675
    if (!$amount || $amount < 0) {
676
        return;
677
    }
678
    $payment_note //= "";
679
    my $dbh = C4::Context->dbh;
680
681
    my $nextaccntno = getnextacctno($borrowernumber);
682
    my $newamtos    = 0;
683
684
    my $data = $dbh->selectrow_hashref(
685
        'SELECT * FROM accountlines WHERE  accountlines_id=?',undef,$accountlines_id);
686
    my $new_outstanding = $data->{amountoutstanding} - $amount;
687
688
    my $update = 'UPDATE  accountlines SET amountoutstanding = ?  WHERE   accountlines_id = ? ';
689
    $dbh->do( $update, undef, $new_outstanding, $accountlines_id);
690
691
    if ( C4::Context->preference("FinesLog") ) {
692
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
693
            action                => 'fee_payment',
694
            borrowernumber        => $borrowernumber,
695
            old_amountoutstanding => $data->{'amountoutstanding'},
696
            new_amountoutstanding => $new_outstanding,
697
            amount_paid           => $data->{'amountoutstanding'} - $new_outstanding,
698
            accountlines_id       => $data->{'accountlines_id'},
699
            accountno             => $data->{'accountno'},
700
            manager_id            => $manager_id,
701
        }));
702
    }
703
704
    # create new line
705
    my $insert = 'INSERT INTO accountlines (borrowernumber, accountno, date, amount, '
706
    .  'description, accounttype, amountoutstanding, itemnumber, manager_id, note) '
707
    . ' VALUES (?, ?, now(), ?, ?, ?, 0, ?, ?, ?)';
708
709
    $dbh->do(  $insert, undef, $borrowernumber, $nextaccntno, $amount,
710
        "Payment, thanks - $user", 'Pay', $data->{'itemnumber'}, $manager_id, $payment_note);
711
712
    UpdateStats( $user, 'payment', $amount, '', '', '', $borrowernumber, $accountno );
713
714
    if ( C4::Context->preference("FinesLog") ) {
715
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
716
            action            => 'create_payment',
717
            borrowernumber    => $user,
718
            accountno         => $nextaccntno,
719
            amount            => 0 - $amount,
720
            accounttype       => 'Pay',
721
            itemnumber        => $data->{'itemnumber'},
722
            accountlines_paid => [ $data->{'accountlines_id'} ],
723
            manager_id        => $manager_id,
724
        }));
725
    }
726
727
    return;
728
}
729
730
=head2 WriteOffFee
731
732
  WriteOffFee( $borrowernumber, $accountline_id, $itemnum, $accounttype, $amount, $branch, $payment_note );
733
734
Write off a fine for a patron.
735
C<$borrowernumber> is the patron's borrower number.
736
C<$accountline_id> is the accountline_id of the fee to write off.
737
C<$itemnum> is the itemnumber of of item whose fine is being written off.
738
C<$accounttype> is the account type of the fine being written off.
739
C<$amount> is a floating-point number, giving the amount that is being written off.
740
C<$branch> is the branchcode of the library where the writeoff occurred.
741
C<$payment_note> is the note to attach to this payment
742
743
=cut
744
745
sub WriteOffFee {
746
    my ( $borrowernumber, $accountlines_id, $itemnum, $accounttype, $amount, $branch, $payment_note ) = @_;
747
    $payment_note //= "";
748
    $branch ||= C4::Context->userenv->{branch};
749
    my $manager_id = 0;
750
    $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
751
752
    # if no item is attached to fine, make sure to store it as a NULL
753
    $itemnum ||= undef;
754
755
    my ( $sth, $query );
756
    my $dbh = C4::Context->dbh();
757
758
    $query = "
759
        UPDATE accountlines SET amountoutstanding = 0
760
        WHERE accountlines_id = ? AND borrowernumber = ?
761
    ";
762
    $sth = $dbh->prepare( $query );
763
    $sth->execute( $accountlines_id, $borrowernumber );
764
765
    if ( C4::Context->preference("FinesLog") ) {
766
        logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
767
            action                => 'fee_writeoff',
768
            borrowernumber        => $borrowernumber,
769
            accountlines_id       => $accountlines_id,
770
            manager_id            => $manager_id,
771
        }));
772
    }
773
774
    $query ="
775
        INSERT INTO accountlines
776
        ( borrowernumber, accountno, itemnumber, date, amount, description, accounttype, manager_id, note )
777
        VALUES ( ?, ?, ?, NOW(), ?, 'Writeoff', 'W', ?, ? )
778
    ";
779
    $sth = $dbh->prepare( $query );
780
    my $acct = getnextacctno($borrowernumber);
781
    $sth->execute( $borrowernumber, $acct, $itemnum, $amount, $manager_id, $payment_note );
782
783
    if ( C4::Context->preference("FinesLog") ) {
784
        logaction("FINES", 'CREATE',$borrowernumber,Dumper({
785
            action            => 'create_writeoff',
786
            borrowernumber    => $borrowernumber,
787
            accountno         => $acct,
788
            amount            => 0 - $amount,
789
            accounttype       => 'W',
790
            itemnumber        => $itemnum,
791
            accountlines_paid => [ $accountlines_id ],
792
            manager_id        => $manager_id,
793
        }));
794
    }
795
796
    UpdateStats( $branch, 'writeoff', $amount, q{}, q{}, q{}, $borrowernumber );
797
798
}
799
800
END { }    # module clean-up code here (global destructor)
801
802
1;
803
__END__
804
805
=head1 SEE ALSO
806
807
DBI(3)
808
809
=cut
810
(-)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.tmpl",
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; Borrowers &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; Borrowers &rsaquo; Create manual invoice</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
<script type="text/javascript">
5
//<![CDATA[
6
$(document).ready(function(){
7
        $('#maninvoice').preventDoubleFormSubmit();
8
        $("fieldset.rows input, 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 (-135 lines)
Lines 1-135 Link Here
1
#!/usr/bin/perl
2
3
4
#writen 11/1/2000 by chris@katipo.oc.nz
5
#script to display borrowers account details
6
7
8
# Copyright 2000-2002 Katipo Communications
9
#
10
# This file is part of Koha.
11
#
12
# Koha is free software; you can redistribute it and/or modify it under the
13
# terms of the GNU General Public License as published by the Free Software
14
# Foundation; either version 2 of the License, or (at your option) any later
15
# version.
16
#
17
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License along
22
# with Koha; if not, write to the Free Software Foundation, Inc.,
23
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25
use strict;
26
use warnings;
27
28
use C4::Auth;
29
use C4::Output;
30
use C4::Dates qw/format_date/;
31
use CGI;
32
use C4::Members;
33
use C4::Branch;
34
use C4::Accounts;
35
use C4::Members::Attributes qw(GetBorrowerAttributes);
36
37
my $input=new CGI;
38
39
40
my ($template, $loggedinuser, $cookie)
41
    = get_template_and_user({template_name => "members/boraccount.tmpl",
42
                            query => $input,
43
                            type => "intranet",
44
                            authnotrequired => 0,
45
                            flagsrequired => {borrowers => 1, updatecharges => 'remaining_permissions'},
46
                            debug => 1,
47
                            });
48
49
my $borrowernumber=$input->param('borrowernumber');
50
my $action = $input->param('action') || '';
51
52
#get borrower details
53
my $data=GetMember('borrowernumber' => $borrowernumber);
54
55
if ( $action eq 'reverse' ) {
56
  ReversePayment( $input->param('accountlines_id') );
57
}
58
59
if ( $data->{'category_type'} eq 'C') {
60
   my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
61
   my $cnt = scalar(@$catcodes);
62
   $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
63
   $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
64
}
65
66
#get account details
67
my ($total,$accts,undef)=GetMemberAccountRecords($borrowernumber);
68
my $totalcredit;
69
if($total <= 0){
70
        $totalcredit = 1;
71
}
72
73
my $reverse_col = 0; # Flag whether we need to show the reverse column
74
foreach my $accountline ( @{$accts}) {
75
    $accountline->{amount} += 0.00;
76
    if ($accountline->{amount} <= 0 ) {
77
        $accountline->{amountcredit} = 1;
78
    }
79
    $accountline->{amountoutstanding} += 0.00;
80
    if ( $accountline->{amountoutstanding} <= 0 ) {
81
        $accountline->{amountoutstandingcredit} = 1;
82
    }
83
84
    $accountline->{date} = format_date($accountline->{date});
85
    $accountline->{amount} = sprintf '%.2f', $accountline->{amount};
86
    $accountline->{amountoutstanding} = sprintf '%.2f', $accountline->{amountoutstanding};
87
    if ($accountline->{accounttype} =~ /^Pay/) {
88
        $accountline->{payment} = 1;
89
        $reverse_col = 1;
90
    }
91
}
92
93
$template->param( adultborrower => 1 ) if ( $data->{'category_type'} eq 'A' );
94
95
my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
96
$template->param( picture => 1 ) if $picture;
97
98
if (C4::Context->preference('ExtendedPatronAttributes')) {
99
    my $attributes = GetBorrowerAttributes($borrowernumber);
100
    $template->param(
101
        ExtendedPatronAttributes => 1,
102
        extendedattributes => $attributes
103
    );
104
}
105
106
$template->param(
107
    finesview           => 1,
108
    firstname           => $data->{'firstname'},
109
    surname             => $data->{'surname'},
110
    othernames          => $data->{'othernames'},
111
    borrowernumber      => $borrowernumber,
112
    cardnumber          => $data->{'cardnumber'},
113
    categorycode        => $data->{'categorycode'},
114
    category_type       => $data->{'category_type'},
115
    categoryname		=> $data->{'description'},
116
    address             => $data->{'address'},
117
    address2            => $data->{'address2'},
118
    city                => $data->{'city'},
119
    state               => $data->{'state'},
120
    zipcode             => $data->{'zipcode'},
121
    country             => $data->{'country'},
122
    phone               => $data->{'phone'},
123
    email               => $data->{'email'},
124
    branchcode          => $data->{'branchcode'},
125
	branchname			=> GetBranchName($data->{'branchcode'}),
126
    total               => sprintf("%.2f",$total),
127
    totalcredit         => $totalcredit,
128
    is_child            => ($data->{'category_type'} eq 'C'),
129
    reverse_col         => $reverse_col,
130
    accounts            => $accts,
131
	activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
132
    RoutingSerials => C4::Context->preference('RoutingSerials'),
133
);
134
135
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/members/mancredit.pl (-115 lines)
Lines 1-115 Link Here
1
#!/usr/bin/perl
2
3
#written 11/1/2000 by chris@katipo.oc.nz
4
#script to display borrowers account details
5
6
7
# Copyright 2000-2002 Katipo Communications
8
# Copyright 2010 BibLibre
9
#
10
# This file is part of Koha.
11
#
12
# Koha is free software; you can redistribute it and/or modify it under the
13
# terms of the GNU General Public License as published by the Free Software
14
# Foundation; either version 2 of the License, or (at your option) any later
15
# version.
16
#
17
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License along
22
# with Koha; if not, write to the Free Software Foundation, Inc.,
23
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25
use strict;
26
use warnings;
27
28
use C4::Auth;
29
use C4::Output;
30
use CGI;
31
32
use C4::Members;
33
use C4::Branch;
34
use C4::Accounts;
35
use C4::Items;
36
use C4::Members::Attributes qw(GetBorrowerAttributes);
37
38
my $input=new CGI;
39
my $flagsrequired = { borrowers => 1, updatecharges => 1 };
40
41
my $borrowernumber=$input->param('borrowernumber');
42
43
#get borrower details
44
my $data=GetMember('borrowernumber' => $borrowernumber);
45
my $add=$input->param('add');
46
47
if ($add){
48
    if ( checkauth( $input, 0, $flagsrequired, 'intranet' ) ) {
49
        my $barcode = $input->param('barcode');
50
        my $itemnum;
51
        if ($barcode) {
52
            $itemnum = GetItemnumberFromBarcode($barcode);
53
        }
54
        my $desc    = $input->param('desc');
55
        my $note    = $input->param('note');
56
        my $amount  = $input->param('amount') || 0;
57
        $amount = -$amount;
58
        my $type = $input->param('type');
59
        manualinvoice( $borrowernumber, $itemnum, $desc, $type, $amount, $note );
60
        print $input->redirect("/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber");
61
    }
62
} else {
63
	my ($template, $loggedinuser, $cookie)
64
	  = get_template_and_user({template_name => "members/mancredit.tmpl",
65
					  query => $input,
66
					  type => "intranet",
67
					  authnotrequired => 0,
68
                      flagsrequired => { borrowers => 1, updatecharges => 'remaining_permissions' },
69
					  debug => 1,
70
					  });
71
					  
72
    if ( $data->{'category_type'} eq 'C') {
73
        my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
74
        my $cnt = scalar(@$catcodes);
75
        $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
76
        $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
77
    }
78
79
    $template->param( adultborrower => 1 ) if ( $data->{category_type} eq 'A' );
80
    my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
81
    $template->param( picture => 1 ) if $picture;
82
83
if (C4::Context->preference('ExtendedPatronAttributes')) {
84
    my $attributes = GetBorrowerAttributes($borrowernumber);
85
    $template->param(
86
        ExtendedPatronAttributes => 1,
87
        extendedattributes => $attributes
88
    );
89
}
90
    
91
    $template->param(
92
        finesview => 1,
93
        borrowernumber => $borrowernumber,
94
        firstname => $data->{'firstname'},
95
        surname  => $data->{'surname'},
96
		    cardnumber => $data->{'cardnumber'},
97
		    categorycode => $data->{'categorycode'},
98
		    category_type => $data->{'category_type'},
99
		    categoryname  => $data->{'description'},
100
		    address => $data->{'address'},
101
		    address2 => $data->{'address2'},
102
		    city => $data->{'city'},
103
		    state => $data->{'state'},
104
		    zipcode => $data->{'zipcode'},
105
		    country => $data->{'country'},
106
		    phone => $data->{'phone'},
107
		    email => $data->{'email'},
108
		    branchcode => $data->{'branchcode'},
109
		    branchname => GetBranchName($data->{'branchcode'}),
110
		    is_child        => ($data->{'category_type'} eq 'C'),
111
			activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
112
            RoutingSerials => C4::Context->preference('RoutingSerials'),
113
        );
114
    output_html_with_http_headers $input, $cookie, $template->output;
115
}
(-)a/members/maninvoice.pl (-142 lines)
Lines 1-142 Link Here
1
#!/usr/bin/perl
2
3
#written 11/1/2000 by chris@katipo.oc.nz
4
#script to display borrowers account details
5
6
7
# Copyright 2000-2002 Katipo Communications
8
# Copyright 2010 BibLibre
9
#
10
# This file is part of Koha.
11
#
12
# Koha is free software; you can redistribute it and/or modify it under the
13
# terms of the GNU General Public License as published by the Free Software
14
# Foundation; either version 2 of the License, or (at your option) any later
15
# version.
16
#
17
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License along
22
# with Koha; if not, write to the Free Software Foundation, Inc.,
23
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25
use strict;
26
use warnings;
27
28
use C4::Auth;
29
use C4::Output;
30
use CGI;
31
use C4::Members;
32
use C4::Accounts;
33
use C4::Items;
34
use C4::Branch;
35
use C4::Members::Attributes qw(GetBorrowerAttributes);
36
37
my $input=new CGI;
38
my $flagsrequired = { borrowers => 1 };
39
40
my $borrowernumber=$input->param('borrowernumber');
41
42
43
# get borrower details
44
my $data=GetMember('borrowernumber'=>$borrowernumber);
45
my $add=$input->param('add');
46
if ($add){
47
    if ( checkauth( $input, 0, $flagsrequired, 'intranet' ) ) {
48
        #  print $input->header;
49
        my $barcode=$input->param('barcode');
50
        my $itemnum;
51
        if ($barcode) {
52
            $itemnum = GetItemnumberFromBarcode($barcode);
53
        }
54
        my $desc=$input->param('desc');
55
        my $amount=$input->param('amount');
56
        my $type=$input->param('type');
57
        my $note    = $input->param('note');
58
        my $error   = manualinvoice( $borrowernumber, $itemnum, $desc, $type, $amount, $note );
59
        if ($error) {
60
            my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
61
                {   template_name   => "members/maninvoice.tmpl",
62
                    query           => $input,
63
                    type            => "intranet",
64
                    authnotrequired => 0,
65
                    flagsrequired   => $flagsrequired,
66
                    debug           => 1,
67
                }
68
            );
69
            if ( $error =~ /FOREIGN KEY/ && $error =~ /itemnumber/ ) {
70
                $template->param( 'ITEMNUMBER' => 1 );
71
            }
72
            $template->param( 'ERROR' => $error );
73
            output_html_with_http_headers $input, $cookie, $template->output;
74
        } else {
75
            print $input->redirect("/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber");
76
            exit;
77
        }
78
    }
79
} else {
80
81
	my ($template, $loggedinuser, $cookie)
82
	= get_template_and_user({template_name => "members/maninvoice.tmpl",
83
					query => $input,
84
					type => "intranet",
85
					authnotrequired => 0,
86
                                      flagsrequired => {borrowers => 1, updatecharges => 'remaining_permissions'},
87
					debug => 1,
88
					});
89
					
90
  # get authorised values with type of MANUAL_INV
91
  my @invoice_types;
92
  my $dbh = C4::Context->dbh;
93
  my $sth = $dbh->prepare('SELECT * FROM authorised_values WHERE category = "MANUAL_INV"');
94
  $sth->execute();
95
  while ( my $row = $sth->fetchrow_hashref() ) {
96
    push @invoice_types, $row;
97
  }
98
  $template->param( invoice_types_loop => \@invoice_types );
99
100
    if ( $data->{'category_type'} eq 'C') {
101
        my  ( $catcodes, $labels ) =  GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
102
        my $cnt = scalar(@$catcodes);
103
        $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1;
104
        $template->param( 'catcode' =>    $catcodes->[0])  if $cnt == 1;
105
    }
106
107
    $template->param( adultborrower => 1 ) if ( $data->{'category_type'} eq 'A' );
108
    my ($picture, $dberror) = GetPatronImage($data->{'borrowernumber'});
109
    $template->param( picture => 1 ) if $picture;
110
111
if (C4::Context->preference('ExtendedPatronAttributes')) {
112
    my $attributes = GetBorrowerAttributes($borrowernumber);
113
    $template->param(
114
        ExtendedPatronAttributes => 1,
115
        extendedattributes => $attributes
116
    );
117
}
118
	$template->param(
119
                finesview => 1,
120
                borrowernumber => $borrowernumber,
121
		firstname => $data->{'firstname'},
122
                surname  => $data->{'surname'},
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
		state => $data->{'state'},
131
		zipcode => $data->{'zipcode'},
132
		country => $data->{'country'},
133
		phone => $data->{'phone'},
134
		email => $data->{'email'},
135
		branchcode => $data->{'branchcode'},
136
		branchname => GetBranchName($data->{'branchcode'}),
137
		is_child        => ($data->{'category_type'} eq 'C'),
138
		activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
139
        RoutingSerials => C4::Context->preference('RoutingSerials'),
140
    );
141
    output_html_with_http_headers $input, $cookie, $template->output;
142
}
(-)a/members/pay.pl (-263 lines)
Lines 1-263 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.tmpl',
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
    if (C4::Context->preference('ExtendedPatronAttributes')) {
231
        $b_ref->{extendedattributes} = GetBorrowerAttributes($borrowernumber);
232
        $template->param(
233
            ExtendedPatronAttributes => 1,
234
        );
235
    }
236
237
    $b_ref->{branchname} = GetBranchName( $b_ref->{branchcode} );
238
    return;
239
}
240
241
sub payselected {
242
    my @params = @_;
243
    my $amt    = 0;
244
    my @lines_to_pay;
245
    foreach (@params) {
246
        if (/^incl_par_(\d+)$/) {
247
            my $index = $1;
248
            push @lines_to_pay, $input->param("accountno$index");
249
            $amt += $input->param("amountoutstanding$index");
250
        }
251
    }
252
    $amt = '&amt=' . $amt;
253
    my $sel = '&selected=' . join ',', @lines_to_pay;
254
    my $notes = '&notes=' . join("%0A", map { $input->param("payment_note_$_") } @lines_to_pay );
255
    my $redirect =
256
        "/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber"
257
      . $amt
258
      . $sel
259
      . $notes;
260
261
    print $input->redirect($redirect);
262
    return;
263
}
(-)a/members/paycollect.pl (-180 lines)
Lines 1-180 Link Here
1
#!/usr/bin/perl
2
# Copyright 2009,2010 PTFS Inc.
3
# Copyright 2011 PTFS-Europe Ltd
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use strict;
21
use warnings;
22
use URI::Escape;
23
use C4::Context;
24
use C4::Auth;
25
use C4::Output;
26
use CGI;
27
use C4::Members;
28
use C4::Accounts;
29
use C4::Koha;
30
use C4::Branch;
31
32
my $input = CGI->new();
33
34
my $updatecharges_permissions = $input->param('writeoff_individual') ? 'writeoff' : 'remaining_permissions';
35
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
36
    {   template_name   => 'members/paycollect.tmpl',
37
        query           => $input,
38
        type            => 'intranet',
39
        authnotrequired => 0,
40
        flagsrequired   => { borrowers => 1, updatecharges => $updatecharges_permissions },
41
        debug           => 1,
42
    }
43
);
44
45
# get borrower details
46
my $borrowernumber = $input->param('borrowernumber');
47
my $borrower       = GetMember( borrowernumber => $borrowernumber );
48
my $user           = $input->remote_user;
49
50
# get account details
51
my $branch = GetBranch( $input, GetBranches() );
52
53
my ( $total_due, $accts, $numaccts ) = GetMemberAccountRecords($borrowernumber);
54
my $total_paid = $input->param('paid');
55
56
my $individual   = $input->param('pay_individual');
57
my $writeoff     = $input->param('writeoff_individual');
58
my $select_lines = $input->param('selected');
59
my $select       = $input->param('selected_accts');
60
my $payment_note = uri_unescape $input->param('payment_note');
61
my $accountno;
62
my $accountlines_id;
63
if ( $individual || $writeoff ) {
64
    if ($individual) {
65
        $template->param( pay_individual => 1 );
66
    } elsif ($writeoff) {
67
        $template->param( writeoff_individual => 1 );
68
    }
69
    my $accounttype       = $input->param('accounttype');
70
    $accountlines_id       = $input->param('accountlines_id');
71
    my $amount            = $input->param('amount');
72
    my $amountoutstanding = $input->param('amountoutstanding');
73
    $accountno = $input->param('accountno');
74
    my $itemnumber  = $input->param('itemnumber');
75
    my $description  = $input->param('description');
76
    my $title        = $input->param('title');
77
    my $notify_id    = $input->param('notify_id');
78
    my $notify_level = $input->param('notify_level');
79
    $total_due = $amountoutstanding;
80
    $template->param(
81
        accounttype       => $accounttype,
82
        accountlines_id    => $accountlines_id,
83
        accountno         => $accountno,
84
        amount            => $amount,
85
        amountoutstanding => $amountoutstanding,
86
        title             => $title,
87
        itemnumber        => $itemnumber,
88
        description       => $description,
89
        notify_id         => $notify_id,
90
        notify_level      => $notify_level,
91
        payment_note    => $payment_note,
92
    );
93
} elsif ($select_lines) {
94
    $total_due = $input->param('amt');
95
    $template->param(
96
        selected_accts => $select_lines,
97
        amt            => $total_due,
98
        selected_accts_notes => $input->param('notes'),
99
    );
100
}
101
102
if ( $total_paid and $total_paid ne '0.00' ) {
103
    if ( $total_paid < 0 or $total_paid > $total_due ) {
104
        $template->param(
105
            error_over => 1,
106
            total_due => $total_due
107
        );
108
    } else {
109
        if ($individual) {
110
            if ( $total_paid == $total_due ) {
111
                makepayment( $accountlines_id, $borrowernumber, $accountno, $total_paid, $user,
112
                    $branch, $payment_note );
113
            } else {
114
                makepartialpayment( $accountlines_id, $borrowernumber, $accountno, $total_paid,
115
                    $user, $branch, $payment_note );
116
            }
117
            print $input->redirect(
118
                "/cgi-bin/koha/members/pay.pl?borrowernumber=$borrowernumber");
119
        } else {
120
            if ($select) {
121
                if ( $select =~ /^([\d,]*).*/ ) {
122
                    $select = $1;    # ensure passing no junk
123
                }
124
                my @acc = split /,/, $select;
125
                my $note = $input->param('selected_accts_notes');
126
                recordpayment_selectaccts( $borrowernumber, $total_paid, \@acc, $note );
127
            } else {
128
                recordpayment( $borrowernumber, $total_paid );
129
            }
130
131
# recordpayment does not return success or failure so lets redisplay the boraccount
132
133
            print $input->redirect(
134
"/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber"
135
            );
136
        }
137
    }
138
} else {
139
    $total_paid = '0.00';    #TODO not right with pay_individual
140
}
141
142
borrower_add_additional_fields($borrower);
143
144
$template->param(
145
    borrowernumber => $borrowernumber,    # some templates require global
146
    borrower      => $borrower,
147
    total         => $total_due,
148
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
149
    RoutingSerials => C4::Context->preference('RoutingSerials'),
150
);
151
152
output_html_with_http_headers $input, $cookie, $template->output;
153
154
sub borrower_add_additional_fields {
155
    my $b_ref = shift;
156
157
# some borrower info is not returned in the standard call despite being assumed
158
# in a number of templates. It should not be the business of this script but in lieu of
159
# a revised api here it is ...
160
    if ( $b_ref->{category_type} eq 'C' ) {
161
        my ( $catcodes, $labels ) =
162
          GetborCatFromCatType( 'A', 'WHERE category_type = ?' );
163
        if ( @{$catcodes} ) {
164
            if ( @{$catcodes} > 1 ) {
165
                $b_ref->{CATCODE_MULTI} = 1;
166
            } elsif ( @{$catcodes} == 1 ) {
167
                $b_ref->{catcode} = $catcodes->[0];
168
            }
169
        }
170
    } elsif ( $b_ref->{category_type} eq 'A' ) {
171
        $b_ref->{adultborrower} = 1;
172
    }
173
    my ( $picture, $dberror ) = GetPatronImage( $b_ref->{borrowernumber} );
174
    if ($picture) {
175
        $b_ref->{has_picture} = 1;
176
    }
177
178
    $b_ref->{branchname} = GetBranchName( $b_ref->{branchcode} );
179
    return;
180
}
(-)a/members/printfeercpt.pl (-143 lines)
Lines 1-143 Link Here
1
#!/usr/bin/perl
2
3
4
#writen 3rd May 2010 by kmkale@anantcorp.com adapted from boraccount.pl by chris@katipo.oc.nz
5
#script to print fee receipts
6
7
8
# Copyright Koustubha Kale
9
#
10
# This file is part of Koha.
11
#
12
# Koha is free software; you can redistribute it and/or modify it under the
13
# terms of the GNU General Public License as published by the Free Software
14
# Foundation; either version 2 of the License, or (at your option) any later
15
# version.
16
#
17
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
18
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
20
#
21
# You should have received a copy of the GNU General Public License along
22
# with Koha; if not, write to the Free Software Foundation, Inc.,
23
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25
use strict;
26
use warnings;
27
28
use C4::Auth;
29
use C4::Output;
30
use C4::Dates qw/format_date/;
31
use CGI;
32
use C4::Members;
33
use C4::Branch;
34
use C4::Accounts;
35
36
my $input=new CGI;
37
38
39
my ($template, $loggedinuser, $cookie)
40
    = get_template_and_user({template_name => "members/printfeercpt.tmpl",
41
                            query => $input,
42
                            type => "intranet",
43
                            authnotrequired => 0,
44
                            flagsrequired => {borrowers => 1, updatecharges => '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.tmpl",
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.tmpl",
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