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