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

(-)a/C4/Circulation.pm (-50 / +65 lines)
Lines 70-76 use Koha::Patron::Quota; Link Here
70
use Koha::Patron::Quota::Usage;
70
use Koha::Patron::Quota::Usage;
71
use Koha::Patron::Quota::Usages;
71
use Koha::Patron::Quota::Usages;
72
72
73
use Carp qw( carp );
73
use Carp            qw( carp );
74
use List::MoreUtils qw( any );
74
use List::MoreUtils qw( any );
75
use Scalar::Util    qw( looks_like_number blessed );
75
use Scalar::Util    qw( looks_like_number blessed );
76
use Date::Calc      qw( Date_to_Days );
76
use Date::Calc      qw( Date_to_Days );
Lines 1371-1396 sub CanBookBeIssued { Link Here
1371
    }
1371
    }
1372
1372
1373
    # CHECK FOR QUOTAS
1373
    # CHECK FOR QUOTAS
1374
    if ( my $quotas = $patron->all_quotas->filter_by_active ) {
1374
    if ( C4::Context->preference('EnableCirculationQuotas') ) {
1375
        if ( $quotas->count > 1 ) {
1375
        if ( my $quotas = $patron->all_quotas->filter_by_active ) {
1376
1376
            if ( $quotas->count > 1 ) {
1377
            # Multiple available quotas found - need confirmation from user
1377
1378
            $needsconfirmation{QUOTA_SELECT} = $quotas;
1378
                # Multiple available quotas found - need confirmation from user
1379
        } elsif ( $quotas->count == 1 ) {
1379
                $needsconfirmation{QUOTA_SELECT} = $quotas;
1380
            my $quota = $quotas->next;
1380
            } elsif ( $quotas->count == 1 ) {
1381
            if ( !$quota->has_available_quota ) {
1381
                my $quota = $quotas->next;
1382
                if ( C4::Context->preference("AllowQuotaOverride") ) {
1382
                if ( !$quota->has_available_quota ) {
1383
                    $needsconfirmation{QUOTA_EXCEEDED} = {
1383
                    if ( C4::Context->preference("AllowQuotaOverride") ) {
1384
                        available => $quota->available_quota,
1384
                        $needsconfirmation{QUOTA_EXCEEDED} = {
1385
                        total     => $quota->allocation,
1385
                            available => $quota->available_quota,
1386
                        used      => $quota->used,
1386
                            total     => $quota->allocation,
1387
                    };
1387
                            used      => $quota->used,
1388
                } else {
1388
                        };
1389
                    $issuingimpossible{QUOTA_EXCEEDED} = {
1389
                    } else {
1390
                        available => $quota->available_quota,
1390
                        $issuingimpossible{QUOTA_EXCEEDED} = {
1391
                        total     => $quota->allocation,
1391
                            available => $quota->available_quota,
1392
                        used      => $quota->used,
1392
                            total     => $quota->allocation,
1393
                    };
1393
                            used      => $quota->used,
1394
                        };
1395
                    }
1394
                }
1396
                }
1395
            }
1397
            }
1396
        }
1398
        }
Lines 1987-2005 sub AddIssue { Link Here
1987
                if C4::Context->preference('RealTimeHoldsQueue');
1989
                if C4::Context->preference('RealTimeHoldsQueue');
1988
1990
1989
            # Check quotas and record usage if needed
1991
            # Check quotas and record usage if needed
1990
            my $quota;
1992
            if ( C4::Context->preference('EnableCirculationQuotas') ) {
1991
            if ($selected_quota_id) {
1993
                my $quota;
1992
                $quota = Koha::Patron::Quotas->find($selected_quota_id);
1994
                if ($selected_quota_id) {
1993
            } else {
1995
                    $quota = Koha::Patron::Quotas->find($selected_quota_id);
1994
                $quota = $patron->all_quotas->filter_by_active->single;
1996
                } else {
1995
            }
1997
                    $quota = $patron->all_quotas->filter_by_active->single;
1998
                }
1999
2000
                if ($quota) {
1996
2001
1997
            if ($quota) {
2002
                    # Update patron's used quota value
1998
              # Update patron's used quota value
2003
                    $quota->add_usage(
1999
              $quota->add_usage({
2004
                        {
2000
                    patron_id => $patron->patron_id,
2005
                            patron_id => $patron->borrowernumber,
2001
                    issue_id => $issue->issue_id,
2006
                            issue_id  => $issue->issue_id,
2002
                });
2007
                        }
2008
                    );
2009
                }
2003
            }
2010
            }
2004
        }
2011
        }
2005
    }
2012
    }
Lines 3353-3369 sub CanBookBeRenewed { Link Here
3353
    }
3360
    }
3354
3361
3355
    # # CHECK FOR QUOTAS
3362
    # # CHECK FOR QUOTAS
3356
    if ( my $quota_usage = Koha::Patron::Quota::Usages->find( { issue_id => $issue->issue_id } ) ) {
3363
    if ( C4::Context->preference('EnableCirculationQuotas') ) {
3357
3364
        if ( my $quota_usage = Koha::Patron::Quota::Usages->find( { issue_id => $issue->issue_id } ) ) {
3358
        # Get current actives quota for the patron
3365
3359
        if ( my $active_quotas = $patron->all_quotas->filter_by_active ) {
3366
            # Get current actives quota for the patron
3360
            my $all_exceeded = 1;
3367
            if ( my $active_quotas = $patron->all_quotas->filter_by_active ) {
3361
            while ( my $active_quota = $active_quotas->next ) {
3368
                my $all_exceeded = 1;
3362
                if ( $active_quota->has_available_quota ) {
3369
                while ( my $active_quota = $active_quotas->next ) {
3363
                    $all_exceeded = 0;
3370
                    if ( $active_quota->has_available_quota ) {
3371
                        $all_exceeded = 0;
3372
                    }
3364
                }
3373
                }
3374
                return ( 0, "QUOTA_EXCEEDED" ) if $all_exceeded;
3365
            }
3375
            }
3366
            return ( 0, "QUOTA_EXCEEDED" ) if $all_exceeded;
3367
        }
3376
        }
3368
    }
3377
    }
3369
3378
Lines 3480-3493 sub AddRenewal { Link Here
3480
    my $circ_library = Koha::Libraries->find( _GetCircControlBranch( $item_object, $patron ) );
3489
    my $circ_library = Koha::Libraries->find( _GetCircControlBranch( $item_object, $patron ) );
3481
3490
3482
    # Check quotas and record usage if needed
3491
    # Check quotas and record usage if needed
3483
    if (my $quota_usage = Koha::Patron::Quota::Usages->find({ issue_id => $issue->issue_id })) {
3492
    if ( C4::Context->preference('EnableCirculationQuotas') ) {
3484
        # Get current active quota for the patron
3493
        if ( my $quota_usage = Koha::Patron::Quota::Usages->find( { issue_id => $issue->issue_id } ) ) {
3485
        if (my $active_quota = Koha::Patron::Quotas->find($quota_usage->patron_quota_id)) {
3494
3486
            # Update patron's used quota value
3495
            # Get current active quota for the patron
3487
                $active_quota->add_usage({
3496
            if ( my $active_quota = Koha::Patron::Quotas->find( $quota_usage->patron_quota_id ) ) {
3488
                    patron_id => $patron->borrowernumber,
3497
3489
                    issue_id  => $issue->issue_id,
3498
                # Update patron's used quota value
3490
                });
3499
                $active_quota->add_usage(
3500
                    {
3501
                        patron_id => $patron->borrowernumber,
3502
                        issue_id  => $issue->issue_id,
3503
                    }
3504
                );
3505
            }
3491
        }
3506
        }
3492
    }
3507
    }
3493
3508
(-)a/installer/data/mysql/atomicupdate/bug_38924-patron_quotas.pl (-9 / +15 lines)
Lines 26-45 return { Link Here
26
                }
26
                }
27
            );
27
            );
28
28
29
            $dbh->do(q{
29
            $dbh->do(
30
                q{
30
                INSERT IGNORE INTO permissions (module_bit, code, description) VALUES
31
                INSERT IGNORE INTO permissions (module_bit, code, description) VALUES
31
                (4, 'manage_borrower_quotas', 'Manage patron quotas'),
32
                (4, 'manage_borrower_quotas', 'Manage patron quotas'),
32
                (4, 'view_borrower_quotas', 'View patron quotas')
33
                (4, 'view_borrower_quotas', 'View patron quotas')
33
            });
34
            }
35
            );
34
36
35
            say_success( $out, "Patron quota table and permissions created successfully" );
37
            say_success( $out, "Patron quota table and permissions created successfully" );
36
        } else {
38
        } else {
37
            say_info( $out, "Patron quota table already exists" );
39
            say_info( $out, "Patron quota table already exists" );
38
        }
40
        }
39
41
40
        unless ( TableExists('patron_quota_usage') )
42
        unless ( TableExists('patron_quota_usage') ) {
41
        {
43
            $dbh->do(
42
            $dbh->do(q{
44
                q{
43
                CREATE TABLE `patron_quota_usage` (
45
                CREATE TABLE `patron_quota_usage` (
44
                  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique identifier for quota usage record',
46
                  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique identifier for quota usage record',
45
                  `patron_quota_id` int(11) NOT NULL COMMENT 'foreign key linking to patron_quota.id',
47
                  `patron_quota_id` int(11) NOT NULL COMMENT 'foreign key linking to patron_quota.id',
Lines 54-72 return { Link Here
54
                  CONSTRAINT `patron_quota_usage_ibfk_1` FOREIGN KEY (`patron_quota_id`) REFERENCES `patron_quota` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
56
                  CONSTRAINT `patron_quota_usage_ibfk_1` FOREIGN KEY (`patron_quota_id`) REFERENCES `patron_quota` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
55
                  CONSTRAINT `patron_quota_usage_ibfk_2` FOREIGN KEY (`patron_id`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE
57
                  CONSTRAINT `patron_quota_usage_ibfk_2` FOREIGN KEY (`patron_id`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE
56
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
58
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
57
            });
59
            }
60
            );
58
61
59
            say_success( $out, "Patron quota usage table created successfully" );
62
            say_success( $out, "Patron quota usage table created successfully" );
60
        } else {
63
        } else {
61
            say_info( $out, "Patron quota usage table already exists" );
64
            say_info( $out, "Patron quota usage table already exists" );
62
        }
65
        }
63
66
64
        $dbh->do(q{
67
        $dbh->do(
68
            q{
65
            INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type)
69
            INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type)
66
            VALUES
70
            VALUES
67
            ('AllowQuotaOverride', '0', NULL, 'Allow staff to override and check out items to patrons who have exceeded their quota limit', 'YesNo'),
71
            ('AllowQuotaOverride', '0', NULL, 'Allow staff to override and check out items to patrons who have exceeded their quota limit', 'YesNo'),
68
            ('UseGuarantorQuota', '0', NULL, 'Use guarantor quota instead of guarantee quota when checking out items', 'YesNo')
72
            ('UseGuarantorQuota', '0', NULL, 'Use guarantor quota instead of guarantee quota when checking out items', 'YesNo'),
69
        });
73
            ('EnableCirculationQuotas','0','','Enable or disable the circulation quotas feature','YesNo')
74
        }
75
        );
70
76
71
        say_success( $out, "Patron quota preferences added successfully" );
77
        say_success( $out, "Patron quota preferences added successfully" );
72
    },
78
    },
(-)a/installer/data/mysql/mandatory/sysprefs.sql (+1 lines)
Lines 261-266 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
261
('EnableOpacSearchHistory','1','YesNo','Enable or disable opac search history',''),
261
('EnableOpacSearchHistory','1','YesNo','Enable or disable opac search history',''),
262
('EnablePointOfSale','0',NULL,'Enable the point of sale feature to allow anonymous transactions with the accounting system. (Requires UseCashRegisters)','YesNo'),
262
('EnablePointOfSale','0',NULL,'Enable the point of sale feature to allow anonymous transactions with the accounting system. (Requires UseCashRegisters)','YesNo'),
263
('EnableSearchHistory','0','','Enable or disable search history','YesNo'),
263
('EnableSearchHistory','0','','Enable or disable search history','YesNo'),
264
('EnableCirculationQuotas','0','','Enable or disable the circulation quotas feature','YesNo'),
264
('EnhancedMessagingPreferences','1','','If ON, allows patrons to select to receive additional messages about items due or nearly due.','YesNo'),
265
('EnhancedMessagingPreferences','1','','If ON, allows patrons to select to receive additional messages about items due or nearly due.','YesNo'),
265
('EnhancedMessagingPreferencesOPAC', '1', NULL, 'If ON, show patrons messaging setting on the OPAC.', 'YesNo'),
266
('EnhancedMessagingPreferencesOPAC', '1', NULL, 'If ON, show patrons messaging setting on the OPAC.', 'YesNo'),
266
('ERMModule', '0', NULL, 'Enable the e-resource management module', 'YesNo'),
267
('ERMModule', '0', NULL, 'Enable the e-resource management module', 'YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc (+2 lines)
Lines 203-213 Link Here
203
                    </li>
203
                    </li>
204
                [% END %]
204
                [% END %]
205
            [% END %]
205
            [% END %]
206
            [% IF Koha.Preference('EnableCirculationQuotas') %]
206
                [% IF patron.category.category_type == 'I' %]
207
                [% IF patron.category.category_type == 'I' %]
207
                    <li [% IF ( quotaview ) %]class="active">[% END %]>
208
                    <li [% IF ( quotaview ) %]class="active">[% END %]>
208
                        <a href="/cgi-bin/koha/members/circulation_quota.pl?borrowernumber=[% patron.borrowernumber | uri %]">Circulation quota</a>
209
                        <a href="/cgi-bin/koha/members/circulation_quota.pl?borrowernumber=[% patron.borrowernumber | uri %]">Circulation quota</a>
209
                    </li>
210
                    </li>
210
                [% END %]
211
                [% END %]
212
            [% END %]
211
            [% IF CAN_user_borrowers_edit_borrowers %]
213
            [% IF CAN_user_borrowers_edit_borrowers %]
212
                [% IF ( IntranetReadingHistoryHolds ) %]
214
                [% IF ( IntranetReadingHistoryHolds ) %]
213
                    <li [% IF holdshistoryview %]class="active"[% END %]>
215
                    <li [% IF holdshistoryview %]class="active"[% END %]>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref (-13 / +19 lines)
Lines 389-406 Circulation: Link Here
389
                  1: Allow
389
                  1: Allow
390
                  0: "Don't allow"
390
                  0: "Don't allow"
391
            - staff to check out an item with age restriction.
391
            - staff to check out an item with age restriction.
392
        -
393
            - pref: AllowQuotaOverride
394
              choices:
395
                  1: "Allow"
396
                  0: "Don't allow"
397
            - staff to check out items to patrons who have exceeded their quota limit.
398
        -
399
            - pref: UseGuarantorQuota
400
              choices:
401
                  1: "Use"
402
                  0: "Don't use"
403
            - guarantor's quota instead of guarantee's quota when checking out items if guarantor has an active quota and quota has enough availability.
404
        -
392
        -
405
            - Prevent patrons from checking out items if they have more than
393
            - Prevent patrons from checking out items if they have more than
406
            - pref: noissuescharge
394
            - pref: noissuescharge
Lines 1341-1346 Circulation: Link Here
1341
            - pref: SCOBatchCheckoutsValidCategories
1329
            - pref: SCOBatchCheckoutsValidCategories
1342
              choices: patron-categories
1330
              choices: patron-categories
1343
              class: multiple
1331
              class: multiple
1332
    Quotas:
1333
        -
1334
            - pref: EnableCirculationQuotas
1335
              choices:
1336
                  1: "Enable"
1337
                  0: "Disable"
1338
            - circulation quotas for patrons.
1339
        -
1340
            - pref: AllowQuotaOverride
1341
              choices:
1342
                  1: "Allow"
1343
                  0: "Don't allow"
1344
            - staff to check out items to patrons who have exceeded their quota limit.
1345
        -
1346
            - pref: UseGuarantorQuota
1347
              choices:
1348
                  1: "Use"
1349
                  0: "Don't use"
1350
            - guarantor's quota instead of guarantee's quota when checking out items if guarantor has an active quota and quota has enough availability.
1344
    Course reserves:
1351
    Course reserves:
1345
        -
1352
        -
1346
            - pref: UseCourseReserves
1353
            - pref: UseCourseReserves
1347
- 

Return to bug 38924