#!/usr/bin/perl

# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <https://www.gnu.org/licenses>.

use Modern::Perl;

use Getopt::Long qw( GetOptions );
use Pod::Usage   qw( pod2usage );

use Koha::Script -cron;
use C4::Biblio qw( DelBiblio );
use Koha::Items;

my @where          = ();
my $verbose        = 0;
my $help           = 0;
my $manual         = 0;
my $commit         = 0;
my $delete_biblios = 0;

GetOptions(
    'where=s'  => \@where, 'v|verbose' => \$verbose,
    'h|help'   => \$help,
    'm|manual' => \$manual,
    'c|commit' => \$commit,
    'del_bibs' => \$delete_biblios
);

pod2usage( -verbose => 2 )                                                            if $manual;
pod2usage( -verbose => 1 )                                                            if $help;
pod2usage( -verbose => 1, -message => 'You must supply at least one --where option' ) if scalar @where == 0;

my $where_clause = join( " AND ", @where );

$verbose && say "Where statement: $where_clause";
if ($delete_biblios) {
    $verbose && say "Deleting bibliographic records when all items are deleted!";
}

print "Test run only! No data will be deleted.\n" unless $commit;
my $deleted_string = $commit ? "Deleted" : "Would have deleted";

my $items = Koha::Items->search( \$where_clause );

DELITEM: while ( my $item = $items->next ) {

    my $safe_to_delete = $item->safe_to_delete;
    my $error;
    if ($safe_to_delete) {
        my $holdings_count = $item->biblio->items->count - 1;
        $item->safe_delete
            if $commit;
        $verbose && say "$deleted_string item " . $item->itemnumber . " ($holdings_count items remain on record)";

        if ( $delete_biblios && $holdings_count == 0 ) {    # aka DO-EET for empty bibs!
            $error = &DelBiblio( $item->biblionumber ) if $commit;
            if ($error) {
                $verbose && say "Could not delete bib " . $item->biblionumber . ": $error";
            } else {
                $verbose && say "No items remaining. $deleted_string bibliographic record " . $item->biblionumber;
            }
        }
    } else {
        say sprintf(
            "Item '%s' (Barcode: '%s', Title: '%s') cannot deleted: %s",
            $item->itemnumber,
            $item->barcode,
            $item->biblio->title,
            @{ $safe_to_delete->messages }[0]->message
        ) if $verbose;
    }
}

=head1 NAME

delete_items.pl - A batch item deletion tool, which generates a query against the items database and deletes the items matching the criteria specified in the command line arguments.

=head1 SYNOPSIS

delete_items.pl [--help|--manual]

delete_items.pl [--verbose] --where "I<SQL CONDITIONAL EXPRESSION>" ... [--commit]

=cut

=head1 OPTIONS

=over 8

=item B<--help>

Show the brief help information.

=item B<--manual>

Read the manual, with examples.

=item B<--verbose>

Send the "WHERE" clause generated by the collected C<--where>
arguments, as well as items affected to Standard Out.

=item B<--where>

The C<--where> option may called multiple times. The following argument
must be a syntactically valid SQL statement which is part of the C<WHERE>
clause querying the items table. These are joined by C<AND>.

=item B<--commit>

No items will be deleted unless the C<--commit> flag is present.

=item B<--del_bibs>

Deletes the bibliographic record if the last item is deleted.

=back

=cut

=head1 EXAMPLES

  The following is an example of this script:

 delete_items.pl --where "withdrawn ! 0"  --where "withdrawn_on < $(date --date="13 month ago" --rfc-3339=date)" --commit

 delete_items.pl --where "itemlost >= '1'" --where "itemlost <='4'" --where "itemlost_on < '2014-04-28'" --commit

=cut

=head1 DESCRIPTION

 This is a lightweight batch deletion tool for items, suitable for running in a cron job.

=cut

=head1 AUTHOR

 Barton Chittenden <barton@bywatersolutions.com>

=cut
