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

(-)a/C4/Circulation.pm (+87 lines)
Lines 86-91 BEGIN { Link Here
86
        &GetBranchItemRule
86
        &GetBranchItemRule
87
		&GetBiblioIssues
87
		&GetBiblioIssues
88
		&GetOpenIssue
88
		&GetOpenIssue
89
        GetIssues
89
		&AnonymiseIssueHistory
90
		&AnonymiseIssueHistory
90
        &CheckIfIssuedToPatron
91
        &CheckIfIssuedToPatron
91
	);
92
	);
Lines 1042-1047 sub CanBookBeIssued { Link Here
1042
        }
1043
        }
1043
    }
1044
    }
1044
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
1045
    return ( \%issuingimpossible, \%needsconfirmation, \%alerts );
1065
    return ( \%issuingimpossible, \%needsconfirmation, \%alerts );
1046
}
1066
}
1047
1067
Lines 2319-2324 sub GetOpenIssue { Link Here
2319
  return $issue;
2339
  return $issue;
2320
}
2340
}
2321
2341
2342
=head2 GetIssues
2343
2344
    $issues = GetIssues({});    # return all issues!
2345
    $issues = GetIssues({ borrowernumber => $borrowernumber, biblionumber => $biblionumber });
2346
2347
Returns all pending issues that match given criteria.
2348
Returns a arrayref or undef if an error occurs.
2349
2350
Allowed criteria are:
2351
2352
=over 2
2353
2354
=item * borrowernumber
2355
2356
=item * biblionumber
2357
2358
=item * itemnumber
2359
2360
=back
2361
2362
=cut
2363
2364
sub GetIssues {
2365
    my ($criteria) = @_;
2366
2367
    # Build filters
2368
    my @filters;
2369
    my @allowed = qw(borrowernumber biblionumber itemnumber);
2370
    foreach (@allowed) {
2371
        if (defined $criteria->{$_}) {
2372
            push @filters, {
2373
                field => $_,
2374
                value => $criteria->{$_},
2375
            };
2376
        }
2377
    }
2378
2379
    # Do we need to join other tables ?
2380
    my %join;
2381
    if (defined $criteria->{biblionumber}) {
2382
        $join{items} = 1;
2383
    }
2384
2385
    # Build SQL query
2386
    my $where = '';
2387
    if (@filters) {
2388
        $where = "WHERE " . join(' AND ', map { "$_->{field} = ?" } @filters);
2389
    }
2390
    my $query = q{
2391
        SELECT issues.*
2392
        FROM issues
2393
    };
2394
    if (defined $join{items}) {
2395
        $query .= q{
2396
            LEFT JOIN items ON (issues.itemnumber = items.itemnumber)
2397
        };
2398
    }
2399
    $query .= $where;
2400
2401
    # Execute SQL query
2402
    my $dbh = C4::Context->dbh;
2403
    my $sth = $dbh->prepare($query);
2404
    my $rv = $sth->execute(map { $_->{value} } @filters);
2405
2406
    return $rv ? $sth->fetchall_arrayref({}) : undef;
2407
}
2408
2322
=head2 GetItemIssues
2409
=head2 GetItemIssues
2323
2410
2324
  $issues = &GetItemIssues($itemnumber, $history);
2411
  $issues = &GetItemIssues($itemnumber, $history);
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 16-21 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
16
('AllowHoldsOnPatronsPossessions','1',NULL,'Allow holds on records that patron have items of it','YesNo'),
16
('AllowHoldsOnPatronsPossessions','1',NULL,'Allow holds on records that patron have items of it','YesNo'),
17
('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'),
17
('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'),
18
('AllowMultipleCovers','0','1','Allow multiple cover images to be attached to each bibliographic record.','YesNo'),
18
('AllowMultipleCovers','0','1','Allow multiple cover images to be attached to each bibliographic record.','YesNo'),
19
('AllowMultipleIssuesOnABiblio',1,'Allow/Don\'t allow patrons to check out multiple items from one biblio','','YesNo'),
19
('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
20
('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
20
('AllowOnShelfHolds','0','','Allow hold requests to be placed on items that are not on loan','YesNo'),
21
('AllowOnShelfHolds','0','','Allow hold requests to be placed on items that are not on loan','YesNo'),
21
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
22
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
(-)a/installer/data/mysql/updatedatabase.pl (+11 lines)
Lines 7134-7139 if ( CheckVersion($DBversion) ) { Link Here
7134
    SetVersion($DBversion);
7134
    SetVersion($DBversion);
7135
}
7135
}
7136
7136
7137
$DBversion = "3.13.00.XXX";
7138
if ( CheckVersion($DBversion) ) {
7139
    $dbh->do(q{
7140
        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
7141
        VALUES('AllowMultipleIssuesOnABiblio',1,'Allow/Don\'t allow patrons to check out multiple items from one biblio','','YesNo')
7142
    });
7143
7144
    print "Upgrade to $DBversion done (Bug 10859 - Add system preference AllowMultipleIssuesOnABiblio)\n";
7145
    SetVersion($DBversion);
7146
}
7147
7137
=head1 FUNCTIONS
7148
=head1 FUNCTIONS
7138
7149
7139
=head2 TableExists($table)
7150
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (+6 lines)
Lines 324-329 Circulation: Link Here
324
                  alert: "display a message"
324
                  alert: "display a message"
325
                  nothing : "do nothing"
325
                  nothing : "do nothing"
326
            - .
326
            - .
327
        -
328
            - pref: AllowMultipleIssuesOnABiblio
329
              choices:
330
                  yes: Allow
331
                  no: "Don't allow"
332
            - patrons to check out multiple items from the same biblio.
327
    Checkin Policy:
333
    Checkin Policy:
328
        -
334
        -
329
            - pref: BlockReturnOfWithdrawnItems
335
            - pref: BlockReturnOfWithdrawnItems
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+9 lines)
Lines 415-420 function validate1(date) { Link Here
415
      [% END %]
415
      [% END %]
416
    </li>
416
    </li>
417
[% END %]
417
[% END %]
418
419
[% IF BIBLIO_ALREADY_ISSUED %]
420
  <li>
421
    Borrower has already an issue on another item from this biblio.
422
    [% IF CAN_user_circulate_force_checkout %]
423
      Check out anyway?
424
    [% END %]
425
  </li>
426
[% END %]
418
</ul>
427
</ul>
419
428
420
[% IF HIGHHOLDS %]
429
[% 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