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

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

Return to bug 23571