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

(-)a/misc/cronjobs/fines.pl (-62 / +94 lines)
Lines 26-55 Link Here
26
# You should have received a copy of the GNU General Public License
26
# You should have received a copy of the GNU General Public License
27
# along with Koha; if not, see <http://www.gnu.org/licenses>.
27
# along with Koha; if not, see <http://www.gnu.org/licenses>.
28
28
29
use strict;
29
use Modern::Perl;
30
use warnings;
31
use 5.010;
32
30
33
use C4::Context;
34
use C4::Overdues;
35
use Getopt::Long;
36
use Carp;
31
use Carp;
37
use File::Spec;
32
use File::Spec;
33
use Getopt::Long;
34
use Parallel::ForkManager;
35
36
use C4::Context;
37
use C4::Overdues;
38
use C4::Log;
38
39
39
use Koha::Calendar;
40
use Koha::Calendar;
40
use Koha::DateUtils;
41
use Koha::DateUtils;
41
use C4::Log;
42
42
43
my $help;
43
my $help;
44
my $verbose;
44
my $verbose;
45
my $output_dir;
45
my $output_dir;
46
my $log;
46
my $log;
47
my $max_processes = 0;
47
48
48
GetOptions(
49
GetOptions(
49
    'h|help'    => \$help,
50
    'h|help'            => \$help,
50
    'v|verbose' => \$verbose,
51
    'v|verbose'         => \$verbose,
51
    'l|log'     => \$log,
52
    'l|log'             => \$log,
52
    'o|out:s'   => \$output_dir,
53
    'o|out:s'           => \$output_dir,
54
    'm|max-processes:s' => \$max_processes,
53
);
55
);
54
my $usage = << 'ENDUSAGE';
56
my $usage = << 'ENDUSAGE';
55
57
Lines 63-68 This script has the following parameters : Link Here
63
    -l --log: log the output to a file (optional if the -o parameter is given)
65
    -l --log: log the output to a file (optional if the -o parameter is given)
64
    -o --out:  ouput directory for logs (defaults to env or /tmp if !exist)
66
    -o --out:  ouput directory for logs (defaults to env or /tmp if !exist)
65
    -v --verbose
67
    -v --verbose
68
    -m --max-processes: The maximum number of concurrent fine calculating processes
66
69
67
ENDUSAGE
70
ENDUSAGE
68
71
Lines 97-158 if ($filename) { Link Here
97
}
100
}
98
my $counted = 0;
101
my $counted = 0;
99
my $overdues = Getoverdues();
102
my $overdues = Getoverdues();
100
for my $overdue ( @{$overdues} ) {
101
    next if $overdue->{itemlost};
102
103
103
    if ( !defined $overdue->{borrowernumber} ) {
104
# Break out overdues per patron, this is needed in case we process overdues
104
        carp
105
# in parallel. All overdues for a single patron still need to be handled by
105
"ERROR in Getoverdues : issues.borrowernumber IS NULL.  Repair 'issues' table now!  Skipping record.\n";
106
# a single process in case there are fine limits in place that need to account
106
        next;
107
# for previous fines. If they were in parallel the math would be incorrect.
107
    }
108
my $overdues_by_patron;
108
    my $borrower = BorType( $overdue->{borrowernumber} );
109
map { push( @{$overdues_by_patron->{ $_->{borrowernumber} } }, $_ ) } @$overdues;
109
    my $branchcode =
110
110
        ( $control eq 'ItemHomeLibrary' ) ? $overdue->{homebranch}
111
my $pm = Parallel::ForkManager->new( $max_processes, '/tmp' );
111
      : ( $control eq 'PatronLibrary' )   ? $borrower->{branchcode}
112
$pm->run_on_finish(    # called BEFORE the first call to start()
112
      :                                     $overdue->{branchcode};
113
    sub {
113
114
        my ( $pid, $exit_code, $ident, $exit_signal, $core_dump, $data ) = @_;
114
# In final case, CircControl must be PickupLibrary. (branchcode comes from issues table here).
115
    if ( !exists $is_holiday{$branchcode} ) {
116
        $is_holiday{$branchcode} = set_holiday( $branchcode, $today );
117
    }
118
115
119
    my $datedue = dt_from_string( $overdue->{date_due} );
116
        $counted++ if $exit_code;
120
    if ( DateTime->compare( $datedue, $today ) == 1 ) {
121
        next;    # not overdue
122
    }
117
    }
123
    ++$counted;
118
);
124
119
125
    my ( $amount, $type, $unitcounttotal ) =
120
OVERDUES_LOOP:
126
      CalcFine( $overdue, $borrower->{categorycode},
121
for my $patron_id ( keys %$overdues_by_patron ) {
127
        $branchcode, $datedue, $today );
122
    my @overdues = @{$overdues_by_patron->{$patron_id}};
128
    $type ||= q{};
123
129
124
    my $pid = $pm->start and next OVERDUES_LOOP;
130
    # Don't update the fine if today is a holiday.
125
    for my $overdue ( @overdues ) {
131
    # This ensures that dropbox mode will remove the correct amount of fine.
126
        my $counted = 0;
132
    if ( $mode eq 'production' && !$is_holiday{$branchcode} ) {
127
        next if $overdue->{itemlost};
133
        if ( $amount > 0 ) {
128
134
            UpdateFine(
129
        if ( !defined $overdue->{borrowernumber} ) {
135
                {
130
            carp "ERROR in Getoverdues : issues.borrowernumber IS NULL.  Repair 'issues' table now!  Skipping record.\n";
136
                    issue_id       => $overdue->{issue_id},
131
            next;
137
                    itemnumber     => $overdue->{itemnumber},
138
                    borrowernumber => $overdue->{borrowernumber},
139
                    amount         => $amount,
140
                    type           => $type,
141
                    due            => output_pref($datedue),
142
                }
143
            );
144
        }
132
        }
133
134
135
        my $borrower = BorType( $overdue->{borrowernumber} );
136
        my $branchcode =
137
            ( $control eq 'ItemHomeLibrary' ) ? $overdue->{homebranch}
138
          : ( $control eq 'PatronLibrary' )   ? $borrower->{branchcode}
139
          :                                     $overdue->{branchcode};
140
141
        # In final case, CircControl must be PickupLibrary. (branchcode comes from issues table here).
142
        if ( !exists $is_holiday{$branchcode} ) {
143
            $is_holiday{$branchcode} = set_holiday( $branchcode, $today );
144
        }
145
146
        my $datedue = dt_from_string( $overdue->{date_due} );
147
        if ( DateTime->compare( $datedue, $today ) == 1 ) {
148
            $pm->finish(0);    # not overdue
149
        }
150
151
        my ( $amount, $type, $unitcounttotal ) =
152
          CalcFine( $overdue, $borrower->{categorycode},
153
            $branchcode, $datedue, $today );
154
        $type ||= q{};
155
156
        # Don't update the fine if today is a holiday.
157
        # This ensures that dropbox mode will remove the correct amount of fine.
158
        if ( $mode eq 'production' && !$is_holiday{$branchcode} ) {
159
            if ( $amount > 0 ) {
160
                UpdateFine(
161
                    {
162
                        issue_id       => $overdue->{issue_id},
163
                        itemnumber     => $overdue->{itemnumber},
164
                        borrowernumber => $overdue->{borrowernumber},
165
                        amount         => $amount,
166
                        type           => $type,
167
                        due            => output_pref($datedue),
168
                    }
169
                );
170
            }
171
        }
172
        if ($filename) {
173
            my @cells;
174
            push @cells,
175
              map { defined $borrower->{$_} ? $borrower->{$_} : q{} }
176
              @borrower_fields;
177
            push @cells, map { $overdue->{$_} } @item_fields;
178
            push @cells, $type, $unitcounttotal, $amount;
179
            say {$fh} join $delim, @cells;
180
        }
181
182
        $counted++;
145
    }
183
    }
146
    if ($filename) {
184
    $pm->finish($counted);
147
        my @cells;
148
        push @cells,
149
          map { defined $borrower->{$_} ? $borrower->{$_} : q{} }
150
          @borrower_fields;
151
        push @cells, map { $overdue->{$_} } @item_fields;
152
        push @cells, $type, $unitcounttotal, $amount;
153
        say {$fh} join $delim, @cells;
154
    }
155
}
185
}
186
187
$pm->wait_all_children;
188
156
if ($filename){
189
if ($filename){
157
    close $fh;
190
    close $fh;
158
}
191
}
159
- 

Return to bug 16528