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 268-277 sub CalcFine { Link Here
268
    } else {
268
    } else {
269
        # a zero (or null)  chargeperiod means no charge.
269
        # a zero (or null)  chargeperiod means no charge.
270
    }
270
    }
271
    if(C4::Context->preference('maxFine') && ( $amount > C4::Context->preference('maxFine'))) {
271
    $amount = $data->{overduefinescap} if $data->{overduefinescap} && $amount > $data->{overduefinescap};
272
        $amount = C4::Context->preference('maxFine');
272
    $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $days_minus_grace, $chargeable_units);
273
    }
273
    return ($amount, $data->{'chargename'}, $days_minus_grace, $chargeable_units);
274
    return ($amount, $data->{chargename}, $units_minus_grace);
275
    # FIXME: chargename is NEVER populated anywhere.
274
    # FIXME: chargename is NEVER populated anywhere.
276
}
275
}
277
276
Lines 521-534 sub UpdateFine { Link Here
521
	#   "REF" is Cash Refund
520
	#   "REF" is Cash Refund
522
    my $sth = $dbh->prepare(
521
    my $sth = $dbh->prepare(
523
        "SELECT * FROM accountlines
522
        "SELECT * FROM accountlines
524
		WHERE itemnumber=?
523
		WHERE borrowernumber=?
525
		AND   borrowernumber=?
524
		AND   accounttype IN ('FU','O','F','M')"
526
		AND   accounttype IN ('FU','O','F','M')
527
		AND   description like ? "
528
    );
525
    );
529
    $sth->execute( $itemnum, $borrowernumber, "%$due%" );
526
    $sth->execute( $borrowernumber );
527
    my $data;
528
    my $total_amount_other = 0.00;
529
    my $due_qr = qr/$due/;
530
    # Cycle through the fines and
531
    # - find line that relates to the requested $itemnum
532
    # - accumulate fines for other items
533
    # so we can update $itemnum fine taking in account fine caps
534
    while (my $rec = $sth->fetchrow_hashref) {
535
        if ($rec->{itemnumber} == $itemnum && $rec->{description} =~ /$due_qr/) {
536
            if ($data) {
537
                warn "Not a unique accountlines record for item $itemnum borrower $borrowernumber";
538
            } else {
539
                $data = $rec;
540
                next;
541
            }
542
        }
543
        $total_amount_other += $rec->{'amount'};
544
    }
545
    if (my $maxfine = C4::Context->preference('MaxFine')) {
546
        if ($total_amount_other + $amount > $maxfine) {
547
            my $new_amount = $maxfine - $total_amount_other;
548
            warn "Reducing fine for item $itemnum borrower $borrowernumber from $amount to $new_amount - MaxFine reached";
549
            return if $new_amount <= 0.00;
550
551
            $amount = $new_amount;
552
        }
553
    }
530
554
531
    if ( my $data = $sth->fetchrow_hashref ) {
555
    if ( $data ) {
532
556
533
		# we're updating an existing fine.  Only modify if amount changed
557
		# we're updating an existing fine.  Only modify if amount changed
534
        # Note that in the current implementation, you cannot pay against an accruing fine
558
        # Note that in the current implementation, you cannot pay against an accruing fine
(-)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 996-1001 CREATE TABLE `issuingrules` ( Link Here
996
  `renewalsallowed` smallint(6) NOT NULL default "0",
996
  `renewalsallowed` smallint(6) NOT NULL default "0",
997
  `reservesallowed` smallint(6) NOT NULL default "0",
997
  `reservesallowed` smallint(6) NOT NULL default "0",
998
  `branchcode` varchar(10) NOT NULL default '',
998
  `branchcode` varchar(10) NOT NULL default '',
999
  overduefinescap decimal default NULL,
999
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
1000
  PRIMARY KEY  (`branchcode`,`categorycode`,`itemtype`),
1000
  KEY `categorycode` (`categorycode`),
1001
  KEY `categorycode` (`categorycode`),
1001
  KEY `itemtype` (`itemtype`)
1002
  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 5219-5224 if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { Link Here
5219
    SetVersion($DBversion);
5219
    SetVersion($DBversion);
5220
}
5220
}
5221
5221
5222
5223
5224
$DBversion = '3.07.00.XXX';
5225
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
5226
    $dbh->do("ALTER TABLE issuingrules ADD overduefinescap decimal DEFAULT NULL");
5227
    my $maxfine = C4::Context->preference('MaxFine');
5228
    if ($maxfine && $maxfine < 900) { # an arbitrary value that tells us it's not "some huge value"
5229
      $dbh->do("UPDATE issuingrules SET overduefinescap=?",undef,$maxfine);
5230
      $dbh->do("UPDATE systempreferences SET value = NULL WHERE variable = 'MaxFine'");
5231
    }
5232
    $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'");
5233
    print "Upgrade to $DBversion done (Bug 7420 add overduefinescap to circulation matrix)\n";
5234
    SetVersion ($DBversion);
5235
}
5236
5222
=head1 FUNCTIONS
5237
=head1 FUNCTIONS
5223
5238
5224
=head2 TableExists($table)
5239
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref (-1 / +2 lines)
Lines 74-83 Patrons: Link Here
74
               no: "Don't allow"
74
               no: "Don't allow"
75
         - "staff to access a patron's checkout history (it is stored regardless)."
75
         - "staff to access a patron's checkout history (it is stored regardless)."
76
     -
76
     -
77
         - The late fine for a specific checkout will only go up to
77
         - The late fine for all checkouts will only go up to
78
         - pref: MaxFine
78
         - pref: MaxFine
79
           class: currency
79
           class: currency
80
         - '[% local_currency %].'
80
         - '[% local_currency %].'
81
         - Empty value means no limit. Single item caps are specified in the circulation rules matrix.
81
     -
82
     -
82
         - pref: memberofinstitution
83
         - pref: memberofinstitution
83
           choices:
84
           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