Bug 17600: Standardize our EXPORT_OK
[srvgit] / misc / cronjobs / longoverdue.pl
index 9763937..dd12b6c 100755 (executable)
@@ -30,20 +30,20 @@ use warnings;
 BEGIN {
     # find Koha's Perl modules
     # test carefully before changing this
-    use FindBin;
+    use FindBin ();
     eval { require "$FindBin::Bin/../kohalib.pl" };
 }
 
-use Koha::Script -cron;
+use Getopt::Long qw( GetOptions );
+use Pod::Usage qw( pod2usage );
+
+use C4::Circulation qw( LostItem MarkIssueReturned );
 use C4::Context;
-use C4::Items;
-use C4::Circulation qw/LostItem MarkIssueReturned/;
-use Getopt::Long;
-use C4::Log;
-use Pod::Usage;
-use Koha::Patrons;
-use Koha::Patron::Categories;
+use C4::Log qw( cronlogaction );
 use Koha::ItemTypes;
+use Koha::Patron::Categories;
+use Koha::Patrons;
+use Koha::Script -cron;
 
 my  $lost;  #  key=lost value,  value=num days.
 my ($charge, $verbose, $confirm, $quiet);
@@ -57,23 +57,25 @@ my $help=0;
 my $man=0;
 my $list_categories = 0;
 my $list_itemtypes = 0;
+my @skip_lost_values;
 
 GetOptions(
-    'l|lost=s%'       => \$lost,
-    'c|charge=s'      => \$charge,
-    'confirm'         => \$confirm,
-    'v|verbose'       => \$verbose,
-    'quiet'           => \$quiet,
-    'maxdays=s'       => \$endrange,
-    'mark-returned'   => \$mark_returned,
-    'h|help'          => \$help,
-    'man|manual'      => \$man,
-    'category=s'      => $borrower_category,
-    'skip-category=s' => $skip_borrower_category,
-    'list-categories' => \$list_categories,
-    'itemtype=s'      => $itemtype,
-    'skip-itemtype=s' => $skip_itemtype,
-    'list-itemtypes'  => \$list_itemtypes,
+    'l|lost=s%'         => \$lost,
+    'c|charge=s'        => \$charge,
+    'confirm'           => \$confirm,
+    'v|verbose'         => \$verbose,
+    'quiet'             => \$quiet,
+    'maxdays=s'         => \$endrange,
+    'mark-returned'     => \$mark_returned,
+    'h|help'            => \$help,
+    'man|manual'        => \$man,
+    'category=s'        => $borrower_category,
+    'skip-category=s'   => $skip_borrower_category,
+    'list-categories'   => \$list_categories,
+    'itemtype=s'        => $itemtype,
+    'skip-itemtype=s'   => $skip_itemtype,
+    'list-itemtypes'    => \$list_itemtypes,
+    'skip-lost-value=s' => \@skip_lost_values,
 );
 
 if ( $man ) {
@@ -98,7 +100,7 @@ if ( scalar @$borrower_category && scalar @$skip_borrower_category) {
 
 if ( scalar @$itemtype && scalar @$skip_itemtype) {
     pod2usage( -verbose => 1,
-               -message => "The options --itemtype and --skip-itemtype are mually exclusive.\n"
+               -message => "The options --itemtype and --skip-itemtype are mutually exclusive.\n"
                            . "Use one or the other.",
                -exitval => 1
             );
@@ -123,6 +125,7 @@ if ( $list_itemtypes ) {
    longoverdue.pl --lost | -l DAYS=LOST_CODE [ --charge | -c CHARGE_CODE ] [ --verbose | -v ] [ --quiet ]
                   [ --maxdays MAX_DAYS ] [ --mark-returned ] [ --category BORROWER_CATEGORY ] ...
                   [ --skip-category BORROWER_CATEGORY ] ...
+                  [ --skip-lost-value LOST_VALUE [ --skip-lost-value LOST_VALUE ] ]
                   [ --commit ]
 
 
@@ -198,6 +201,11 @@ Act on all available itemtype codes, except those listed.
 This may be specified multiple times, to exclude multiple itemtypes.
 May not be used with B<--itemtype>
 
+=item B<--skip-lost-value>
+
+Act on all available lost values, except those listed.
+This may be specified multiple times, to exclude multiple lost values.
+
 =item B<--list-itemtypes>
 
 List itemtypes available for use by B<--itemtype> or
@@ -246,6 +254,12 @@ near-term release, so this script is not intended to have a long lifetime.
 # FIXME: do checks on --lost ranges to make sure the authorized values exist.
 # FIXME: do checks on --lost ranges to make sure don't go past endrange.
 #
+
+unless ( scalar @skip_lost_values ) {
+    my $preference = C4::Context->preference( 'DefaultLongOverdueSkipLostStatuses' );
+    @skip_lost_values = split( ',', $preference );
+}
+
 if ( ! defined($lost) ) {
     my $longoverdue_value = C4::Context->preference('DefaultLongOverdueLostValue');
     my $longoverdue_days = C4::Context->preference('DefaultLongOverdueDays');
@@ -255,7 +269,7 @@ if ( ! defined($lost) ) {
     else {
         pod2usage( {
                 -exitval => 1,
-                -msg => q|ERROR: No --lost (-l) option defined|,
+                -msg => q|ERROR: No --lost (-l) option or system preferences DefaultLongOverdueLostValue/DefaultLongOverdueDays defined|,
         } );
     }
 }
@@ -275,20 +289,30 @@ cronlogaction();
 # In my opinion, this line is safe SQL to have outside the API. --atz
 our $bounds_sth = C4::Context->dbh->prepare("SELECT DATE_SUB(CURDATE(), INTERVAL ? DAY)");
 
-sub bounds ($) {
+sub bounds {
     $bounds_sth->execute(shift);
     return $bounds_sth->fetchrow;
 }
 
 # FIXME - This sql should be inside the API.
 sub longoverdue_sth {
+    my ( $params ) = @_;
+    my $skip_lost_values = $params->{skip_lost_values};
+
+    my $skip_lost_values_sql = q{};
+    if ( @$skip_lost_values ) {
+        my $values = join( ',', map { qq{'$_'} } @$skip_lost_values );
+        $skip_lost_values_sql = "AND itemlost NOT IN ( $values )"
+    }
+
     my $query = "
-    SELECT items.itemnumber, borrowernumber, date_due
+    SELECT items.itemnumber, borrowernumber, date_due, itemlost
       FROM issues, items
      WHERE items.itemnumber = issues.itemnumber
       AND  DATE_SUB(CURDATE(), INTERVAL ? DAY)  > date_due
       AND  DATE_SUB(CURDATE(), INTERVAL ? DAY) <= date_due
       AND  itemlost <> ?
+      $skip_lost_values_sql
      ORDER BY date_due
     ";
     return C4::Context->dbh->prepare($query);
@@ -301,7 +325,7 @@ $borrower_category = [ map { uc $_ } @$borrower_category ];
 $skip_borrower_category = [ map { uc $_} @$skip_borrower_category ];
 my %category_to_process;
 for my $cat ( @$borrower_category ) {
-    unless ( grep { /^$cat$/ } @available_categories ) {
+    unless ( grep { $_ eq $cat } @available_categories ) {
         pod2usage(
             '-exitval' => 1,
             '-message' => "The category $cat does not exist in the database",
@@ -311,7 +335,7 @@ for my $cat ( @$borrower_category ) {
 }
 if ( @$skip_borrower_category ) {
     for my $cat ( @$skip_borrower_category ) {
-        unless ( grep { /^$cat$/ } @available_categories ) {
+        unless ( grep { $_ eq $cat } @available_categories ) {
             pod2usage(
                 '-exitval' => 1,
                 '-message' => "The category $cat does not exist in the database",
@@ -329,7 +353,7 @@ $itemtype = [ map { uc $_ } @$itemtype ];
 $skip_itemtype = [ map { uc $_} @$skip_itemtype ];
 my %itemtype_to_process;
 for my $it ( @$itemtype ) {
-    unless ( grep { /^$it$/ } @available_itemtypes ) {
+    unless ( grep { $_ eq $it } @available_itemtypes ) {
         pod2usage(
             '-exitval' => 1,
             '-message' => "The itemtype $it does not exist in the database",
@@ -339,7 +363,7 @@ for my $it ( @$itemtype ) {
 }
 if ( @$skip_itemtype ) {
     for my $it ( @$skip_itemtype ) {
-        unless ( grep { /^$it$/ } @available_itemtypes ) {
+        unless ( grep { $_ eq $it } @available_itemtypes ) {
             pod2usage(
                 '-exitval' => 1,
                 '-message' => "The itemtype $it does not exist in the database",
@@ -360,7 +384,7 @@ my $i = 0;
 # FIXME - The item is only marked returned if you supply --charge .
 #         We need a better way to handle this.
 #
-my $sth_items = longoverdue_sth();
+my $sth_items = longoverdue_sth({ skip_lost_values => \@skip_lost_values });
 
 foreach my $startrange (sort keys %$lost) {
     if( my $lostvalue = $lost->{$startrange} ) {
@@ -383,7 +407,8 @@ foreach my $startrange (sort keys %$lost) {
             }
             printf ("Due %s: item %5s from borrower %5s to lost: %s\n", $row->{date_due}, $row->{itemnumber}, $row->{borrowernumber}, $lostvalue) if($verbose);
             if($confirm) {
-                ModItem({ itemlost => $lostvalue }, $row->{'biblionumber'}, $row->{'itemnumber'});
+                Koha::Items->find( $row->{itemnumber} )->itemlost($lostvalue)
+                  ->store;
                 if ( $charge && $charge eq $lostvalue ) {
                     LostItem( $row->{'itemnumber'}, 'cronjob', $mark_returned );
                 } elsif ( $mark_returned ) {
@@ -407,10 +432,10 @@ foreach my $startrange (sort keys %$lost) {
     $endrange = $startrange;
 }
 
-sub summarize ($$) {
+sub summarize {
     my $arg = shift;    # ref to array
     my $got_items = shift || 0;     # print "count" line for items
-    my @report = @$arg or return undef;
+    my @report = @$arg or return;
     my $i = 0;
     for my $range (@report) {
         printf "\nRange %s\nDue %3s - %3s days ago (%s to %s), lost => %s\n", ++$i,