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

(-)a/misc/cronjobs/fines.pl (-65 / +118 lines)
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
}

Return to bug 23571