|
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 |
- |
|
|