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

(-)a/C4/Overdues.pm (-12 / +36 lines)
Lines 241-248 C<$amount> is the fine owed by the patron (see above). Link Here
241
C<$chargename> is the chargename field from the applicable record in
241
C<$chargename> is the chargename field from the applicable record in
242
the categoryitem table, whatever that is.
242
the categoryitem table, whatever that is.
243
243
244
C<$daycount> is the number of days between start and end dates, Calendar adjusted (where needed), 
244
C<$unitcount> is the number of chargeable units (days between start and end dates, Calendar adjusted where needed, 
245
minus any applicable grace period.
245
minus any applicable grace period, or hours)
246
246
247
FIXME - What is chargename supposed to be ?
247
FIXME - What is chargename supposed to be ?
248
248
Lines 281-290 sub CalcFine { Link Here
281
    } else {
281
    } else {
282
        # a zero (or null)  chargeperiod means no charge.
282
        # a zero (or null)  chargeperiod means no charge.
283
    }
283
    }
284
    if(C4::Context->preference('maxFine') && ( $amount > C4::Context->preference('maxFine'))) {
284
    $amount = $data->{overduefinescap} if $data->{overduefinescap} && $amount > $data->{overduefinescap};
285
        $amount = C4::Context->preference('maxFine');
285
    $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $days_minus_grace, $chargeable_units);
286
    }
286
    return ($amount, $data->{'chargename'}, $days_minus_grace, $chargeable_units);
287
    return ($amount, $data->{chargename}, $days_minus_grace);
288
    # FIXME: chargename is NEVER populated anywhere.
287
    # FIXME: chargename is NEVER populated anywhere.
289
}
288
}
290
289
Lines 492-505 sub UpdateFine { Link Here
492
	#   "REF" is Cash Refund
491
	#   "REF" is Cash Refund
493
    my $sth = $dbh->prepare(
492
    my $sth = $dbh->prepare(
494
        "SELECT * FROM accountlines
493
        "SELECT * FROM accountlines
495
		WHERE itemnumber=?
494
		WHERE borrowernumber=?
496
		AND   borrowernumber=?
495
		AND   accounttype IN ('FU','O','F','M')"
497
		AND   accounttype IN ('FU','O','F','M')
498
		AND   description like ? "
499
    );
496
    );
500
    $sth->execute( $itemnum, $borrowernumber, "%$due%" );
497
    $sth->execute( $borrowernumber );
498
    my $data;
499
    my $total_amount_other = 0.00;
500
    my $due_qr = qr/$due/;
501
    # Cycle through the fines and
502
    # - find line that relates to the requested $itemnum
503
    # - accumulate fines for other items
504
    # so we can update $itemnum fine taking in account fine caps
505
    while (my $rec = $sth->fetchrow_hashref) {
506
        if ($rec->{itemnumber} == $itemnum && $rec->{description} =~ /$due_qr/) {
507
            if ($data) {
508
                warn "Not a unique accountlines record for item $itemnum borrower $borrowernumber";
509
            } else {
510
                $data = $rec;
511
                next;
512
            }
513
        }
514
        $total_amount_other += $rec->{'amount'};
515
    }
516
    if (my $maxfine = C4::Context->preference('MaxFine')) {
517
        if ($total_amount_other + $amount > $maxfine) {
518
            my $new_amount = $maxfine - $total_amount_other;
519
            warn "Reducing fine for item $itemnum borrower $borrowernumber from $amount to $new_amount - MaxFine reached";
520
            return if $new_amount <= 0.00;
521
522
            $amount = $new_amount;
523
        }
524
    }
501
525
502
    if ( my $data = $sth->fetchrow_hashref ) {
526
    if ( $data ) {
503
527
504
		# we're updating an existing fine.  Only modify if amount changed
528
		# we're updating an existing fine.  Only modify if amount changed
505
        # Note that in the current implementation, you cannot pay against an accruing fine
529
        # Note that in the current implementation, you cannot pay against an accruing fine
(-)a/C4/Search.pm (-1 / +1 lines)
Lines 26-32 use C4::Search::PazPar2; Link Here
26
use XML::Simple;
26
use XML::Simple;
27
use C4::Dates qw(format_date);
27
use C4::Dates qw(format_date);
28
use C4::Members qw(GetHideLostItemsPreference);
28
use C4::Members qw(GetHideLostItemsPreference);
29
use C4::XSLT;
29
# use C4::XSLT;
30
use C4::Branch;
30
use C4::Branch;
31
use C4::Reserves;    # CheckReserves
31
use C4::Reserves;    # CheckReserves
32
use C4::Debug;
32
use C4::Debug;
(-)a/admin/smart-rules.pl (-4 / +5 lines)
Lines 101-108 elsif ($op eq 'delete-branch-item') { Link Here
101
# save the values entered
101
# save the values entered
102
elsif ($op eq 'add') {
102
elsif ($op eq 'add') {
103
    my $sth_search = $dbh->prepare('SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?');
103
    my $sth_search = $dbh->prepare('SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?');
104
    my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
104
    my $sth_insert = $dbh->prepare('INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, lengthunit, hardduedate, hardduedatecompare, fine, finedays, firstremind, chargeperiod,rentaldiscount, overduefinescap) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
105
    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?  WHERE branchcode=? AND categorycode=? AND itemtype=?");
105
    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, lengthunit = ?, hardduedate=?, hardduedatecompare=?, rentaldiscount=?, overduefinescap=?  WHERE branchcode=? AND categorycode=? AND itemtype=?");
106
    
106
    
107
    my $br = $branch; # branch
107
    my $br = $branch; # branch
108
    my $bor  = $input->param('categorycode'); # borrower category
108
    my $bor  = $input->param('categorycode'); # borrower category
Lines 122-135 elsif ($op eq 'add') { Link Here
122
    $hardduedate = format_date_in_iso($hardduedate);
122
    $hardduedate = format_date_in_iso($hardduedate);
123
    my $hardduedatecompare = $input->param('hardduedatecompare');
123
    my $hardduedatecompare = $input->param('hardduedatecompare');
124
    my $rentaldiscount = $input->param('rentaldiscount');
124
    my $rentaldiscount = $input->param('rentaldiscount');
125
    my $overduefinescap = $input->param('overduefinescap') || undef;
125
    $debug and warn "Adding $br, $bor, $cat, $fine, $maxissueqty";
126
    $debug and warn "Adding $br, $bor, $cat, $fine, $maxissueqty";
126
127
127
    $sth_search->execute($br,$bor,$cat);
128
    $sth_search->execute($br,$bor,$cat);
128
    my $res = $sth_search->fetchrow_hashref();
129
    my $res = $sth_search->fetchrow_hashref();
129
    if ($res->{total}) {
130
    if ($res->{total}) {
130
        $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount, $br,$bor,$cat);
131
        $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$lengthunit, $hardduedate,$hardduedatecompare,$rentaldiscount,$overduefinescap, $br,$bor,$cat);
131
    } else {
132
    } else {
132
        $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount);
133
        $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$lengthunit,$hardduedate,$hardduedatecompare,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount,$overduefinescap);
133
    }
134
    }
134
} 
135
} 
135
elsif ($op eq "set-branch-defaults") {
136
elsif ($op eq "set-branch-defaults") {
(-)a/installer/data/mysql/kohastructure.sql (+1 lines)
Lines 995-1000 CREATE TABLE `issuingrules` ( Link Here
995
  `renewalsallowed` smallint(6) NOT NULL default "0",
995
  `renewalsallowed` smallint(6) NOT NULL default "0",
996
  `reservesallowed` smallint(6) NOT NULL default "0",
996
  `reservesallowed` smallint(6) NOT NULL default "0",
997
  `branchcode` varchar(10) NOT NULL default '',
997
  `branchcode` varchar(10) NOT NULL default '',
998
  overduefinescap decimal default NULL,
998
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
999
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
999
  KEY `categorycode` (`categorycode`),
1000
  KEY `categorycode` (`categorycode`),
1000
  KEY `itemtype` (`itemtype`)
1001
  KEY `itemtype` (`itemtype`)
(-)a/installer/data/mysql/sysprefs.sql (-1 / +1 lines)
Lines 62-68 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES Link Here
62
-- this is selected by the web installer now
62
-- this is selected by the web installer now
63
-- INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('marcflavour','MARC21','Define global MARC flavor (MARC21 or UNIMARC) used for character encoding','MARC21|UNIMARC','Choice');
63
-- INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('marcflavour','MARC21','Define global MARC flavor (MARC21 or UNIMARC) used for character encoding','MARC21|UNIMARC','Choice');
64
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('MARCOrgCode','OSt','Define MARC Organization Code - http://www.loc.gov/marc/organizations/orgshome.html','','free');
64
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('MARCOrgCode','OSt','Define MARC Organization Code - http://www.loc.gov/marc/organizations/orgshome.html','','free');
65
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('MaxFine',9999,'Maximum fine a patron can have for a single late return','','Integer');
65
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('MaxFine',NULL,'Maximum fine a patron can have for all late returns at one moment. Single item caps are specified in the circulation rules matrix.','','Integer');
66
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxoutstanding',5,'maximum amount withstanding to be able make holds','','Integer');
66
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxoutstanding',5,'maximum amount withstanding to be able make holds','','Integer');
67
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxreserves',50,'Define maximum number of holds a patron can place','','Integer');
67
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxreserves',50,'Define maximum number of holds a patron can place','','Integer');
68
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxItemsInSearchResults',20,'Specify the maximum number of items to display for each result on a page of results',NULL,'free');
68
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxItemsInSearchResults',20,'Specify the maximum number of items to display for each result on a page of results',NULL,'free');
(-)a/installer/data/mysql/updatedatabase.pl (+15 lines)
Lines 5139-5144 if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { Link Here
5139
    SetVersion($DBversion);
5139
    SetVersion($DBversion);
5140
}
5140
}
5141
5141
5142
5143
5144
$DBversion = '3.07.00.XXX';
5145
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
5146
    $dbh->do("ALTER TABLE issuingrules ADD overduefinescap decimal DEFAULT NULL");
5147
    my $maxfine = C4::Context->preference('MaxFine');
5148
    if ($maxfine && $maxfine < 900) { # an arbitrary value that tells us it's not "some huge value"
5149
      $dbh->do("UPDATE issuingrules SET overduefinescap=?",undef,$maxfine);
5150
      $dbh->do("UPDATE systempreferences SET value = NULL WHERE variable = 'MaxFine'");
5151
    }
5152
    $dbh->do("UPDATE systempreferences SET explanation = 'Maximum fine a patron can have for all late returns at one moment. Single item caps are specified in the circulation rules matrix.' WHERE variable = 'MaxFine'");
5153
    print "Upgrade to $DBversion done (Bug 7420 add overduefinescap to circulation matrix)\n";
5154
    SetVersion ($DBversion);
5155
}
5156
5142
=head1 FUNCTIONS
5157
=head1 FUNCTIONS
5143
5158
5144
=head2 DropAllForeignKeys($table)
5159
=head2 DropAllForeignKeys($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref (-1 / +2 lines)
Lines 73-82 Patrons: Link Here
73
               no: "Don't allow"
73
               no: "Don't allow"
74
         - "staff to access a patron's checkout history (it is stored regardless)."
74
         - "staff to access a patron's checkout history (it is stored regardless)."
75
     -
75
     -
76
         - The late fine for a specific checkout will only go up to
76
         - The late fine for all checkouts will only go up to
77
         - pref: MaxFine
77
         - pref: MaxFine
78
           class: currency
78
           class: currency
79
         - '[% local_currency %].'
79
         - '[% local_currency %].'
80
         - Empty value means no limit. Single item caps are specified in the circulation rules matrix.
80
     -
81
     -
81
         - pref: memberofinstitution
82
         - pref: memberofinstitution
82
           choices:
83
           choices:
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt (-1 / +3 lines)
Lines 78-83 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
78
                <th>Fine amount</th>
78
                <th>Fine amount</th>
79
                <th>Fine charging interval</th>
79
                <th>Fine charging interval</th>
80
                <th>Fine grace period (day)</th>
80
                <th>Fine grace period (day)</th>
81
                <th>Overdue Fines Cap ($)</th>
81
                <th>Suspension in days (day)</th>
82
                <th>Suspension in days (day)</th>
82
                <th>Renewals allowed (count)</th>
83
                <th>Renewals allowed (count)</th>
83
                <th>Holds allowed (count)</th>
84
                <th>Holds allowed (count)</th>
Lines 122-127 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
122
							<td>[% rule.fine %]</td>
123
							<td>[% rule.fine %]</td>
123
							<td>[% rule.chargeperiod %]</td>
124
							<td>[% rule.chargeperiod %]</td>
124
							<td>[% rule.firstremind %]</td>
125
							<td>[% rule.firstremind %]</td>
126
							<td>[% rule.overduefinescap FILTER format("%.2f") %]</td>
125
							<td>[% rule.finedays %]</td>
127
							<td>[% rule.finedays %]</td>
126
							<td>[% rule.renewalsallowed %]</td>
128
							<td>[% rule.renewalsallowed %]</td>
127
							<td>[% rule.reservesallowed %]</td>
129
							<td>[% rule.reservesallowed %]</td>
Lines 182-187 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
182
                    <td><input name="fine" size="4" /></td>
184
                    <td><input name="fine" size="4" /></td>
183
                    <td><input name="chargeperiod" size="2" /></td>
185
                    <td><input name="chargeperiod" size="2" /></td>
184
                    <td><input name="firstremind" size="2" /> </td>
186
                    <td><input name="firstremind" size="2" /> </td>
187
                    <td><input name="overduefinescap" size="6" /> </td>
185
                    <td><input name="finedays" size="3" /> </td>
188
                    <td><input name="finedays" size="3" /> </td>
186
                    <td><input name="renewalsallowed" size="2" /></td>
189
                    <td><input name="renewalsallowed" size="2" /></td>
187
                    <td><input name="reservesallowed" size="2" /></td>
190
                    <td><input name="reservesallowed" size="2" /></td>
188
- 

Return to bug 7420