Bug 17600: Standardize our EXPORT_OK
[srvgit] / misc / cronjobs / update_patrons_category.pl
old mode 100644 (file)
new mode 100755 (executable)
index e426803..542cc30
@@ -20,18 +20,18 @@ use Modern::Perl;
 BEGIN {
     # find Koha's Perl modules
     # test carefully before changing this
-    use FindBin;
+    use FindBin ();
     eval { require "$FindBin::Bin/../kohalib.pl" };
 }
 
 use C4::Context;
-use Getopt::Long;
-use Pod::Usage;
+use Getopt::Long qw( GetOptions );
+use Pod::Usage qw( pod2usage );
 use Koha::Logger;
 use Koha::Patrons;
 use Koha::Patron::Categories;
-use Koha::DateUtils;
-use Data::Dumper;
+use Koha::DateUtils qw( dt_from_string );
+use Koha::Script -cron;
 
 =head1 NAME
 
@@ -40,22 +40,24 @@ update_patrons_category.pl - Given a set of parameters update selected patrons f
 =head1 SYNOPSIS
 
 update_patrons_category.pl -f=categorycode -t=categorycode
-                          [-b=branchcode] [-au] [-ao] [-fo=X] [-fu=X]
+                          [-b=branchcode] [--too_old] [--too_young] [-fo=X] [-fu=X]
                           [-rb=date] [-ra=date] [-v]
                           [--field column=value ...]
 
 update_patrons_category.pl --help | --man
 
 Options:
+
    --help                   brief help message
    --man                    full documentation
-   -ao --ageover            update if over  maximum age for current category
-   -au --ageunder           update if under minimuum age  current category
+   -too_old                 update if over  maximum age for current category
+   -too_young               update if under minimuum age  current category
    -fo=X --fineover=X       update if fines over  X amount
    -fu=X --fineunder=X      update if fines under X amount
    -rb=date --regbefore     update if registration date is before given date
    -ra=date --regafter      update if registration date is after a given date
-   -d --dbfield name=value    where <name> is a column in the borrowers table, patrons will be updated if the field is equal to given <value>
+   -d --field name=value    where <name> is a column in the borrowers table, patrons will be updated if the field is equal to given <value>
+   --where <conditions>     where clause to add to the query
    -v -verbose              verbose mode
    -c --confirm             commit changes to db, no action will be taken unless this switch is included
    -b --branch <branchname> only deal with patrons from this library/branch
@@ -74,7 +76,7 @@ Print a brief help message and exits.
 
 Prints the manual page and exits.
 
-=item B<--verbosse | -v>
+=item B<--verbose | -v>
 
 Verbose. Without this flag set, only fatal errors are reported.
 
@@ -95,11 +97,11 @@ branches.branchcode table.
 
 *required* defines the category patrons will be converted to. Expects the code from categories.categorycode.
 
-=item B<--ageover | -ao>
+=item B<--too_old>
 
 Update patron only if they are above the maximum age range specified for the 'from' category.
 
-=item B<--ageunde | -au>
+=item B<--too_young>
 
 Update patron only if they are below the minimum age range specified for the 'from' category.
 
@@ -107,7 +109,7 @@ Update patron only if they are below the minimum age range specified for the 'fr
 
 Supply a number and only account with fines over this number will be updated.
 
-=item B<==fineunder=X | -fu=X>
+=item B<--fineunder=X | -fu=X>
 
 Supply a number and only account with fines under this number will be updated.
 
@@ -121,12 +123,27 @@ Enter a date in ISO format YYYY-MM-DD and only patrons registered after this dat
 
 =item B<--field column=value | -d column=value>
 
-Use this flag to specify a column in the borrowers table and update only patrons whose value in that column matches the value supplied (repeatable)
+Use this flag to specify a column in the borrowers table and update only patrons whose value in that column equals the value supplied (repeatable)
+A value of null will check for a field that is not set.
 
 e.g.
 --field dateexpiry=2016-01-01
 will update all patrons who expired on that date, useful for schools etc.
 
+=item B<--where $conditions>
+
+Use this option to specify a condition built with columns from the borrowers table
+
+e.g.
+--where 'email IS NULL'
+will update all patrons with no value for email
+
+--where 'categorycode LIKE "%CHILD"'
+will update all patrons with a category ending in CHILD.
+
+--where 'categorycode LIKE RESIDENT%'
+will update all patrons whose category does not begin with RESIDENT.
+
 =back
 
 =head1 DESCRIPTION
@@ -139,7 +156,7 @@ C<update_patron_categories.pl> - Suggests that you read this help. :)
 
 C<update_patron_categories.pl> -b=<branchcode> -f=<categorycode> -t=<categorycode> --confirm  - Processes a single branch, and updates the patron categories from fromcat to tocat.
 
-C<update_patron_categories.pl> -b=<branchcode> -f=<categorycode> -t=<categorycode>  -a --confirm  - Processes a single branch, and updates the patron categories from fromcat to tocat for patrons outside the age range of fromcat.
+C<update_patron_categories.pl> -b=<branchcode> -f=<categorycode> -t=<categorycode>  --too_old --confirm  - Processes a single branch, and updates the patron categories from fromcat to tocat for patrons over the age range of fromcat.
 
 C<update_patron_categories.pl> -f=<categorycode> -t=<categorycode> -v  - Processes all branches, shows all messages, and reports the patrons who would be affected. Takes no action on the database.
 
@@ -152,10 +169,8 @@ my $help    = 0;
 my $man     = 0;
 my $verbose = 0;
 my $doit    = 0;
-my $au;
-my $ao;
-my $min_dob;
-my $max_dob;
+my $ageunder;
+my $ageover;
 my $remove_guarantors = 0;
 my $fine_min;
 my $fine_max;
@@ -165,6 +180,7 @@ my $reg_bef;
 my $reg_aft;
 my $branch_lim;
 my %fields;
+my @where;
 
 GetOptions(
     'help|?'          => \$help,
@@ -173,33 +189,30 @@ GetOptions(
     'c|confirm'       => \$doit,
     'f|from=s'        => \$fromcat,
     't|to=s'          => \$tocat,
-    'ao|ageover'      => \$ageover,
-    'au|ageunder'     => \$ageunder,
+    'too_old'         => \$ageover,
+    'too_young'       => \$ageunder,
     'fo|finesover=s'  => \$fine_min,
     'fu|finesunder=s' => \$fine_max,
     'rb|regbefore=s'  => \$reg_bef,
     'ra|regafter=s'   => \$reg_aft,
     'b|branch=s'      => \$branch_lim,
-    'd|field=s'       => \%fields
-) or pod2usage(2);
+    'd|field=s'       => \%fields,
+    'where=s'         => \@where,
+);
+
 pod2usage(1) if $help;
-pod2usage( -verbose => 2 ) if $man;
 
-warn "v $verbose c $doit f $fromcat t $tocat";
-warn Data::Dumper::Dumper(%fields);
-exit;
+pod2usage( -verbose => 2 ) if $man;
 
 if ( not $fromcat && $tocat ) {    #make sure we've specified the info we need.
-    print
-"Must supply category from and to (-f & -t) please specify -help for usage tips.\n";
+    print "Must supply category from and to (-f & -t) please specify -help for usage tips.\n";
+    pod2usage(1);
     exit;
 }
 
 ( $verbose && !$doit ) and print "No actions will be taken (test mode)\n";
 
-$verbose
-  and print
-"Will update patrons from $fromcat to $tocat with conditions below (if any)\n";
+$verbose and print "Will update patrons from $fromcat to $tocat with conditions below (if any)\n";
 
 my %params;
 
@@ -209,15 +222,13 @@ if ( $reg_bef || $reg_aft ) {
     if ( defined $reg_bef ) {
         eval { $date_bef = dt_from_string( $reg_bef, 'iso' ); };
     }
-    die
-"$reg_bef is not a valid date before, aborting! Use a date in format YYYY-MM-DD.$@"
-      if $@;
+    die "$reg_bef is not a valid date before, aborting! Use a date in format YYYY-MM-DD.$@"
+        if $@;
     if ( defined $reg_aft ) {
         eval { $date_aft = dt_from_string( $reg_aft, 'iso' ); };
     }
-    die
-"$reg_bef is not a valid date after, aborting! Use a date in format YYYY-MM-DD.$@"
-      if $@;
+    die "$reg_bef is not a valid date after, aborting! Use a date in format YYYY-MM-DD.$@"
+        if $@;
     $params{dateenrolled}{'<='} = $reg_bef if defined $date_bef;
     $params{dateenrolled}{'>='} = $reg_aft if defined $date_aft;
 }
@@ -243,37 +254,42 @@ if ($verbose) {
 }
 
 while ( my ( $key, $value ) = each %fields ) {
-    $verbose and print "    Borrower column $key is equal to $value\n";
+    $verbose and print "    Borrower column $key is $value\n";
+    $value = undef if lc($value) eq 'null';
     $params{ "me." . $key } = $value;
 }
 
-my $target_patrons = Koha::Patrons->search_patrons_to_update(
+my $where_literal = join ' AND ', @where;
+my $target_patrons = Koha::Patrons->search( \%params );
+$target_patrons = $target_patrons->search( \$where_literal ) if @where;
+$target_patrons = $target_patrons->search_patrons_to_update_category(
     {
         from          => $fromcat,
         search_params => \%params,
-        ageunder      => $ageunder,
-        ageover       => $ageover,
+        too_young     => $ageunder,
+        too_old       => $ageover,
         fine_min      => $fine_min,
         fine_max      => $fine_max,
     }
 );
+
 my $patrons_found    = $target_patrons->count;
 my $actually_updated = 0;
 my $testdisplay      = $doit ? "" : "WOULD HAVE ";
 if ($verbose) {
     while ( my $target_patron = $target_patrons->next() ) {
-        my $target = Koha::Patrons->find( $target_patron->borrowernumber );
+        $target_patron->discard_changes();
         $verbose
           and print $testdisplay
           . "Updated "
-          . $target->firstname . " "
-          . $target->surname
+          . $target_patron->firstname() . " "
+          . $target_patron->surname()
           . " from $fromcat to $tocat\n";
     }
     $target_patrons->reset;
 }
 if ($doit) {
-    $actually_updated = $target_patrons->update_category( { to => $tocat } );
+    $actually_updated = $target_patrons->update_category_to( { category => $tocat } );
 }
 
 $verbose and print "$patrons_found found, $actually_updated updated\n";