From 455164c4caa49a38322678bc1191a5f27a151c79 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Tue, 11 Feb 2025 14:14:09 +0000 Subject: [PATCH] Bug 38924: Add option to enable/disable quotas --- C4/Circulation.pm | 113 ++++++++++-------- .../atomicupdate/bug_38924-patron_quotas.pl | 28 +++-- installer/data/mysql/mandatory/sysprefs.sql | 1 + .../prog/en/includes/circ-menu.inc | 10 +- .../admin/preferences/circulation.pref | 31 +++-- 5 files changed, 107 insertions(+), 76 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index f38d6973a54..632f43e586a 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1376,26 +1376,28 @@ sub CanBookBeIssued { } # CHECK FOR QUOTAS - if ( my $quotas = $patron->all_quotas->filter_by_active ) { - if ( $quotas->count > 1 ) { - - # Multiple available quotas found - need confirmation from user - $needsconfirmation{QUOTA_SELECT} = $quotas; - } elsif ( $quotas->count == 1 ) { - my $quota = $quotas->next; - if ( !$quota->has_available_quota ) { - if ( C4::Context->preference("AllowQuotaOverride") ) { - $needsconfirmation{QUOTA_EXCEEDED} = { - available => $quota->available_quota, - total => $quota->allocation, - used => $quota->used, - }; - } else { - $issuingimpossible{QUOTA_EXCEEDED} = { - available => $quota->available_quota, - total => $quota->allocation, - used => $quota->used, - }; + if ( C4::Context->preference('EnableCirculationQuotas') ) { + if ( my $quotas = $patron->all_quotas->filter_by_active ) { + if ( $quotas->count > 1 ) { + + # Multiple available quotas found - need confirmation from user + $needsconfirmation{QUOTA_SELECT} = $quotas; + } elsif ( $quotas->count == 1 ) { + my $quota = $quotas->next; + if ( !$quota->has_available_quota ) { + if ( C4::Context->preference("AllowQuotaOverride") ) { + $needsconfirmation{QUOTA_EXCEEDED} = { + available => $quota->available_quota, + total => $quota->allocation, + used => $quota->used, + }; + } else { + $issuingimpossible{QUOTA_EXCEEDED} = { + available => $quota->available_quota, + total => $quota->allocation, + used => $quota->used, + }; + } } } } @@ -2031,19 +2033,24 @@ sub AddIssue { if C4::Context->preference('RealTimeHoldsQueue'); # Check quotas and record usage if needed - my $quota; - if ($selected_quota_id) { - $quota = Koha::Patron::Quotas->find($selected_quota_id); - } else { - $quota = $patron->all_quotas->filter_by_active->single; - } + if ( C4::Context->preference('EnableCirculationQuotas') ) { + my $quota; + if ($selected_quota_id) { + $quota = Koha::Patron::Quotas->find($selected_quota_id); + } else { + $quota = $patron->all_quotas->filter_by_active->single; + } + + if ($quota) { - if ($quota) { - # Update patron's used quota value - $quota->add_usage({ - patron_id => $patron->patron_id, - issue_id => $issue->issue_id, - }); + # Update patron's used quota value + $quota->add_usage( + { + patron_id => $patron->borrowernumber, + issue_id => $issue->issue_id, + } + ); + } } } } @@ -3418,18 +3425,20 @@ sub CanBookBeRenewed { } } - # # CHECK FOR QUOTAS - if ( my $quota_usage = Koha::Patron::Quota::Usages->find( { issue_id => $issue->issue_id } ) ) { + # # CHECK FOR QUOTAS + if ( C4::Context->preference('EnableCirculationQuotas') ) { + if ( my $quota_usage = Koha::Patron::Quota::Usages->find( { issue_id => $issue->issue_id } ) ) { - # Get current actives quota for the patron - if ( my $active_quotas = $patron->all_quotas->filter_by_active ) { - my $all_exceeded = 1; - while ( my $active_quota = $active_quotas->next ) { - if ( $active_quota->has_available_quota ) { - $all_exceeded = 0; + # Get current actives quota for the patron + if ( my $active_quotas = $patron->all_quotas->filter_by_active ) { + my $all_exceeded = 1; + while ( my $active_quota = $active_quotas->next ) { + if ( $active_quota->has_available_quota ) { + $all_exceeded = 0; + } } + return ( 0, "QUOTA_EXCEEDED" ) if $all_exceeded; } - return ( 0, "QUOTA_EXCEEDED" ) if $all_exceeded; } } @@ -3548,14 +3557,20 @@ sub AddRenewal { my $circ_library = Koha::Libraries->find( _GetCircControlBranch( $item_object, $patron ) ); # Check quotas and record usage if needed - if (my $quota_usage = Koha::Patron::Quota::Usages->find({ issue_id => $issue->issue_id })) { - # Get current active quota for the patron - if (my $active_quota = Koha::Patron::Quotas->find($quota_usage->patron_quota_id)) { - # Update patron's used quota value - $active_quota->add_usage({ - patron_id => $patron->borrowernumber, - issue_id => $issue->issue_id, - }); + if ( C4::Context->preference('EnableCirculationQuotas') ) { + if ( my $quota_usage = Koha::Patron::Quota::Usages->find( { issue_id => $issue->issue_id } ) ) { + + # Get current active quota for the patron + if ( my $active_quota = Koha::Patron::Quotas->find( $quota_usage->patron_quota_id ) ) { + + # Update patron's used quota value + $active_quota->add_usage( + { + patron_id => $patron->borrowernumber, + issue_id => $issue->issue_id, + } + ); + } } } diff --git a/installer/data/mysql/atomicupdate/bug_38924-patron_quotas.pl b/installer/data/mysql/atomicupdate/bug_38924-patron_quotas.pl index 7c1ae600b1a..67fea327011 100755 --- a/installer/data/mysql/atomicupdate/bug_38924-patron_quotas.pl +++ b/installer/data/mysql/atomicupdate/bug_38924-patron_quotas.pl @@ -25,21 +25,23 @@ return { ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; } ); - - $dbh->do(q{ + + $dbh->do( + q{ INSERT IGNORE INTO permissions (module_bit, code, description) VALUES (4, 'manage_borrower_quotas', 'Manage patron quotas'), (4, 'view_borrower_quotas', 'View patron quotas') - }); - + } + ); + say_success( $out, "Patron quota table and permissions created successfully" ); } else { say_info( $out, "Patron quota table already exists" ); } - unless ( TableExists('patron_quota_usage') ) - { - $dbh->do(q{ + unless ( TableExists('patron_quota_usage') ) { + $dbh->do( + q{ CREATE TABLE `patron_quota_usage` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique identifier for quota usage record', `patron_quota_id` int(11) NOT NULL COMMENT 'foreign key linking to patron_quota.id', @@ -54,19 +56,23 @@ return { CONSTRAINT `patron_quota_usage_ibfk_1` FOREIGN KEY (`patron_quota_id`) REFERENCES `patron_quota` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `patron_quota_usage_ibfk_2` FOREIGN KEY (`patron_id`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - }); + } + ); say_success( $out, "Patron quota usage table created successfully" ); } else { say_info( $out, "Patron quota usage table already exists" ); } - $dbh->do(q{ + $dbh->do( + q{ INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type) VALUES ('AllowQuotaOverride', '0', NULL, 'Allow staff to override and check out items to patrons who have exceeded their quota limit', 'YesNo'), - ('UseGuarantorQuota', '0', NULL, 'Use guarantor quota instead of guarantee quota when checking out items', 'YesNo') - }); + ('UseGuarantorQuota', '0', NULL, 'Use guarantor quota instead of guarantee quota when checking out items', 'YesNo'), + ('EnableCirculationQuotas','0','','Enable or disable the circulation quotas feature','YesNo') + } + ); say_success( $out, "Patron quota preferences added successfully" ); }, diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql index 254268e1d20..a8630be3454 100644 --- a/installer/data/mysql/mandatory/sysprefs.sql +++ b/installer/data/mysql/mandatory/sysprefs.sql @@ -261,6 +261,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('EnableAdvancedCatalogingEditor','0',NULL,'Enable the Rancor advanced cataloging editor','YesNo'), ('EnableBooking','1',NULL,'If enabled, activate every functionalities related with Bookings module','YesNo'), ('EnableBorrowerFiles','0',NULL,'If enabled, allows librarians to upload and attach arbitrary files to a borrower record.','YesNo'), +('EnableCirculationQuotas','0','','Enable or disable the circulation quotas feature','YesNo'), ('EnableExpiredPasswordReset', '0', NULL, 'Enable ability for patrons with expired password to reset their password directly', 'YesNo'), ('EnableItemGroupHolds','0',NULL,'Enable item groups holds feature','YesNo'), ('EnableItemGroups','0',NULL,'Enable the item groups feature','YesNo'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc index 2f0d1ca0fc2..4e72d08b5f5 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc @@ -211,10 +211,12 @@ Holds history [% END %] - [% IF patron.category.category_type == 'I' %] -
  • - Circulation quota -
  • + [% IF Koha.Preference('EnableCirculationQuotas') %] + [% IF patron.category.category_type == 'I' %] +
  • + Circulation quota +
  • + [% END %] [% END %] [% IF ( CAN_user_tools_view_system_logs ) %]
  • diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 7d92e725006..f46d99f7fbd 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -402,18 +402,6 @@ Circulation: 1: Allow 0: "Don't allow" - staff to check out an item with age restriction. - - - - pref: AllowQuotaOverride - choices: - 1: "Allow" - 0: "Don't allow" - - staff to check out items to patrons who have exceeded their quota limit. - - - - pref: UseGuarantorQuota - choices: - 1: "Use" - 0: "Don't use" - - guarantor's quota instead of guarantee's quota when checking out items if guarantor has an active quota and quota has enough availability. - - Prevent patrons from checking out items if they have more than - pref: noissuescharge @@ -1380,6 +1368,25 @@ Circulation: - pref: SCOBatchCheckoutsValidCategories choices: patron-categories class: multiple + Quotas: + - + - pref: EnableCirculationQuotas + choices: + 1: "Enable" + 0: "Disable" + - circulation quotas for patrons. + - + - pref: AllowQuotaOverride + choices: + 1: "Allow" + 0: "Don't allow" + - staff to check out items to patrons who have exceeded their quota limit. + - + - pref: UseGuarantorQuota + choices: + 1: "Use" + 0: "Don't use" + - guarantor's quota instead of guarantee's quota when checking out items if guarantor has an active quota and quota has enough availability. Course reserves: - - pref: UseCourseReserves -- 2.39.5