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

(-)a/C4/Circulation.pm (+86 lines)
Lines 1043-1048 sub CanBookBeIssued { Link Here
1043
        }
1043
        }
1044
    }
1044
    }
1045
1045
1046
    if (not C4::Context->preference('AllowMultipleIssuesOnABiblio')) {
1047
        # Check if borrower has already issued an item from the same biblio
1048
        # Only if it's not a subscription
1049
        my $biblionumber = $item->{biblionumber};
1050
        require C4::Serials;
1051
        my $is_a_subscription = C4::Serials::CountSubscriptionFromBiblionumber($biblionumber);
1052
        unless ($is_a_subscription) {
1053
            my $issues = GetIssues( {
1054
                borrowernumber => $borrower->{borrowernumber},
1055
                biblionumber   => $biblionumber,
1056
            } );
1057
            my @issues = $issues ? @$issues : ();
1058
            # If there is at least one issue on another item than the item we want to checkout
1059
            if (scalar @issues > 0 and $issues[0]->{itemnumber} != $item->{itemnumber}) {
1060
                $needsconfirmation{BIBLIO_ALREADY_ISSUED} = 1;
1061
            }
1062
        }
1063
    }
1064
1046
    return ( \%issuingimpossible, \%needsconfirmation, \%alerts );
1065
    return ( \%issuingimpossible, \%needsconfirmation, \%alerts );
1047
}
1066
}
1048
1067
Lines 2324-2329 sub GetOpenIssue { Link Here
2324
2343
2325
}
2344
}
2326
2345
2346
=head2 GetIssues
2347
2348
    $issues = GetIssues({});    # return all issues!
2349
    $issues = GetIssues({ borrowernumber => $borrowernumber, biblionumber => $biblionumber });
2350
2351
Returns all pending issues that match given criteria.
2352
Returns a arrayref or undef if an error occurs.
2353
2354
Allowed criteria are:
2355
2356
=over 2
2357
2358
=item * borrowernumber
2359
2360
=item * biblionumber
2361
2362
=item * itemnumber
2363
2364
=back
2365
2366
=cut
2367
2368
sub GetIssues {
2369
    my ($criteria) = @_;
2370
2371
    # Build filters
2372
    my @filters;
2373
    my @allowed = qw(borrowernumber biblionumber itemnumber);
2374
    foreach (@allowed) {
2375
        if (defined $criteria->{$_}) {
2376
            push @filters, {
2377
                field => $_,
2378
                value => $criteria->{$_},
2379
            };
2380
        }
2381
    }
2382
2383
    # Do we need to join other tables ?
2384
    my %join;
2385
    if (defined $criteria->{biblionumber}) {
2386
        $join{items} = 1;
2387
    }
2388
2389
    # Build SQL query
2390
    my $where = '';
2391
    if (@filters) {
2392
        $where = "WHERE " . join(' AND ', map { "$_->{field} = ?" } @filters);
2393
    }
2394
    my $query = q{
2395
        SELECT issues.*
2396
        FROM issues
2397
    };
2398
    if (defined $join{items}) {
2399
        $query .= q{
2400
            LEFT JOIN items ON (issues.itemnumber = items.itemnumber)
2401
        };
2402
    }
2403
    $query .= $where;
2404
2405
    # Execute SQL query
2406
    my $dbh = C4::Context->dbh;
2407
    my $sth = $dbh->prepare($query);
2408
    my $rv = $sth->execute(map { $_->{value} } @filters);
2409
2410
    return $rv ? $sth->fetchall_arrayref({}) : undef;
2411
}
2412
2327
=head2 GetItemIssues
2413
=head2 GetItemIssues
2328
2414
2329
  $issues = &GetItemIssues($itemnumber, $history);
2415
  $issues = &GetItemIssues($itemnumber, $history);
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 17-22 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
17
('AllowHoldsOnDamagedItems','1','','Allow hold requests to be placed on damaged items','YesNo'),
17
('AllowHoldsOnDamagedItems','1','','Allow hold requests to be placed on damaged items','YesNo'),
18
('AllowHoldsOnPatronsPossessions','1',NULL,'Allow holds on records that patron have items of it','YesNo'),
18
('AllowHoldsOnPatronsPossessions','1',NULL,'Allow holds on records that patron have items of it','YesNo'),
19
('AllowItemsOnHoldCheckout','0','','Do not generate RESERVE_WAITING and RESERVED warning when checking out items reserved to someone else. This allows self checkouts for those items.','YesNo'),
19
('AllowItemsOnHoldCheckout','0','','Do not generate RESERVE_WAITING and RESERVED warning when checking out items reserved to someone else. This allows self checkouts for those items.','YesNo'),
20
('AllowMultipleIssuesOnABiblio',1,'Allow/Don\'t allow patrons to check out multiple items from one biblio','','YesNo'),
20
('AllowMultipleCovers','0','1','Allow multiple cover images to be attached to each bibliographic record.','YesNo'),
21
('AllowMultipleCovers','0','1','Allow multiple cover images to be attached to each bibliographic record.','YesNo'),
21
('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
22
('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
22
('AllowOfflineCirculation','0','','If on, enables HTML5 offline circulation functionality.','YesNo'),
23
('AllowOfflineCirculation','0','','If on, enables HTML5 offline circulation functionality.','YesNo'),
(-)a/installer/data/mysql/updatedatabase.pl (+11 lines)
Lines 7953-7958 if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { Link Here
7953
    SetVersion($DBversion);
7953
    SetVersion($DBversion);
7954
}
7954
}
7955
7955
7956
$DBversion = "3.15.00.XXX";
7957
if ( CheckVersion($DBversion) ) {
7958
    $dbh->do(q{
7959
        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
7960
        VALUES('AllowMultipleIssuesOnABiblio',1,'Allow/Don\'t allow patrons to check out multiple items from one biblio','','YesNo')
7961
    });
7962
7963
    print "Upgrade to $DBversion done (Bug 10859 - Add system preference AllowMultipleIssuesOnABiblio)\n";
7964
    SetVersion($DBversion);
7965
}
7966
7956
=head1 FUNCTIONS
7967
=head1 FUNCTIONS
7957
7968
7958
=head2 TableExists($table)
7969
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+6 lines)
Lines 337-342 Circulation: Link Here
337
                  alert: "display a message"
337
                  alert: "display a message"
338
                  nothing : "do nothing"
338
                  nothing : "do nothing"
339
            - .
339
            - .
340
        -
341
            - pref: AllowMultipleIssuesOnABiblio
342
              choices:
343
                  yes: Allow
344
                  no: "Don't allow"
345
            - patrons to check out multiple items from the same biblio.
340
    Checkin Policy:
346
    Checkin Policy:
341
        -
347
        -
342
            - pref: BlockReturnOfWithdrawnItems
348
            - pref: BlockReturnOfWithdrawnItems
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+9 lines)
Lines 269-274 var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export"); Link Here
269
[% IF  HIGHHOLDS %]
269
[% IF  HIGHHOLDS %]
270
    <li>High demand item. Loan period shortened to [% HIGHHOLDS.duration %] days (due [% HIGHHOLDS.returndate %]). Check out anyway?</li>
270
    <li>High demand item. Loan period shortened to [% HIGHHOLDS.duration %] days (due [% HIGHHOLDS.returndate %]). Check out anyway?</li>
271
[% END %]
271
[% END %]
272
273
[% IF BIBLIO_ALREADY_ISSUED %]
274
  <li>
275
    Borrower has already an issue on another item from this biblio.
276
    [% IF CAN_user_circulate_force_checkout %]
277
      Check out anyway?
278
    [% END %]
279
  </li>
280
[% END %]
272
</ul>
281
</ul>
273
282
274
[% IF HIGHHOLDS %]
283
[% IF HIGHHOLDS %]
(-)a/t/db_dependent/Circulation/GetIssues.t (-1 / +101 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
5
use Test::More;
6
use Test::MockModule;
7
use C4::Biblio;
8
use C4::Items;
9
use C4::Members;
10
use C4::Branch;
11
use C4::Category;
12
use C4::Circulation;
13
use MARC::Record;
14
15
my $branchcode;
16
my $branch_created;
17
my @branches = keys %{ GetBranches() };
18
if (@branches) {
19
    $branchcode = $branches[0];
20
} else {
21
    $branchcode = 'B';
22
    ModBranch({ add => 1, branchcode => $branchcode, branchname => 'Branch' });
23
    $branch_created = 1;
24
}
25
26
my %item_branch_infos = (
27
    homebranch => $branchcode,
28
    holdingbranch => $branchcode,
29
);
30
31
my ($biblionumber1) = AddBiblio(MARC::Record->new, '');
32
my $itemnumber1 = AddItem({ barcode => '0101', %item_branch_infos }, $biblionumber1);
33
my $itemnumber2 = AddItem({ barcode => '0102', %item_branch_infos }, $biblionumber1);
34
35
my ($biblionumber2) = AddBiblio(MARC::Record->new, '');
36
my $itemnumber3 = AddItem({ barcode => '0203', %item_branch_infos }, $biblionumber2);
37
38
my $categorycode;
39
my $category_created;
40
my @categories = C4::Category->all;
41
if (@categories) {
42
    $categorycode = $categories[0]->{categorycode}
43
} else {
44
    $categorycode = 'C';
45
    C4::Context->dbh->do(
46
        "INSERT INTO categories(categorycode) VALUES(?)", undef, $categorycode);
47
    $category_created = 1;
48
}
49
50
my $borrowernumber = AddMember(categorycode => $categorycode, branchcode => $branchcode);
51
my $borrower = GetMember(borrowernumber => $borrowernumber);
52
53
# Need to mock userenv for AddIssue
54
my $module = new Test::MockModule('C4::Context');
55
$module->mock('userenv', sub { { branch => $branchcode } });
56
AddIssue($borrower, '0101');
57
AddIssue($borrower, '0203');
58
59
# Begin tests...
60
my $issues;
61
$issues = GetIssues({biblionumber => $biblionumber1});
62
is(scalar @$issues, 1, "Biblio $biblionumber1 has 1 item issued");
63
is($issues->[0]->{itemnumber}, $itemnumber1, "First item of biblio $biblionumber1 is issued");
64
65
$issues = GetIssues({biblionumber => $biblionumber2});
66
is(scalar @$issues, 1, "Biblio $biblionumber2 has 1 item issued");
67
is($issues->[0]->{itemnumber}, $itemnumber3, "First item of biblio $biblionumber2 is issued");
68
69
$issues = GetIssues({borrowernumber => $borrowernumber});
70
is(scalar @$issues, 2, "Borrower $borrowernumber checked out 2 items");
71
72
$issues = GetIssues({borrowernumber => $borrowernumber, biblionumber => $biblionumber1});
73
is(scalar @$issues, 1, "One of those is an item from biblio $biblionumber1");
74
75
$issues = GetIssues({borrowernumber => $borrowernumber, biblionumber => $biblionumber2});
76
is(scalar @$issues, 1, "The other is an item from biblio $biblionumber2");
77
78
$issues = GetIssues({itemnumber => $itemnumber2});
79
is(scalar @$issues, 0, "No one has issued the second item of biblio $biblionumber2");
80
81
END {
82
    AddReturn('0101', $branchcode);
83
    AddReturn('0203', $branchcode);
84
    DelMember($borrowernumber);
85
    if ($category_created) {
86
        C4::Context->dbh->do(
87
            "DELETE FROM categories WHERE categorycode = ?", undef, $categorycode);
88
    }
89
    my $dbh = C4::Context->dbh;
90
    C4::Items::DelItem($dbh, $biblionumber1, $itemnumber1);
91
    C4::Items::DelItem($dbh, $biblionumber1, $itemnumber2);
92
    C4::Items::DelItem($dbh, $biblionumber2, $itemnumber3);
93
    C4::Biblio::DelBiblio($biblionumber1);
94
    C4::Biblio::DelBiblio($biblionumber2);
95
96
    if ($branch_created) {
97
        DelBranch($branchcode);
98
    }
99
};
100
101
done_testing;

Return to bug 10859