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

(-)a/C4/Overdues.pm (-47 / +50 lines)
Lines 24-29 use strict; Link Here
24
use Date::Calc qw/Today Date_to_Days/;
24
use Date::Calc qw/Today Date_to_Days/;
25
use Date::Manip qw/UnixDate/;
25
use Date::Manip qw/UnixDate/;
26
use List::MoreUtils qw( uniq );
26
use List::MoreUtils qw( uniq );
27
use POSIX qw( floor ceil );
27
28
28
use C4::Circulation;
29
use C4::Circulation;
29
use C4::Context;
30
use C4::Context;
Lines 34-78 use C4::Debug; Link Here
34
use vars qw($VERSION @ISA @EXPORT);
35
use vars qw($VERSION @ISA @EXPORT);
35
36
36
BEGIN {
37
BEGIN {
37
	# set the version for version checking
38
    # set the version for version checking
38
    $VERSION = 3.07.00.049;
39
    $VERSION = 3.07.00.049;
39
	require Exporter;
40
    require Exporter;
40
	@ISA    = qw(Exporter);
41
    @ISA = qw(Exporter);
41
	# subs to rename (and maybe merge some...)
42
42
	push @EXPORT, qw(
43
    # subs to rename (and maybe merge some...)
43
        &CalcFine
44
    push @EXPORT, qw(
44
        &Getoverdues
45
      &CalcFine
45
        &checkoverdues
46
      &Getoverdues
46
        &NumberNotifyId
47
      &checkoverdues
47
        &AmountNotify
48
      &NumberNotifyId
48
        &UpdateFine
49
      &AmountNotify
49
        &GetFine
50
      &UpdateFine
50
        &get_chargeable_units
51
      &GetFine
51
        &CheckItemNotify
52
      &get_chargeable_units
52
        &GetOverduesForBranch
53
      &CheckItemNotify
53
        &RemoveNotifyLine
54
      &GetOverduesForBranch
54
        &AddNotifyLine
55
      &RemoveNotifyLine
55
        &GetOverdueMessageTransportTypes
56
      &AddNotifyLine
56
	);
57
      &GetOverdueMessageTransportTypes
57
	# subs to remove
58
    );
58
	push @EXPORT, qw(
59
59
        &BorType
60
    # subs to remove
60
	);
61
    push @EXPORT, qw(
61
62
      &BorType
62
	# check that an equivalent don't exist already before moving
63
    );
63
64
64
	# subs to move to Circulation.pm
65
    # check that an equivalent don't exist already before moving
65
	push @EXPORT, qw(
66
66
        &GetIssuesIteminfo
67
    # subs to move to Circulation.pm
67
	);
68
    push @EXPORT, qw(
68
69
      &GetIssuesIteminfo
69
     # &GetIssuingRules - delete.
70
    );
70
   # use C4::Circulation::GetIssuingRule instead.
71
71
72
    # &GetIssuingRules - delete.
72
	# subs to move to Biblio.pm
73
    # use C4::Circulation::GetIssuingRule instead.
73
	push @EXPORT, qw(
74
74
        &GetItems
75
    # subs to move to Biblio.pm
75
	);
76
    push @EXPORT, qw(
77
      &GetItems
78
    );
76
}
79
}
77
80
78
=head1 NAME
81
=head1 NAME
Lines 251-265 sub CalcFine { Link Here
251
    my $chargeable_units = get_chargeable_units($fine_unit, $start_date, $end_date, $branchcode);
254
    my $chargeable_units = get_chargeable_units($fine_unit, $start_date, $end_date, $branchcode);
252
    my $units_minus_grace = $chargeable_units - $data->{firstremind};
255
    my $units_minus_grace = $chargeable_units - $data->{firstremind};
253
    my $amount = 0;
256
    my $amount = 0;
254
    if ($data->{'chargeperiod'}  && ($units_minus_grace > 0)  ) {
257
    if ( $data->{'chargeperiod'} && ( $units_minus_grace > 0 ) ) {
255
        if ( C4::Context->preference('FinesIncludeGracePeriod') ) {
258
        my $units = C4::Context->preference('FinesIncludeGracePeriod') ? $chargeable_units : $units_minus_grace;
256
            $amount = int($chargeable_units / $data->{'chargeperiod'}) * $data->{'fine'};# TODO fine calc should be in cents
259
        my $charge_periods = $units / $data->{'chargeperiod'};
257
        } else {
260
        # If chargeperiod_charge_at = 1, we charge a fine at the start of each charge period
258
            $amount = int($units_minus_grace / $data->{'chargeperiod'}) * $data->{'fine'};
261
        # if chargeperiod_charge_at = 0, we charge at the end of each charge period
259
        }
262
        $charge_periods = $data->{'chargeperiod_charge_at'} == 1 ? ceil($charge_periods) : floor($charge_periods);
260
    } else {
263
        $amount = $charge_periods * $data->{'fine'};
261
        # a zero (or null) chargeperiod or negative units_minus_grace value means no charge.
264
    } # else { # a zero (or null) chargeperiod or negative units_minus_grace value means no charge. }
262
    }
265
263
    $amount = $data->{overduefinescap} if $data->{overduefinescap} && $amount > $data->{overduefinescap};
266
    $amount = $data->{overduefinescap} if $data->{overduefinescap} && $amount > $data->{overduefinescap};
264
    $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $units_minus_grace, $chargeable_units);
267
    $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $units_minus_grace, $chargeable_units);
265
    return ($amount, $data->{'chargename'}, $units_minus_grace, $chargeable_units);
268
    return ($amount, $data->{'chargename'}, $units_minus_grace, $chargeable_units);
(-)a/Koha/Schema/Result/Issuingrule.pm (+8 lines)
Lines 80-85 __PACKAGE__->table("issuingrules"); Link Here
80
  data_type: 'integer'
80
  data_type: 'integer'
81
  is_nullable: 1
81
  is_nullable: 1
82
82
83
=head2 chargeperiod_charge_at
84
85
  data_type: 'tinyint'
86
  default_value: 0
87
  is_nullable: 0
88
83
=head2 accountsent
89
=head2 accountsent
84
90
85
  data_type: 'integer'
91
  data_type: 'integer'
Lines 202-207 __PACKAGE__->add_columns( Link Here
202
  { data_type => "integer", is_nullable => 1 },
208
  { data_type => "integer", is_nullable => 1 },
203
  "chargeperiod",
209
  "chargeperiod",
204
  { data_type => "integer", is_nullable => 1 },
210
  { data_type => "integer", is_nullable => 1 },
211
  "chargeperiod_charge_at",
212
  { data_type => "tinyint", default_value => 0, is_nullable => 0 },
205
  "accountsent",
213
  "accountsent",
206
  { data_type => "integer", is_nullable => 1 },
214
  { data_type => "integer", is_nullable => 1 },
207
  "chargename",
215
  "chargename",
(-)a/admin/smart-rules.pl (-23 / +25 lines)
Lines 110-115 elsif ($op eq 'add') { Link Here
110
    $maxsuspensiondays = undef if $maxsuspensiondays eq q||;
110
    $maxsuspensiondays = undef if $maxsuspensiondays eq q||;
111
    my $firstremind  = $input->param('firstremind');
111
    my $firstremind  = $input->param('firstremind');
112
    my $chargeperiod = $input->param('chargeperiod');
112
    my $chargeperiod = $input->param('chargeperiod');
113
    my $chargeperiod_charge_at = $input->param('chargeperiod_charge_at');
113
    my $maxissueqty  = $input->param('maxissueqty');
114
    my $maxissueqty  = $input->param('maxissueqty');
114
    my $maxonsiteissueqty  = $input->param('maxonsiteissueqty');
115
    my $maxonsiteissueqty  = $input->param('maxonsiteissueqty');
115
    my $renewalsallowed  = $input->param('renewalsallowed');
116
    my $renewalsallowed  = $input->param('renewalsallowed');
Lines 137-165 elsif ($op eq 'add') { Link Here
137
    my $rs = $schema->resultset('Issuingrule');
138
    my $rs = $schema->resultset('Issuingrule');
138
139
139
    my $params = {
140
    my $params = {
140
        branchcode         => $br,
141
        branchcode             => $br,
141
        categorycode       => $bor,
142
        categorycode           => $bor,
142
        itemtype           => $itemtype,
143
        itemtype               => $itemtype,
143
        fine               => $fine,
144
        fine                   => $fine,
144
        finedays           => $finedays,
145
        finedays               => $finedays,
145
        maxsuspensiondays  => $maxsuspensiondays,
146
        maxsuspensiondays      => $maxsuspensiondays,
146
        firstremind        => $firstremind,
147
        firstremind            => $firstremind,
147
        chargeperiod       => $chargeperiod,
148
        chargeperiod           => $chargeperiod,
148
        maxissueqty        => $maxissueqty,
149
        chargeperiod_charge_at => $chargeperiod_charge_at,
149
        maxonsiteissueqty  => $maxonsiteissueqty,
150
        maxissueqty            => $maxissueqty,
150
        renewalsallowed    => $renewalsallowed,
151
        maxonsiteissueqty      => $maxonsiteissueqty,
151
        renewalperiod      => $renewalperiod,
152
        renewalsallowed        => $renewalsallowed,
152
        norenewalbefore    => $norenewalbefore,
153
        renewalperiod          => $renewalperiod,
153
        auto_renew         => $auto_renew,
154
        norenewalbefore        => $norenewalbefore,
154
        reservesallowed    => $reservesallowed,
155
        auto_renew             => $auto_renew,
155
        issuelength        => $issuelength,
156
        reservesallowed        => $reservesallowed,
156
        lengthunit         => $lengthunit,
157
        issuelength            => $issuelength,
157
        hardduedate        => $hardduedate,
158
        lengthunit             => $lengthunit,
158
        hardduedatecompare => $hardduedatecompare,
159
        hardduedate            => $hardduedate,
159
        rentaldiscount     => $rentaldiscount,
160
        hardduedatecompare     => $hardduedatecompare,
160
        onshelfholds       => $onshelfholds,
161
        rentaldiscount         => $rentaldiscount,
161
        opacitemholds      => $opacitemholds,
162
        onshelfholds           => $onshelfholds,
162
        overduefinescap    => $overduefinescap,
163
        opacitemholds          => $opacitemholds,
164
        overduefinescap        => $overduefinescap,
163
    };
165
    };
164
166
165
    $rs->update_or_create($params);
167
    $rs->update_or_create($params);
(-)a/installer/data/mysql/atomicupdate/bug_13590.sql (+1 lines)
Line 0 Link Here
1
ALTER TABLE issuingrules ADD chargeperiod_charge_at BOOLEAN NOT NULL DEFAULT  '0' AFTER chargeperiod;
(-)a/installer/data/mysql/kohastructure.sql (+1 lines)
Lines 1172-1177 CREATE TABLE `issuingrules` ( -- circulation and fine rules Link Here
1172
  `maxsuspensiondays` int(11) default NULL, -- max suspension days
1172
  `maxsuspensiondays` int(11) default NULL, -- max suspension days
1173
  `firstremind` int(11) default NULL, -- fine grace period
1173
  `firstremind` int(11) default NULL, -- fine grace period
1174
  `chargeperiod` int(11) default NULL, -- how often the fine amount is charged
1174
  `chargeperiod` int(11) default NULL, -- how often the fine amount is charged
1175
  `chargeperiod_charge_at` tinyint(1) NOT NULL DEFAULT '0', -- Should fine be given at the start ( 1 ) or the end ( 0 ) of the period
1175
  `accountsent` int(11) default NULL, -- not used? always NULL
1176
  `accountsent` int(11) default NULL, -- not used? always NULL
1176
  `chargename` varchar(100) default NULL, -- not used? always NULL
1177
  `chargename` varchar(100) default NULL, -- not used? always NULL
1177
  `maxissueqty` int(4) default NULL, -- total number of checkouts allowed
1178
  `maxissueqty` int(4) default NULL, -- total number of checkouts allowed
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt (+8 lines)
Lines 148-153 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
148
                <th>Hard due date</th>
148
                <th>Hard due date</th>
149
                <th>Fine amount</th>
149
                <th>Fine amount</th>
150
                <th>Fine charging interval</th>
150
                <th>Fine charging interval</th>
151
                <th>Charge when?</th>
151
                <th>Fine grace period</th>
152
                <th>Fine grace period</th>
152
                <th>Overdue fines cap (amount)</th>
153
                <th>Overdue fines cap (amount)</th>
153
                <th>Suspension in days (day)</th>
154
                <th>Suspension in days (day)</th>
Lines 212-217 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
212
                            </td>
213
                            </td>
213
							<td>[% rule.fine %]</td>
214
							<td>[% rule.fine %]</td>
214
							<td>[% rule.chargeperiod %]</td>
215
							<td>[% rule.chargeperiod %]</td>
216
                <td>[% IF rule.chargeperiod_charge_at %]Start of interval[% ELSE %]End of interval[% END %]</td>
215
							<td>[% rule.firstremind %]</td>
217
							<td>[% rule.firstremind %]</td>
216
                            <td>[% rule.overduefinescap FILTER format("%.2f") %]</td>
218
                            <td>[% rule.overduefinescap FILTER format("%.2f") %]</td>
217
							<td>[% rule.finedays %]</td>
219
							<td>[% rule.finedays %]</td>
Lines 273-278 for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidde Link Here
273
                    </td>
275
                    </td>
274
                    <td><input type="text" name="fine" id="fine" size="4" /></td>
276
                    <td><input type="text" name="fine" id="fine" size="4" /></td>
275
                    <td><input type="text" name="chargeperiod" id="chargeperiod" size="2" /></td>
277
                    <td><input type="text" name="chargeperiod" id="chargeperiod" size="2" /></td>
278
                    <td>
279
                        <select name="chargeperiod_charge_at" id="chargeperiod_charge_at">
280
                           <option value="0">End of interval</option>
281
                           <option value="1">Start of interval</option>
282
                        </select>
283
                    </td>
276
                    <td><input type="text" name="firstremind" id="firstremind" size="2" /> </td>
284
                    <td><input type="text" name="firstremind" id="firstremind" size="2" /> </td>
277
                    <td><input type="text" name="overduefinescap" id="overduefinescap" size="6" /> </td>
285
                    <td><input type="text" name="overduefinescap" id="overduefinescap" size="6" /> </td>
278
                    <td><input type="text" name="finedays" id="fined" size="3" /> </td>
286
                    <td><input type="text" name="finedays" id="fined" size="3" /> </td>
(-)a/t/db_dependent/Circulation_Issuingrule.t (-1 / +9 lines)
Lines 121-126 my $sampleissuingrule1 = { Link Here
121
    auto_renew         => 0,
121
    auto_renew         => 0,
122
    issuelength        => 5,
122
    issuelength        => 5,
123
    chargeperiod       => 0,
123
    chargeperiod       => 0,
124
    chargeperiod_charge_at => 0,
124
    rentaldiscount     => '2.000000',
125
    rentaldiscount     => '2.000000',
125
    reservesallowed    => 0,
126
    reservesallowed    => 0,
126
    hardduedate        => '2013-01-01',
127
    hardduedate        => '2013-01-01',
Lines 155-160 my $sampleissuingrule2 = { Link Here
155
    finedays           => 'Null',
156
    finedays           => 'Null',
156
    firstremind        => 'Null',
157
    firstremind        => 'Null',
157
    chargeperiod       => 'Null',
158
    chargeperiod       => 'Null',
159
    chargeperiod_charge_at => 0,
158
    rentaldiscount     => 2.00,
160
    rentaldiscount     => 2.00,
159
    overduefinescap    => 'Null',
161
    overduefinescap    => 'Null',
160
    accountsent        => 'Null',
162
    accountsent        => 'Null',
Lines 184-189 my $sampleissuingrule3 = { Link Here
184
    finedays           => 'Null',
186
    finedays           => 'Null',
185
    firstremind        => 'Null',
187
    firstremind        => 'Null',
186
    chargeperiod       => 'Null',
188
    chargeperiod       => 'Null',
189
    chargeperiod_charge_at => 0,
187
    rentaldiscount     => 3.00,
190
    rentaldiscount     => 3.00,
188
    overduefinescap    => 'Null',
191
    overduefinescap    => 'Null',
189
    accountsent        => 'Null',
192
    accountsent        => 'Null',
Lines 194-199 my $sampleissuingrule3 = { Link Here
194
    onshelfholds       => 1,
197
    onshelfholds       => 1,
195
    opacitemholds      => 'F',
198
    opacitemholds      => 'F',
196
};
199
};
200
197
$query = 'INSERT INTO issuingrules (
201
$query = 'INSERT INTO issuingrules (
198
                branchcode,
202
                branchcode,
199
                categorycode,
203
                categorycode,
Lines 213-218 $query = 'INSERT INTO issuingrules ( Link Here
213
                finedays,
217
                finedays,
214
                firstremind,
218
                firstremind,
215
                chargeperiod,
219
                chargeperiod,
220
                chargeperiod_charge_at,
216
                rentaldiscount,
221
                rentaldiscount,
217
                overduefinescap,
222
                overduefinescap,
218
                accountsent,
223
                accountsent,
Lines 220-226 $query = 'INSERT INTO issuingrules ( Link Here
220
                chargename,
225
                chargename,
221
                restrictedtype,
226
                restrictedtype,
222
                maxsuspensiondays
227
                maxsuspensiondays
223
                ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)';
228
                ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)';
224
my $sth = $dbh->prepare($query);
229
my $sth = $dbh->prepare($query);
225
$sth->execute(
230
$sth->execute(
226
    $sampleissuingrule1->{branchcode},
231
    $sampleissuingrule1->{branchcode},
Lines 241-246 $sth->execute( Link Here
241
    $sampleissuingrule1->{finedays},
246
    $sampleissuingrule1->{finedays},
242
    $sampleissuingrule1->{firstremind},
247
    $sampleissuingrule1->{firstremind},
243
    $sampleissuingrule1->{chargeperiod},
248
    $sampleissuingrule1->{chargeperiod},
249
    $sampleissuingrule1->{chargeperiod_charge_at},
244
    $sampleissuingrule1->{rentaldiscount},
250
    $sampleissuingrule1->{rentaldiscount},
245
    $sampleissuingrule1->{overduefinescap},
251
    $sampleissuingrule1->{overduefinescap},
246
    $sampleissuingrule1->{accountsent},
252
    $sampleissuingrule1->{accountsent},
Lines 268-273 $sth->execute( Link Here
268
    $sampleissuingrule2->{finedays},
274
    $sampleissuingrule2->{finedays},
269
    $sampleissuingrule2->{firstremind},
275
    $sampleissuingrule2->{firstremind},
270
    $sampleissuingrule2->{chargeperiod},
276
    $sampleissuingrule2->{chargeperiod},
277
    $sampleissuingrule2->{chargeperiod_charge_at},
271
    $sampleissuingrule2->{rentaldiscount},
278
    $sampleissuingrule2->{rentaldiscount},
272
    $sampleissuingrule2->{overduefinescap},
279
    $sampleissuingrule2->{overduefinescap},
273
    $sampleissuingrule2->{accountsent},
280
    $sampleissuingrule2->{accountsent},
Lines 295-300 $sth->execute( Link Here
295
    $sampleissuingrule3->{finedays},
302
    $sampleissuingrule3->{finedays},
296
    $sampleissuingrule3->{firstremind},
303
    $sampleissuingrule3->{firstremind},
297
    $sampleissuingrule3->{chargeperiod},
304
    $sampleissuingrule3->{chargeperiod},
305
    $sampleissuingrule3->{chargeperiod_charge_at},
298
    $sampleissuingrule3->{rentaldiscount},
306
    $sampleissuingrule3->{rentaldiscount},
299
    $sampleissuingrule3->{overduefinescap},
307
    $sampleissuingrule3->{overduefinescap},
300
    $sampleissuingrule3->{accountsent},
308
    $sampleissuingrule3->{accountsent},
(-)a/t/db_dependent/Fines.t (-1 / +56 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
5
use C4::Context;
6
use C4::Overdues;
7
use Koha::Database;
8
use Koha::DateUtils;
9
10
use Test::More tests => 5;
11
12
#Start transaction
13
my $dbh = C4::Context->dbh;
14
my $schema = Koha::Database->new()->schema();
15
16
$dbh->{RaiseError} = 1;
17
$dbh->{AutoCommit} = 0;
18
19
$dbh->do(q|DELETE FROM issuingrules|);
20
21
my $issuingrule = $schema->resultset('Issuingrule')->create(
22
    {
23
        categorycode           => '*',
24
        itemtype               => '*',
25
        branchcode             => '*',
26
        fine                   => 1,
27
        finedays               => 0,
28
        chargeperiod           => 7,
29
        chargeperiod_charge_at => 0,
30
        lengthunit             => 'days',
31
        issuelength            => 1,
32
    }
33
);
34
35
ok( $issuingrule, 'Issuing rule created' );
36
37
my $period_start = dt_from_string('2000-01-01');
38
my $period_end = dt_from_string('2000-01-05');
39
40
my ( $fine ) = CalcFine( {}, q{}, q{}, $period_start, $period_end  );
41
is( $fine, 0, '4 days overdue, charge period 7 days, charge at end of interval gives fine of $0' );
42
43
$period_end = dt_from_string('2000-01-10');
44
( $fine ) = CalcFine( {}, q{}, q{}, $period_start, $period_end  );
45
is( $fine, 1, '9 days overdue, charge period 7 days, charge at end of interval gives fine of $1' );
46
47
# Test charging fine at the *beginning* of each charge period
48
$issuingrule->update( { chargeperiod_charge_at => 1 } );
49
50
$period_end = dt_from_string('2000-01-05');
51
( $fine ) = CalcFine( {}, q{}, q{}, $period_start, $period_end  );
52
is( $fine, 1, '4 days overdue, charge period 7 days, charge at start of interval gives fine of $1' );
53
54
$period_end = dt_from_string('2000-01-10');
55
( $fine ) = CalcFine( {}, q{}, q{}, $period_start, $period_end  );
56
is( $fine, 2, '9 days overdue, charge period 7 days, charge at start of interval gives fine of $2' );

Return to bug 13590