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

(-)a/C4/ImportBatch.pm (-2 / +1 lines)
Lines 937-944 sub BatchRevertItems { Link Here
937
    $sth->execute();
937
    $sth->execute();
938
    while (my $row = $sth->fetchrow_hashref()) {
938
    while (my $row = $sth->fetchrow_hashref()) {
939
        my $item = Koha::Items->find($row->{itemnumber});
939
        my $item = Koha::Items->find($row->{itemnumber});
940
        my $error = $item->safe_delete;
940
        if ($item->safe_delete){
941
        if ($error eq '1'){
942
            my $updsth = $dbh->prepare("UPDATE import_items SET status = ? WHERE import_items_id = ?");
941
            my $updsth = $dbh->prepare("UPDATE import_items SET status = ? WHERE import_items_id = ?");
943
            $updsth->bind_param(1, 'reverted');
942
            $updsth->bind_param(1, 'reverted');
944
            $updsth->bind_param(2, $row->{'import_items_id'});
943
            $updsth->bind_param(2, $row->{'import_items_id'});
(-)a/Koha/Acquisition/Order.pm (-2 / +2 lines)
Lines 127-137 sub cancel { Link Here
127
    my $items = $self->items;
127
    my $items = $self->items;
128
    while ( my $item = $items->next ) {
128
    while ( my $item = $items->next ) {
129
        my $deleted = $item->safe_delete;
129
        my $deleted = $item->safe_delete;
130
        unless ( ref($deleted) eq 'Koha::Item' ) {
130
        unless ( $deleted ) {
131
            $self->add_message(
131
            $self->add_message(
132
                {
132
                {
133
                    message => 'error_delitem',
133
                    message => 'error_delitem',
134
                    payload => { item => $item, reason => $deleted }
134
                    payload => { item => $item, reason => @{$deleted->messages}[0]->messages }
135
                }
135
                }
136
            );
136
            );
137
        }
137
        }
(-)a/Koha/BackgroundJob/BatchDeleteBiblio.pm (-3 / +3 lines)
Lines 112-125 sub process { Link Here
112
        # Delete items
112
        # Delete items
113
        my $items = Koha::Items->search({ biblionumber => $biblionumber });
113
        my $items = Koha::Items->search({ biblionumber => $biblionumber });
114
        while ( my $item = $items->next ) {
114
        while ( my $item = $items->next ) {
115
            my $error = $item->safe_delete;
115
            my $deleted = $item->safe_delete;
116
            if(ref($error) ne 'Koha::Item'){
116
            if( $deleted ) {
117
                push @messages, {
117
                push @messages, {
118
                    type => 'error',
118
                    type => 'error',
119
                    code => 'item_not_deleted',
119
                    code => 'item_not_deleted',
120
                    biblionumber => $biblionumber,
120
                    biblionumber => $biblionumber,
121
                    itemnumber => $item->itemnumber,
121
                    itemnumber => $item->itemnumber,
122
                    error => $error,
122
                    error => @{$deleted->messages}[0]->messages,
123
                };
123
                };
124
                $schema->storage->txn_rollback;
124
                $schema->storage->txn_rollback;
125
                $job->progress( ++$job_progress )->store;
125
                $job->progress( ++$job_progress )->store;
(-)a/Koha/BackgroundJob/BatchDeleteItem.pm (-1 / +1 lines)
Lines 114-120 sub process { Link Here
114
                    my $item = Koha::Items->find($record_id) || next;
114
                    my $item = Koha::Items->find($record_id) || next;
115
115
116
                    my $return = $item->safe_delete;
116
                    my $return = $item->safe_delete;
117
                    unless ( ref($return) ) {
117
                    unless ( $return ) {
118
118
119
                        # FIXME Do we need to rollback the whole transaction if a deletion failed?
119
                        # FIXME Do we need to rollback the whole transaction if a deletion failed?
120
                        push @not_deleted_itemnumbers, $item->itemnumber;
120
                        push @not_deleted_itemnumbers, $item->itemnumber;
(-)a/Koha/Item.pm (-7 / +14 lines)
Lines 45-50 use Koha::Libraries; Link Here
45
use Koha::StockRotationItem;
45
use Koha::StockRotationItem;
46
use Koha::StockRotationRotas;
46
use Koha::StockRotationRotas;
47
use Koha::TrackedLinks;
47
use Koha::TrackedLinks;
48
use Koha::Result::Boolean;
48
49
49
use base qw(Koha::Object);
50
use base qw(Koha::Object);
50
51
Lines 248-254 sub safe_delete { Link Here
248
    my $params = @_ ? shift : {};
249
    my $params = @_ ? shift : {};
249
250
250
    my $safe_to_delete = $self->safe_to_delete;
251
    my $safe_to_delete = $self->safe_to_delete;
251
    return $safe_to_delete unless $safe_to_delete eq '1';
252
    return $safe_to_delete unless $safe_to_delete;
252
253
253
    $self->move_to_deleted;
254
    $self->move_to_deleted;
254
255
Lines 274-295 returns 1 if the item is safe to delete, Link Here
274
sub safe_to_delete {
275
sub safe_to_delete {
275
    my ($self) = @_;
276
    my ($self) = @_;
276
277
277
    return "book_on_loan" if $self->checkout;
278
    my $error;
278
279
279
    return "not_same_branch"
280
    $error = "book_on_loan" if $self->checkout;
281
282
    $error = "not_same_branch"
280
      if defined C4::Context->userenv
283
      if defined C4::Context->userenv
281
      and !C4::Context->IsSuperLibrarian()
284
      and !C4::Context->IsSuperLibrarian()
282
      and C4::Context->preference("IndependentBranches")
285
      and C4::Context->preference("IndependentBranches")
283
      and ( C4::Context->userenv->{branch} ne $self->homebranch );
286
      and ( C4::Context->userenv->{branch} ne $self->homebranch );
284
287
285
    # check it doesn't have a waiting reserve
288
    # check it doesn't have a waiting reserve
286
    return "book_reserved"
289
    $error = "book_reserved"
287
      if $self->holds->search( { found => [ 'W', 'T' ] } )->count;
290
      if $self->holds->search( { found => [ 'W', 'T' ] } )->count;
288
291
289
    return "linked_analytics"
292
    $error = "linked_analytics"
290
      if C4::Items::GetAnalyticsCount( $self->itemnumber ) > 0;
293
      if C4::Items::GetAnalyticsCount( $self->itemnumber ) > 0;
291
294
292
    return "last_item_for_hold"
295
    $error = "last_item_for_hold"
293
      if $self->biblio->items->count == 1
296
      if $self->biblio->items->count == 1
294
      && $self->biblio->holds->search(
297
      && $self->biblio->holds->search(
295
          {
298
          {
Lines 297-303 sub safe_to_delete { Link Here
297
          }
300
          }
298
        )->count;
301
        )->count;
299
302
300
    return 1;
303
    if ( $error ) {
304
        return Koha::Result::Boolean->new(0)->add_message({ message => $error });
305
    }
306
307
    return Koha::Result::Boolean->new(1);
301
}
308
}
302
309
303
=head3 move_to_deleted
310
=head3 move_to_deleted
(-)a/cataloguing/additem.pl (-7 / +6 lines)
Lines 376-386 if ($op eq "additem") { Link Here
376
#-------------------------------------------------------------------------------
376
#-------------------------------------------------------------------------------
377
    # check that there is no issue on this item before deletion.
377
    # check that there is no issue on this item before deletion.
378
    my $item = Koha::Items->find($itemnumber);
378
    my $item = Koha::Items->find($itemnumber);
379
    my $error = $item->safe_delete;
379
    my $deleted = $item->safe_delete;
380
    if(ref($error) eq 'Koha::Item'){
380
    if($deleted) {
381
        print $input->redirect("additem.pl?biblionumber=$biblionumber&frameworkcode=$frameworkcode&searchid=$searchid");
381
        print $input->redirect("additem.pl?biblionumber=$biblionumber&frameworkcode=$frameworkcode&searchid=$searchid");
382
    }else{
382
    } else {
383
        push @errors,$error;
383
        push @errors, @{$deleted->messages}[0]->message;
384
        $nextop="additem";
384
        $nextop="additem";
385
    }
385
    }
386
#-------------------------------------------------------------------------------
386
#-------------------------------------------------------------------------------
Lines 388-396 if ($op eq "additem") { Link Here
388
#-------------------------------------------------------------------------------
388
#-------------------------------------------------------------------------------
389
    my $items = Koha::Items->search({ biblionumber => $biblionumber });
389
    my $items = Koha::Items->search({ biblionumber => $biblionumber });
390
    while ( my $item = $items->next ) {
390
    while ( my $item = $items->next ) {
391
        my $error = $item->safe_delete({ skip_record_index => 1 });
391
        my $deleted = $item->safe_delete({ skip_record_index => 1 });
392
        next if ref $error eq 'Koha::Item'; # Deleted item is returned if deletion successful
392
        push @errors, @{$deleted->messages}[0]->message;
393
        push @errors,$error;
394
    }
393
    }
395
    my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
394
    my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
396
    $indexer->index_records( $biblionumber, "specialUpdate", "biblioserver" );
395
    $indexer->index_records( $biblionumber, "specialUpdate", "biblioserver" );
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc (-7 / +10 lines)
Lines 264-276 Link Here
264
                            [% IF item.safe_to_delete == 1 %]
264
                            [% IF item.safe_to_delete == 1 %]
265
                                <td><input type="checkbox" name="itemnumber" value="[% item.itemnumber | html %]" id="row[% item.itemnumber | html %]" checked="checked" /></td>
265
                                <td><input type="checkbox" name="itemnumber" value="[% item.itemnumber | html %]" id="row[% item.itemnumber | html %]" checked="checked" /></td>
266
                            [% ELSE %]
266
                            [% ELSE %]
267
                                [% SWITCH item.safe_to_delete%]
267
                                [% SET messages = item.safe_to_delete.messages %]
268
                                [% CASE "book_on_loan" %][% SET cannot_delete_reason = t("Item is checked out") %]
268
                                [% FOR m IN messages %]
269
                                [% CASE "not_same_branch" %][% SET cannot_delete_reason = t("Item does not belong to your library") %]
269
                                    [% SWITCH m %]
270
                                [% CASE "book_reserved" %][% SET cannot_delete_reason = t("Item has a waiting hold") %]
270
                                    [% CASE "book_on_loan" %][% SET cannot_delete_reason = t("Item is checked out") %]
271
                                [% CASE "linked_analytics" %][% SET cannot_delete_reason = t("Item has linked analytics") %]
271
                                    [% CASE "not_same_branch" %][% SET cannot_delete_reason = t("Item does not belong to your library") %]
272
                                [% CASE "last_item_for_hold" %][% SET cannot_delete_reason = t("Last item for bibliographic record with biblio-level hold on it") %]
272
                                    [% CASE "book_reserved" %][% SET cannot_delete_reason = t("Item has a waiting hold") %]
273
                                [% CASE %][% SET cannot_delete_reason = t("Unknown reason") _ '(' _ item.safe_to_delete _ ')' %]
273
                                    [% CASE "linked_analytics" %][% SET cannot_delete_reason = t("Item has linked analytics") %]
274
                                    [% CASE "last_item_for_hold" %][% SET cannot_delete_reason = t("Last item for bibliographic record with biblio-level hold on it") %]
275
                                    [% CASE %][% SET cannot_delete_reason = t("Unknown reason") _ '(' _ item.safe_to_delete _ ')' %]
276
                                    [% END %]
274
                                [% END %]
277
                                [% END %]
275
278
276
                                <td><input type="checkbox" name="itemnumber" value="[% item.itemnumber | html %]" id="row[% item.itemnumber | html %]" disabled="disabled" title="[% cannot_delete_reason | html %]"/></td>
279
                                <td><input type="checkbox" name="itemnumber" value="[% item.itemnumber | html %]" id="row[% item.itemnumber | html %]" disabled="disabled" title="[% cannot_delete_reason | html %]"/></td>
(-)a/misc/cronjobs/delete_items.pl (-2 / +2 lines)
Lines 78-89 DELITEM: while ( my $item = $GLOBAL->{sth}->{target_items}->fetchrow_hashref() ) Link Here
78
78
79
    my $item_object = Koha::Items->find($item->{itemnumber});
79
    my $item_object = Koha::Items->find($item->{itemnumber});
80
    my $safe_to_delete = $item_object->safe_to_delete;
80
    my $safe_to_delete = $item_object->safe_to_delete;
81
    if( $safe_to_delete eq '1' )  {
81
    if( $safe_to_delete )  {
82
        $item_object->safe_delete
82
        $item_object->safe_delete
83
            if $OPTIONS->{flags}->{commit};
83
            if $OPTIONS->{flags}->{commit};
84
        verbose "Deleting '$item->{itemnumber}'";
84
        verbose "Deleting '$item->{itemnumber}'";
85
    } else {
85
    } else {
86
        verbose "Item '$item->{itemnumber}' not deleted: $safe_to_delete";
86
        verbose sprintf "Item '%s' not deleted: %s", $item->{itemnumber}, @{$safe_to_delete->messages}[0]->message
87
    }
87
    }
88
}
88
}
89
89
(-)a/misc/cronjobs/delete_records_via_leader.pl (-6 / +8 lines)
Lines 91-109 foreach my $m (@metadatas) { Link Here
91
            my $itemnumber = $item->itemnumber;
91
            my $itemnumber = $item->itemnumber;
92
92
93
            if( $test ){
93
            if( $test ){
94
                my $result = $item->safe_to_delete;
94
                my $deleted = $item->safe_to_delete;
95
                if ( $result eq "1") {
95
                if ( $deleted ) {
96
                    say "TEST MODE: Item $itemnumber would have been deleted";
96
                    say "TEST MODE: Item $itemnumber would have been deleted";
97
                } else {
97
                } else {
98
                    say "TEST MODE: ERROR DELETING ITEM $itemnumber: $result";
98
                    my $error = @{$deleted->messages}[0]->message
99
                    say "TEST MODE: ERROR DELETING ITEM $itemnumber: $error";
99
                }
100
                }
100
            } else {
101
            } else {
101
                my $result = $item->safe_delete;
102
                my $deleted = $item->safe_to_delete;
102
                if ( ref $result eq "Koha::Item" ){
103
                if ( $deleted ) {
103
                    say "DELETED ITEM $itemnumber" if $verbose;
104
                    say "DELETED ITEM $itemnumber" if $verbose;
104
                    $deleted_items_count++;
105
                    $deleted_items_count++;
105
                } else {
106
                } else {
106
                    say "ERROR DELETING ITEM $itemnumber: $result";
107
                    my $error = @{$deleted->messages}[0]->message
108
                    say "ERROR DELETING ITEM $itemnumber: $error";
107
                }
109
                }
108
            }
110
            }
109
            $total_items_count++;
111
            $total_items_count++;
(-)a/t/db_dependent/Circulation/IsItemIssued.t (-4 / +3 lines)
Lines 67-73 AddIssue($borrower, $item->barcode); Link Here
67
is ( IsItemIssued( $item->itemnumber ), 1, "item is now on loan" );
67
is ( IsItemIssued( $item->itemnumber ), 1, "item is now on loan" );
68
68
69
is(
69
is(
70
    $item->safe_delete,
70
    @{$item->safe_delete->messages}[0]->message,
71
    'book_on_loan',
71
    'book_on_loan',
72
    'item that is on loan cannot be deleted',
72
    'item that is on loan cannot be deleted',
73
);
73
);
Lines 77-85 is ( IsItemIssued( $item->itemnumber ), 0, "item has been returned" ); Link Here
77
77
78
$item->discard_changes; # FIXME We should not need that
78
$item->discard_changes; # FIXME We should not need that
79
                        # If we do not, $self->checkout in safe_to_delete will not know the item has been checked out
79
                        # If we do not, $self->checkout in safe_to_delete will not know the item has been checked out
80
is(
80
ok(
81
    ref($item->safe_delete),
81
    $item->safe_delete,
82
    'Koha::Item',
83
    'item that is not on loan can be deleted',
82
    'item that is not on loan can be deleted',
84
);
83
);
85
84
(-)a/t/db_dependent/Koha/Item.t (-12 / +18 lines)
Lines 571-577 subtest 'request_transfer' => sub { Link Here
571
};
571
};
572
572
573
subtest 'deletion' => sub {
573
subtest 'deletion' => sub {
574
    plan tests => 12;
574
    plan tests => 13;
575
575
576
    $schema->storage->txn_begin;
576
    $schema->storage->txn_begin;
577
577
Lines 606-622 subtest 'deletion' => sub { Link Here
606
    C4::Circulation::AddIssue( $patron->unblessed, $item->barcode );
606
    C4::Circulation::AddIssue( $patron->unblessed, $item->barcode );
607
607
608
    is(
608
    is(
609
        $item->safe_to_delete,
609
        @{$item->safe_to_delete->messages}[0]->message,
610
        'book_on_loan',
610
        'book_on_loan',
611
        'Koha::Item->safe_to_delete reports item on loan',
611
        'Koha::Item->safe_to_delete reports item on loan',
612
    );
612
    );
613
613
614
    is(
614
    is(
615
        $item->safe_delete,
615
        @{$item->safe_to_delete->messages}[0]->message,
616
        'book_on_loan',
616
        'book_on_loan',
617
        'item that is on loan cannot be deleted',
617
        'item that is on loan cannot be deleted',
618
    );
618
    );
619
619
620
    ok(
621
        ! $item->safe_to_delete,
622
        'Koha::Item->safe_to_delete shows item NOT safe to delete'
623
    );
624
620
    AddReturn( $item->barcode, $library->branchcode );
625
    AddReturn( $item->barcode, $library->branchcode );
621
626
622
    # book_reserved is tested in t/db_dependent/Reserves.t
627
    # book_reserved is tested in t/db_dependent/Reserves.t
Lines 626-638 subtest 'deletion' => sub { Link Here
626
    my $item_2 = $builder->build_sample_item({ library => $library_2->branchcode });
631
    my $item_2 = $builder->build_sample_item({ library => $library_2->branchcode });
627
632
628
    is(
633
    is(
629
        $item_2->safe_to_delete,
634
        @{$item_2->safe_to_delete->messages}[0]->message,
630
        'not_same_branch',
635
        'not_same_branch',
631
        'Koha::Item->safe_to_delete reports IndependentBranches restriction',
636
        'Koha::Item->safe_to_delete reports IndependentBranches restriction',
632
    );
637
    );
633
638
634
    is(
639
    is(
635
        $item_2->safe_delete,
640
        @{$item_2->safe_to_delete->messages}[0]->message,
636
        'not_same_branch',
641
        'not_same_branch',
637
        'IndependentBranches prevents deletion at another branch',
642
        'IndependentBranches prevents deletion at another branch',
638
    );
643
    );
Lines 646-658 subtest 'deletion' => sub { Link Here
646
651
647
        $item->discard_changes;
652
        $item->discard_changes;
648
        is(
653
        is(
649
            $item->safe_to_delete,
654
            @{$item->safe_to_delete->messages}[0]->message,
650
            'linked_analytics',
655
            'linked_analytics',
651
            'Koha::Item->safe_to_delete reports linked analytics',
656
            'Koha::Item->safe_to_delete reports linked analytics',
652
        );
657
        );
653
658
654
        is(
659
        is(
655
            $item->safe_delete,
660
            @{$item->safe_to_delete->messages}[0]->message,
656
            'linked_analytics',
661
            'linked_analytics',
657
            'Linked analytics prevents deletion of item',
662
            'Linked analytics prevents deletion of item',
658
        );
663
        );
Lines 661-675 subtest 'deletion' => sub { Link Here
661
666
662
    { # last_item_for_hold
667
    { # last_item_for_hold
663
        C4::Reserves::AddReserve({ branchcode => $patron->branchcode, borrowernumber => $patron->borrowernumber, biblionumber => $item->biblionumber });
668
        C4::Reserves::AddReserve({ branchcode => $patron->branchcode, borrowernumber => $patron->borrowernumber, biblionumber => $item->biblionumber });
664
        is( $item->safe_to_delete, 'last_item_for_hold', 'Item cannot be deleted if a biblio-level is placed on the biblio and there is only 1 item attached to the biblio' );
669
        is(
665
670
            @{$item->safe_to_delete->messages}[0]->message,
671
            'last_item_for_hold',
672
            'Item cannot be deleted if a biblio-level is placed on the biblio and there is only 1 item attached to the biblio'
673
        );
666
        # With another item attached to the biblio, the item can be deleted
674
        # With another item attached to the biblio, the item can be deleted
667
        $builder->build_sample_item({ biblionumber => $item->biblionumber });
675
        $builder->build_sample_item({ biblionumber => $item->biblionumber });
668
    }
676
    }
669
677
670
    is(
678
    ok(
671
        $item->safe_to_delete,
679
        $item->safe_to_delete,
672
        1,
673
        'Koha::Item->safe_to_delete shows item safe to delete'
680
        'Koha::Item->safe_to_delete shows item safe to delete'
674
    );
681
    );
675
682
676
- 

Return to bug 29788