Lines 36-50
use C4::Overdues;
Link Here
|
36 |
use Getopt::Long; |
36 |
use Getopt::Long; |
37 |
use Carp; |
37 |
use Carp; |
38 |
use File::Spec; |
38 |
use File::Spec; |
|
|
39 |
use Fcntl qw(:flock); |
39 |
|
40 |
|
40 |
use Koha::Calendar; |
41 |
use Koha::Calendar; |
41 |
use Koha::DateUtils; |
42 |
use Koha::DateUtils; |
42 |
use C4::Log; |
43 |
use C4::Log; |
43 |
|
44 |
|
|
|
45 |
use constant LOCK_FILENAME => 'fines..LCK'; |
46 |
|
44 |
my $help; |
47 |
my $help; |
45 |
my $verbose; |
48 |
my $verbose; |
46 |
my $output_dir; |
49 |
my $output_dir; |
47 |
my $log; |
50 |
my $log; |
|
|
51 |
my $use_flock = 1; |
48 |
|
52 |
|
49 |
GetOptions( |
53 |
GetOptions( |
50 |
'h|help' => \$help, |
54 |
'h|help' => \$help, |
Lines 74-79
if ($help) {
Link Here
|
74 |
|
78 |
|
75 |
cronlogaction(); |
79 |
cronlogaction(); |
76 |
|
80 |
|
|
|
81 |
my ($lockfile, $LockFH); |
82 |
foreach ( |
83 |
'/var/lock/koha', |
84 |
'/var/lock/koha_fines', |
85 |
'/tmp/koha_fines' |
86 |
) { |
87 |
#we try three possibilities (we really want to lock :) |
88 |
next if !$_; |
89 |
($LockFH, $lockfile) = _create_lockfile($_); |
90 |
last if defined $LockFH; |
91 |
} |
92 |
if( !defined $LockFH ) { |
93 |
print "WARNING: Could not create lock file $lockfile: $!\n"; |
94 |
print "Verify if directories /var/lock/koha/". C4::Context->config('database').", /var/lock/koha_fines_" . C4::Context->config('database')." or /tmp/koha_fines_" . C4::Context->config('database')." exist and check file permissions\n"; |
95 |
$use_flock = 0; # we disable file locking now and will continue |
96 |
# without it |
97 |
# note that this mimics old behavior (before we used |
98 |
# the lockfile) |
99 |
}; |
100 |
|
77 |
my @borrower_fields = |
101 |
my @borrower_fields = |
78 |
qw(cardnumber categorycode surname firstname email phone address citystate); |
102 |
qw(cardnumber categorycode surname firstname email phone address citystate); |
79 |
my @item_fields = qw(itemnumber barcode date_due); |
103 |
my @item_fields = qw(itemnumber barcode date_due); |
Lines 98-175
if ($filename) {
Link Here
|
98 |
} |
122 |
} |
99 |
my $counted = 0; |
123 |
my $counted = 0; |
100 |
my $overdues = Getoverdues(); |
124 |
my $overdues = Getoverdues(); |
101 |
for my $overdue ( @{$overdues} ) { |
125 |
if(_flock($LockFH, LOCK_EX|LOCK_NB)) { |
102 |
next if $overdue->{itemlost}; |
126 |
for my $overdue ( @{$overdues} ) { |
103 |
|
127 |
next if $overdue->{itemlost}; |
104 |
if ( !defined $overdue->{borrowernumber} ) { |
128 |
|
105 |
carp |
129 |
if ( !defined $overdue->{borrowernumber} ) { |
106 |
"ERROR in Getoverdues : issues.borrowernumber IS NULL. Repair 'issues' table now! Skipping record.\n"; |
130 |
carp |
107 |
next; |
131 |
"ERROR in Getoverdues : issues.borrowernumber IS NULL. Repair 'issues' table now! Skipping record.\n"; |
108 |
} |
132 |
next; |
109 |
my $borrower = BorType( $overdue->{borrowernumber} ); |
133 |
} |
110 |
my $branchcode = |
134 |
my $borrower = BorType( $overdue->{borrowernumber} ); |
111 |
( $control eq 'ItemHomeLibrary' ) ? $overdue->{homebranch} |
135 |
my $branchcode = |
112 |
: ( $control eq 'PatronLibrary' ) ? $borrower->{branchcode} |
136 |
( $control eq 'ItemHomeLibrary' ) ? $overdue->{homebranch} |
113 |
: $overdue->{branchcode}; |
137 |
: ( $control eq 'PatronLibrary' ) ? $borrower->{branchcode} |
114 |
|
138 |
: $overdue->{branchcode}; |
115 |
# In final case, CircControl must be PickupLibrary. (branchcode comes from issues table here). |
139 |
|
116 |
if ( !exists $is_holiday{$branchcode} ) { |
140 |
# In final case, CircControl must be PickupLibrary. (branchcode comes from issues table here). |
117 |
$is_holiday{$branchcode} = set_holiday( $branchcode, $today ); |
141 |
if ( !exists $is_holiday{$branchcode} ) { |
118 |
} |
142 |
$is_holiday{$branchcode} = set_holiday( $branchcode, $today ); |
|
|
143 |
} |
119 |
|
144 |
|
120 |
my $datedue = dt_from_string( $overdue->{date_due} ); |
145 |
my $datedue = dt_from_string( $overdue->{date_due} ); |
121 |
if ( DateTime->compare( $datedue, $today ) == 1 ) { |
146 |
if ( DateTime->compare( $datedue, $today ) == 1 ) { |
122 |
next; # not overdue |
147 |
next; # not overdue |
123 |
} |
148 |
} |
124 |
++$counted; |
149 |
++$counted; |
125 |
|
150 |
|
126 |
my ( $amount, $unitcounttotal, $unitcount ) = |
151 |
my ( $amount, $unitcounttotal, $unitcount ) = |
127 |
CalcFine( $overdue, $borrower->{categorycode}, |
152 |
CalcFine( $overdue, $borrower->{categorycode}, |
128 |
$branchcode, $datedue, $today ); |
153 |
$branchcode, $datedue, $today ); |
129 |
|
154 |
|
130 |
# Don't update the fine if today is a holiday. |
155 |
# Don't update the fine if today is a holiday. |
131 |
# This ensures that dropbox mode will remove the correct amount of fine. |
156 |
# This ensures that dropbox mode will remove the correct amount of fine. |
132 |
if ( $mode eq 'production' && !$is_holiday{$branchcode} ) { |
157 |
if ( $mode eq 'production' && !$is_holiday{$branchcode} ) { |
133 |
if ( $amount && $amount > 0 ) { |
158 |
if ( $amount && $amount > 0 ) { |
134 |
UpdateFine( |
159 |
UpdateFine( |
135 |
{ |
160 |
{ |
136 |
issue_id => $overdue->{issue_id}, |
161 |
issue_id => $overdue->{issue_id}, |
137 |
itemnumber => $overdue->{itemnumber}, |
162 |
itemnumber => $overdue->{itemnumber}, |
138 |
borrowernumber => $overdue->{borrowernumber}, |
163 |
borrowernumber => $overdue->{borrowernumber}, |
139 |
amount => $amount, |
164 |
amount => $amount, |
140 |
due => output_pref($datedue), |
165 |
due => output_pref($datedue), |
141 |
} |
166 |
} |
142 |
); |
167 |
); |
|
|
168 |
} |
169 |
} |
170 |
if ($filename) { |
171 |
my @cells; |
172 |
push @cells, |
173 |
map { defined $borrower->{$_} ? $borrower->{$_} : q{} } |
174 |
@borrower_fields; |
175 |
push @cells, map { $overdue->{$_} } @item_fields; |
176 |
push @cells, $unitcounttotal, $amount; |
177 |
say {$fh} join $delim, @cells; |
143 |
} |
178 |
} |
144 |
} |
179 |
} |
145 |
if ($filename) { |
180 |
if ($filename){ |
146 |
my @cells; |
181 |
close $fh; |
147 |
push @cells, |
|
|
148 |
map { defined $borrower->{$_} ? $borrower->{$_} : q{} } |
149 |
@borrower_fields; |
150 |
push @cells, map { $overdue->{$_} } @item_fields; |
151 |
push @cells, $unitcounttotal, $amount; |
152 |
say {$fh} join $delim, @cells; |
153 |
} |
182 |
} |
154 |
} |
|
|
155 |
if ($filename){ |
156 |
close $fh; |
157 |
} |
158 |
|
183 |
|
159 |
if ($verbose) { |
184 |
if ($verbose) { |
160 |
my $overdue_items = @{$overdues}; |
185 |
my $overdue_items = @{$overdues}; |
161 |
print <<"EOM"; |
186 |
print <<"EOM"; |
162 |
Fines assessment -- $today |
187 |
Fines assessment -- $today |
163 |
EOM |
188 |
EOM |
164 |
if ($filename) { |
189 |
if ($filename) { |
165 |
say "Saved to $filename"; |
190 |
say "Saved to $filename"; |
166 |
} |
191 |
} |
167 |
print <<"EOM"; |
192 |
print <<"EOM"; |
168 |
Number of Overdue Items: |
193 |
Number of Overdue Items: |
169 |
counted $overdue_items |
194 |
counted $overdue_items |
170 |
reported $counted |
195 |
reported $counted |
171 |
|
196 |
|
172 |
EOM |
197 |
EOM |
|
|
198 |
} |
199 |
_flock($LockFH, LOCK_UN); |
200 |
} else { |
201 |
print "Skipping fines assessment because flock failed on $lockfile: $!\n"; |
173 |
} |
202 |
} |
174 |
|
203 |
|
175 |
sub set_holiday { |
204 |
sub set_holiday { |
Lines 196-198
sub get_filename {
Link Here
|
196 |
} |
225 |
} |
197 |
return $name; |
226 |
return $name; |
198 |
} |
227 |
} |
199 |
- |
228 |
|
|
|
229 |
sub _create_lockfile { #returns undef on failure |
230 |
my $dir= shift; |
231 |
unless (-d $dir) { |
232 |
eval { mkpath($dir, 0, oct(755)) }; |
233 |
return if $@; |
234 |
} |
235 |
return if !open my $fh, q{>}, $dir.'/'.LOCK_FILENAME; |
236 |
return ( $fh, $dir.'/'.LOCK_FILENAME ); |
237 |
} |
238 |
|
239 |
sub _flock { |
240 |
my ($fh, $op)= @_; |
241 |
return 1 if !$use_flock; |
242 |
|
243 |
#check if flock is present; if not, you will have a fatal error |
244 |
my $lock_acquired = eval { flock($fh, $op) }; |
245 |
|
246 |
# assuming that $fh and $op are fine(..), an undef $lock_acquired |
247 |
# means no flock |
248 |
$use_flock = defined($lock_acquired) ? 1 : 0; |
249 |
print "Warning: flock could not be used!\n" if !$use_flock; |
250 |
return 1 if !$use_flock; |
251 |
return $lock_acquired; |
252 |
} |