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

(-)a/C4/Items.pm (-28 / +69 lines)
Lines 77-82 BEGIN { Link Here
77
        GetItemnumberFromBarcode
77
        GetItemnumberFromBarcode
78
        GetBarcodeFromItemnumber
78
        GetBarcodeFromItemnumber
79
        GetHiddenItemnumbers
79
        GetHiddenItemnumbers
80
        ItemSafeToDelete
80
        DelItemCheck
81
        DelItemCheck
81
    MoveItemFromBiblio
82
    MoveItemFromBiblio
82
    GetLatestAcquisitions
83
    GetLatestAcquisitions
Lines 2308-2375 sub MoveItemFromBiblio { Link Here
2308
    return;
2309
    return;
2309
}
2310
}
2310
2311
2311
=head2 DelItemCheck
2312
=head2 ItemSafeToDelete
2312
2313
2313
   DelItemCheck($dbh, $biblionumber, $itemnumber);
2314
   ItemSafeToDelete($dbh, $biblionumber, $itemnumber);
2314
2315
2315
Exported function (core API) for deleting an item record in Koha if there no current issue.
2316
Exported function (core API) for checking whether an item record is safe to delete.
2317
2318
returns 1 if the item is safe to delete,
2319
2320
"book_on_loan" if the item is checked out,
2321
2322
"not_same_branch" if the item is blocked by independent branches,
2323
2324
"book_reserved" if the there are holds aganst the item, or
2325
2326
"linked_analytics" if the item has linked analytic records.
2316
2327
2317
=cut
2328
=cut
2318
2329
2319
sub DelItemCheck {
2330
sub ItemSafeToDelete {
2320
    my ( $dbh, $biblionumber, $itemnumber ) = @_;
2331
    my ( $dbh, $biblionumber, $itemnumber ) = @_;
2321
2332
    my $status;
2322
    $dbh ||= C4::Context->dbh;
2333
    $dbh ||= C4::Context->dbh;
2323
2334
2324
    my $error;
2335
    my $error;
2325
2336
2326
        my $countanalytics=GetAnalyticsCount($itemnumber);
2337
    my $countanalytics = GetAnalyticsCount($itemnumber);
2327
2328
2338
2329
    # check that there is no issue on this item before deletion.
2339
    # check that there is no issue on this item before deletion.
2330
    my $sth = $dbh->prepare(q{
2340
    my $sth = $dbh->prepare(
2341
        q{
2331
        SELECT COUNT(*) FROM issues
2342
        SELECT COUNT(*) FROM issues
2332
        WHERE itemnumber = ?
2343
        WHERE itemnumber = ?
2333
    });
2344
    }
2345
    );
2334
    $sth->execute($itemnumber);
2346
    $sth->execute($itemnumber);
2335
    my ($onloan) = $sth->fetchrow;
2347
    my ($onloan) = $sth->fetchrow;
2336
2348
2337
    my $item = GetItem($itemnumber);
2349
    my $item = GetItem($itemnumber);
2338
2350
2339
    if ($onloan){
2351
    if ($onloan) {
2340
        $error = "book_on_loan" 
2352
        $status = "book_on_loan";
2341
    }
2353
    }
2342
    elsif ( defined C4::Context->userenv
2354
    elsif ( defined C4::Context->userenv
2343
        and !C4::Context->IsSuperLibrarian()
2355
        and !C4::Context->IsSuperLibrarian()
2344
        and C4::Context->preference("IndependentBranches")
2356
        and C4::Context->preference("IndependentBranches")
2345
        and ( C4::Context->userenv->{branch} ne $item->{'homebranch'} ) )
2357
        and ( C4::Context->userenv->{branch} ne $item->{'homebranch'} ) )
2346
    {
2358
    {
2347
        $error = "not_same_branch";
2359
        $status = "not_same_branch";
2348
    }
2360
    }
2349
	else{
2361
    else {
2350
        # check it doesn't have a waiting reserve
2362
        # check it doesn't have a waiting reserve
2351
        $sth = $dbh->prepare(q{
2363
        $sth = $dbh->prepare(
2364
            q{
2352
            SELECT COUNT(*) FROM reserves
2365
            SELECT COUNT(*) FROM reserves
2353
            WHERE (found = 'W' OR found = 'T')
2366
            WHERE (found = 'W' OR found = 'T')
2354
            AND itemnumber = ?
2367
            AND itemnumber = ?
2355
        });
2368
        }
2369
        );
2356
        $sth->execute($itemnumber);
2370
        $sth->execute($itemnumber);
2357
        my ($reserve) = $sth->fetchrow;
2371
        my ($reserve) = $sth->fetchrow;
2358
        if ($reserve){
2372
        if ($reserve) {
2359
            $error = "book_reserved";
2373
            $status = "book_reserved";
2360
        } elsif ($countanalytics > 0){
2361
		$error = "linked_analytics";
2362
	} else {
2363
            DelItem(
2364
                {
2365
                    biblionumber => $biblionumber,
2366
                    itemnumber   => $itemnumber
2367
                }
2368
            );
2369
            return 1;
2370
        }
2374
        }
2375
        elsif ( $countanalytics > 0 ) {
2376
            $status = "linked_analytics";
2377
        }
2378
        else {
2379
            $status = 1;
2380
        }
2381
    }
2382
    return $status;
2383
}
2384
2385
=head2 DelItemCheck
2386
2387
   DelItemCheck($dbh, $biblionumber, $itemnumber);
2388
2389
Exported function (core API) for deleting an item record in Koha if there no current issue.
2390
2391
DelItemCheck wraps ItemSafeToDelete around DelItem.
2392
2393
It takes a database handle, biblionumber and itemnumber as arguments, and can optionally take a hashref with a 'do_not_commit' flag:
2394
2395
    DelItemCheck(  $dbh, $biblionumber, $itemnumber, { do_not_commit => 1 } );
2396
2397
This is done so that command line scripts calling DelItemCheck have the option of doing a 'dry-run'.
2398
=cut
2399
2400
sub DelItemCheck {
2401
    my ( $dbh, $biblionumber, $itemnumber, $options ) = @_;
2402
    my $commit = ( defined $options && $options->{do_not_commit} eq 1 ) ? 0 : 1;
2403
    my $status = ItemSafeToDelete( $dbh, $biblionumber, $itemnumber );
2404
2405
    if ( $status == 1 && $commit ) {
2406
        DelItem(
2407
            {
2408
                biblionumber => $biblionumber,
2409
                itemnumber   => $itemnumber
2410
            }
2411
        );
2371
    }
2412
    }
2372
    return $error;
2413
    return $status;
2373
}
2414
}
2374
2415
2375
=head2 _koha_modify_item
2416
=head2 _koha_modify_item
(-)a/t/db_dependent/Items_DelItemCheck.t (-1 / +145 lines)
Line 0 Link Here
0
- 
1
use Modern::Perl;
2
3
use MARC::Record;
4
use C4::Biblio;
5
use C4::Circulation;
6
use C4::Members;
7
use t::lib::Mocks;
8
9
10
use Test::More tests => 10;
11
12
*C4::Context::userenv = \&Mock_userenv;
13
14
BEGIN {
15
    use_ok('C4::Items');
16
}
17
18
my $dbh = C4::Context->dbh;
19
$dbh->{AutoCommit} = 0;
20
$dbh->{RaiseError} = 1;
21
22
my ( $biblionumber, $bibitemnum ) = get_biblio();
23
24
# book_on_loan
25
26
my ( $borrowernumber, $borrower ) = get_borrower();
27
my ( $itemnumber, $item )         = get_item( $biblionumber );
28
AddIssue( $borrower, 'i_dont_exist' );
29
30
is(
31
    ItemSafeToDelete($dbh, $biblionumber, $itemnumber),
32
    'book_on_loan',
33
    'ItemSafeToDelete reports item on loan',
34
);
35
36
is(
37
    DelItemCheck($dbh, $biblionumber, $itemnumber),
38
    'book_on_loan',
39
    'item that is on loan cannot be deleted',
40
);
41
42
AddReturn('i_dont_exist', 'CPL');
43
44
# book_reserved is tested in t/db_dependent/Reserves.t
45
46
# not_same_branch
47
t::lib::Mocks::mock_preference('IndependentBranches', 1);
48
ModItem( { homebranch => 'FPL', holdingbranch => 'FPL' }, $biblionumber, $itemnumber );
49
50
is(
51
    ItemSafeToDelete($dbh, $biblionumber, $itemnumber),
52
    'not_same_branch',
53
    'ItemSafeToDelete reports IndependentBranches restriction',
54
);
55
56
is(
57
    DelItemCheck($dbh, $biblionumber, $itemnumber),
58
    'not_same_branch',
59
    'IndependentBranches prevents deletion at another branch',
60
);
61
62
ModItem( { homebranch => 'CPL', holdingbranch => 'CPL' }, $biblionumber, $itemnumber );
63
64
# linked_analytics
65
66
{ # codeblock to limit scope of $module->mock
67
68
    my $module = Test::MockModule->new('C4::Items');
69
    $module->mock( GetAnalyticsCount => sub { return 1 } );
70
71
    is(
72
        ItemSafeToDelete($dbh, $biblionumber, $itemnumber),
73
        'linked_analytics',
74
        'ItemSafeToDelete reports linked analytics',
75
    );
76
77
    is(
78
        DelItemCheck($dbh, $biblionumber, $itemnumber),
79
        'linked_analytics',
80
        'Linked analytics prevents deletion of item',
81
    );
82
83
}
84
85
is(
86
    ItemSafeToDelete($dbh, $biblionumber, $itemnumber),
87
    1,
88
    'ItemSafeToDelete shows item safe to delete'
89
);
90
91
DelItemCheck($dbh, $biblionumber, $itemnumber, { do_not_commit => 1 } );
92
93
my $testitem = GetItem( $itemnumber );
94
95
is( $testitem->{itemnumber} ,  $itemnumber,
96
    "DelItemCheck should not delete item if 'do_not_commit' is set"
97
);
98
99
DelItemCheck( $dbh, $biblionumber, $itemnumber );
100
101
$testitem = GetItem( $itemnumber );
102
103
is( $testitem->{itemnumber}, undef,
104
    "DelItemCheck should delete item if 'do_not_commit' not set"
105
);
106
107
# End of testing
108
109
# Helper methods to set up Biblio, Item, and Borrower.
110
sub get_biblio {
111
    my $bib = MARC::Record->new();
112
    $bib->append_fields(
113
        MARC::Field->new( '100', ' ', ' ', a => 'Moffat, Steven' ),
114
        MARC::Field->new( '245', ' ', ' ', a => 'Silence in the library' ),
115
    );
116
    my ( $bibnum, $bibitemnum ) = AddBiblio( $bib, '' );
117
    return ( $bibnum, $bibitemnum );
118
}
119
120
sub get_item {
121
    my $biblionumber = shift;
122
    my ( $item_bibnum, $item_bibitemnum, $itemnumber ) =
123
      AddItem( { homebranch => 'CPL', holdingbranch => 'CPL', barcode => 'i_dont_exist' }, $biblionumber );
124
    my $item = GetItem( $itemnumber );
125
    return ( $itemnumber, $item );
126
}
127
128
sub get_borrower {
129
    my $borrowernumber = AddMember(
130
        firstname =>  'my firstname',
131
        surname => 'my surname',
132
        categorycode => 'S',
133
        branchcode => 'CPL',
134
    );
135
136
    my $borrower = GetMember( borrowernumber => $borrowernumber );
137
    return ( $borrowernumber, $borrower );
138
}
139
140
# C4::Context->userenv
141
sub Mock_userenv {
142
        return { flags => 0, branch => 'CPL' };
143
}
144
145
$dbh->rollback;

Return to bug 14504