From c275d7321166570aa7acac815a6254c54b1af284 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Mon, 8 Sep 2025 18:47:01 +0100 Subject: [PATCH] Bug 3492: Add hold fees to circulation rules system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit integrates hold fee configuration into the main circulation rules system, providing granular control over hold fees based on patron category, item type, and branch combinations. Changes: - Add hold_fee as a new circulation rule type with full scope support - Remove deprecated reservefee column mapping from Koha::Patron::Category - Integrate hold fee input into the circulation rules admin interface - Add hold fee column to the main circulation rules matrix - Enable proper rule hierarchy resolution for hold fees Hold fees can now be configured at multiple levels with automatic fallback handling following standard circulation rule patterns. Sponsored-by: OpenFifth Signed-off-by: Jackie Usher Signed-off-by: Tomás Cohen Arazi --- Koha/CirculationRules.pm | 4 ++++ Koha/Patron/Category.pm | 1 - admin/smart-rules.pl | 3 +++ .../prog/en/modules/admin/smart-rules.tt | 13 ++++++++++++- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Koha/CirculationRules.pm b/Koha/CirculationRules.pm index 7bae491af5..d48e934041 100644 --- a/Koha/CirculationRules.pm +++ b/Koha/CirculationRules.pm @@ -86,6 +86,10 @@ our $RULE_KINDS = { scope => [ 'branchcode', 'categorycode' ], is_monetary => 1, }, + hold_fee => { + scope => [ 'branchcode', 'categorycode', 'itemtype' ], + is_monetary => 1, + }, open_article_requests_limit => { scope => [ 'branchcode', 'categorycode' ], }, diff --git a/Koha/Patron/Category.pm b/Koha/Patron/Category.pm index ab4973b544..b7aad5f43f 100644 --- a/Koha/Patron/Category.pm +++ b/Koha/Patron/Category.pm @@ -311,7 +311,6 @@ sub to_api_mapping { dateofbirthrequired => 'lower_age_limit', enrolmentfee => 'enrolment_fee', overduenoticerequired => 'overdue_notice_required', - reservefee => 'reserve_fee', hidelostitems => 'hide_lost_items', category_type => 'category_type', BlockExpiredPatronOpacActions => 'block_expired_patron_opac_actions', diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index 2c1ed57a44..d0385051dd 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -121,6 +121,7 @@ if ( $op eq 'cud-delete' ) { recall_shelf_time => undef, decreaseloanholds => undef, holds_pickup_period => undef, + hold_fee => undef, } } ); @@ -318,6 +319,7 @@ elsif ( $op eq 'cud-add' ) { my $recall_overdue_fine = $input->param('recall_overdue_fine'); my $recall_shelf_time = $input->param('recall_shelf_time'); my $holds_pickup_period = strip_non_numeric( scalar $input->param('holds_pickup_period') ); + my $hold_fee = $input->param('hold_fee') || q{}; my $rules = { maxissueqty => $maxissueqty, @@ -361,6 +363,7 @@ elsif ( $op eq 'cud-add' ) { recall_overdue_fine => $recall_overdue_fine, recall_shelf_time => $recall_shelf_time, holds_pickup_period => $holds_pickup_period, + hold_fee => $hold_fee, }; Koha::CirculationRules->set_rules( diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index 4930108177..118162419b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -156,6 +156,7 @@ On shelf holds allowed OPAC item level holds Holds pickup period (day) + Hold fee [% IF Koha.Preference('ArticleRequests') %] Article requests [% END %] @@ -218,8 +219,9 @@ [% SET recall_overdue_fine = all_rules.$c.$i.recall_overdue_fine %] [% SET recall_shelf_time = all_rules.$c.$i.recall_shelf_time %] [% SET holds_pickup_period = all_rules.$c.$i.holds_pickup_period %] + [% SET hold_fee = all_rules.$c.$i.hold_fee %] - [% SET show_rule = note || maxissueqty || maxonsiteissueqty || issuelength || daysmode || lengthunit || hardduedate || hardduedatecompare || fine || chargeperiod || chargeperiod_charge_at || firstremind || overduefinescap || cap_fine_to_replacement_price || expire_reserves_charge || finedays || maxsuspensiondays || suspension_chargeperiod || renewalsallowed || unseenrenewalsallowed || renewalperiod || norenewalbefore || noautorenewalbefore || auto_renew || no_auto_renewal_after || no_auto_renewal_after_hard_limit || reservesallowed || holds_per_day || holds_per_record || onshelfholds || opacitemholds || article_requests || rentaldiscount || decreaseloanholds || recalls_allowed || recalls_per_record || on_shelf_recalls || recall_due_date_interval || recall_overdue_fine || recall_shelf_time || holds_pickup_period %] + [% SET show_rule = note || maxissueqty || maxonsiteissueqty || issuelength || daysmode || lengthunit || hardduedate || hardduedatecompare || fine || chargeperiod || chargeperiod_charge_at || firstremind || overduefinescap || cap_fine_to_replacement_price || expire_reserves_charge || finedays || maxsuspensiondays || suspension_chargeperiod || renewalsallowed || unseenrenewalsallowed || renewalperiod || norenewalbefore || noautorenewalbefore || auto_renew || no_auto_renewal_after || no_auto_renewal_after_hard_limit || reservesallowed || holds_per_day || holds_per_record || onshelfholds || opacitemholds || article_requests || rentaldiscount || decreaseloanholds || recalls_allowed || recalls_per_record || on_shelf_recalls || recall_due_date_interval || recall_overdue_fine || recall_shelf_time || holds_pickup_period || hold_fee %] [% IF show_rule %] [% SET row_count = row_count + 1 %] @@ -412,6 +414,13 @@ [% holds_pickup_period | html %] [% END %] + + [% IF hold_fee.defined && hold_fee != '' %] + [% hold_fee | $Price %] + [% ELSE %] + 0.00 + [% END %] + [% IF Koha.Preference('ArticleRequests') %] [% IF article_requests == 'no' %] @@ -565,6 +574,7 @@ + [% IF Koha.Preference('ArticleRequests') %]