Bugzilla – Attachment 184868 Details for
Bug 40529
Update how hold groups work
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 40529: Add hold group targets logic
Bug-40529-Add-hold-group-targets-logic.patch (text/plain), 11.49 KB, created by
Pedro Amorim
on 2025-07-30 11:58:08 UTC
(
hide
)
Description:
Bug 40529: Add hold group targets logic
Filename:
MIME Type:
Creator:
Pedro Amorim
Created:
2025-07-30 11:58:08 UTC
Size:
11.49 KB
patch
obsolete
>From 941bd674c0db8d612139693fd8b7fbd06ead465b Mon Sep 17 00:00:00 2001 >From: Pedro Amorim <pedro.amorim@openfifth.co.uk> >Date: Fri, 25 Jul 2025 13:11:05 +0000 >Subject: [PATCH] Bug 40529: Add hold group targets logic > >Hold group target hold: >The hold that is set as the hold group's target. If a hold group has a >hold target, subsequent check-ins that would 'trap' items to the >remaining holds in the group are instead skipped. >--- > Koha/Hold.pm | 18 +++ > Koha/HoldGroup.pm | 16 +++ > Koha/Schema/Result/HoldGroup.pm | 19 ++- > Koha/Schema/Result/HoldGroupTargetHold.pm | 126 ++++++++++++++++++ > Koha/Schema/Result/Reserve.pm | 19 ++- > api/v1/swagger/definitions/hold_group.yaml | 3 + > .../bug_40529_-_hold_group_table_target.pl | 25 ++++ > installer/data/mysql/kohastructure.sql | 14 ++ > koha-tmpl/intranet-tmpl/prog/js/holds.js | 8 ++ > svc/holds | 1 + > 10 files changed, 245 insertions(+), 4 deletions(-) > create mode 100644 Koha/Schema/Result/HoldGroupTargetHold.pm > create mode 100755 installer/data/mysql/atomicupdate/bug_40529_-_hold_group_table_target.pl > >diff --git a/Koha/Hold.pm b/Koha/Hold.pm >index e4ce7dae264..876036d0010 100644 >--- a/Koha/Hold.pm >+++ b/Koha/Hold.pm >@@ -200,6 +200,24 @@ sub cleanup_hold_group { > } > } > >+=head3 is_hold_group_target >+ >+$self->is_hold_group_target; >+ >+Returns whether this hold is its hold group target >+ >+=cut >+ >+sub is_hold_group_target { >+ my ($self) = @_; >+ >+ return 1 >+ if $self->hold_group >+ && $self->hold_group->target_hold_id >+ && $self->hold_group->target_hold_id eq $self->reserve_id; >+ return 0; >+} >+ > =head3 set_transfer > > =cut >diff --git a/Koha/HoldGroup.pm b/Koha/HoldGroup.pm >index 7a7ae302408..028ae70516d 100644 >--- a/Koha/HoldGroup.pm >+++ b/Koha/HoldGroup.pm >@@ -78,6 +78,22 @@ sub holds { > return Koha::Holds->_new_from_dbic($holds_rs); > } > >+=head3 target_hold_id >+ >+ $holds = $hold_group->target_hold_id >+ >+Return the target_hold_id >+ >+=cut >+ >+sub target_hold_id { >+ my ($self) = @_; >+ >+ return unless $self->_result->hold_group_target_hold; >+ >+ return $self->_result->hold_group_target_hold->reserve_id; >+} >+ > =head3 _type > > =cut >diff --git a/Koha/Schema/Result/HoldGroup.pm b/Koha/Schema/Result/HoldGroup.pm >index 173e7443e2a..42bf74e4477 100644 >--- a/Koha/Schema/Result/HoldGroup.pm >+++ b/Koha/Schema/Result/HoldGroup.pm >@@ -95,6 +95,21 @@ __PACKAGE__->belongs_to( > }, > ); > >+=head2 hold_group_target_hold >+ >+Type: might_have >+ >+Related object: L<Koha::Schema::Result::HoldGroupTargetHold> >+ >+=cut >+ >+__PACKAGE__->might_have( >+ "hold_group_target_hold", >+ "Koha::Schema::Result::HoldGroupTargetHold", >+ { "foreign.hold_group_id" => "self.hold_group_id" }, >+ { cascade_copy => 0, cascade_delete => 0 }, >+); >+ > =head2 old_reserves > > Type: has_many >@@ -126,8 +141,8 @@ __PACKAGE__->has_many( > ); > > >-# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-25 13:02:35 >-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hlAYDHvqpFZRpNU+d+y4RA >+# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-25 13:10:48 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3CiPWMgltRazKxPlIb5x3g > > > # You can replace this text with custom code or comments, and it will be preserved on regeneration >diff --git a/Koha/Schema/Result/HoldGroupTargetHold.pm b/Koha/Schema/Result/HoldGroupTargetHold.pm >new file mode 100644 >index 00000000000..b23ea3146bc >--- /dev/null >+++ b/Koha/Schema/Result/HoldGroupTargetHold.pm >@@ -0,0 +1,126 @@ >+use utf8; >+package Koha::Schema::Result::HoldGroupTargetHold; >+ >+# Created by DBIx::Class::Schema::Loader >+# DO NOT MODIFY THE FIRST PART OF THIS FILE >+ >+=head1 NAME >+ >+Koha::Schema::Result::HoldGroupTargetHold >+ >+=cut >+ >+use strict; >+use warnings; >+ >+use base 'DBIx::Class::Core'; >+ >+=head1 TABLE: C<hold_group_target_holds> >+ >+=cut >+ >+__PACKAGE__->table("hold_group_target_holds"); >+ >+=head1 ACCESSORS >+ >+=head2 hold_group_id >+ >+ data_type: 'integer' >+ extra: {unsigned => 1} >+ is_foreign_key: 1 >+ is_nullable: 0 >+ >+foreign key, linking this to the hold_groups table >+ >+=head2 reserve_id >+ >+ data_type: 'integer' >+ is_foreign_key: 1 >+ is_nullable: 1 >+ >+foreign key, linking this to the reserves table >+ >+=cut >+ >+__PACKAGE__->add_columns( >+ "hold_group_id", >+ { >+ data_type => "integer", >+ extra => { unsigned => 1 }, >+ is_foreign_key => 1, >+ is_nullable => 0, >+ }, >+ "reserve_id", >+ { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, >+); >+ >+=head1 UNIQUE CONSTRAINTS >+ >+=head2 C<hold_group_id> >+ >+=over 4 >+ >+=item * L</hold_group_id> >+ >+=back >+ >+=cut >+ >+__PACKAGE__->add_unique_constraint("hold_group_id", ["hold_group_id"]); >+ >+=head2 C<reserve_id> >+ >+=over 4 >+ >+=item * L</reserve_id> >+ >+=back >+ >+=cut >+ >+__PACKAGE__->add_unique_constraint("reserve_id", ["reserve_id"]); >+ >+=head1 RELATIONS >+ >+=head2 hold_group >+ >+Type: belongs_to >+ >+Related object: L<Koha::Schema::Result::HoldGroup> >+ >+=cut >+ >+__PACKAGE__->belongs_to( >+ "hold_group", >+ "Koha::Schema::Result::HoldGroup", >+ { hold_group_id => "hold_group_id" }, >+ { is_deferrable => 1, on_delete => "CASCADE", on_update => "RESTRICT" }, >+); >+ >+=head2 reserve >+ >+Type: belongs_to >+ >+Related object: L<Koha::Schema::Result::Reserve> >+ >+=cut >+ >+__PACKAGE__->belongs_to( >+ "reserve", >+ "Koha::Schema::Result::Reserve", >+ { reserve_id => "reserve_id" }, >+ { >+ is_deferrable => 1, >+ join_type => "LEFT", >+ on_delete => "CASCADE", >+ on_update => "RESTRICT", >+ }, >+); >+ >+ >+# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-25 13:10:48 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:xgRnzTXH+Q+YxYLKQeGe+g >+ >+ >+# You can replace this text with custom code or comments, and it will be preserved on regeneration >+1; >diff --git a/Koha/Schema/Result/Reserve.pm b/Koha/Schema/Result/Reserve.pm >index 664df77b482..9de57b5451e 100644 >--- a/Koha/Schema/Result/Reserve.pm >+++ b/Koha/Schema/Result/Reserve.pm >@@ -440,6 +440,21 @@ __PACKAGE__->belongs_to( > }, > ); > >+=head2 hold_group_target_hold >+ >+Type: might_have >+ >+Related object: L<Koha::Schema::Result::HoldGroupTargetHold> >+ >+=cut >+ >+__PACKAGE__->might_have( >+ "hold_group_target_hold", >+ "Koha::Schema::Result::HoldGroupTargetHold", >+ { "foreign.reserve_id" => "self.reserve_id" }, >+ { cascade_copy => 0, cascade_delete => 0 }, >+); >+ > =head2 item_group > > Type: belongs_to >@@ -501,8 +516,8 @@ __PACKAGE__->belongs_to( > ); > > >-# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-25 13:02:35 >-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:x5AS7F7aOMb9ihb8gaxZvQ >+# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-07-25 13:10:48 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hipLVZ6zkbJZha+kYRMslQ > > __PACKAGE__->belongs_to( > "item", >diff --git a/api/v1/swagger/definitions/hold_group.yaml b/api/v1/swagger/definitions/hold_group.yaml >index 271c262b58b..4f122579503 100644 >--- a/api/v1/swagger/definitions/hold_group.yaml >+++ b/api/v1/swagger/definitions/hold_group.yaml >@@ -10,6 +10,9 @@ properties: > visual_hold_group_id: > type: integer > description: Visual ID for this hold group, in the context of the related patron >+ target_hold_id: >+ type: integer >+ description: Target hold ID of this hold group > holds: > type: > - array >diff --git a/installer/data/mysql/atomicupdate/bug_40529_-_hold_group_table_target.pl b/installer/data/mysql/atomicupdate/bug_40529_-_hold_group_table_target.pl >new file mode 100755 >index 00000000000..4d064351362 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_40529_-_hold_group_table_target.pl >@@ -0,0 +1,25 @@ >+use Modern::Perl; >+use Koha::Installer::Output qw(say_warning say_success say_info); >+ >+return { >+ bug_number => "40529", >+ description => "Add 'hold_groups_target_hold_id' column to hold_groups", >+ up => sub { >+ my ($args) = @_; >+ my ( $dbh, $out ) = @$args{qw(dbh out)}; >+ >+ unless ( TableExists('hold_group_target_holds') ) { >+ $dbh->do( >+ q{ >+ CREATE TABLE hold_group_target_holds ( >+ `hold_group_id` int unsigned NOT NULL UNIQUE COMMENT 'foreign key, linking this to the hold_groups table', >+ `reserve_id` int(11) DEFAULT NULL UNIQUE COMMENT 'foreign key, linking this to the reserves table', >+ CONSTRAINT `hold_group_target_holds_ibfk_1` FOREIGN KEY (`hold_group_id`) REFERENCES `hold_groups` (`hold_group_id`) ON DELETE CASCADE, >+ CONSTRAINT `hold_group_target_holds_ibfk_2` FOREIGN KEY (`reserve_id`) REFERENCES `reserves` (`reserve_id`) ON DELETE CASCADE >+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; >+ } >+ ); >+ say_success( $out, "Added table 'hold_group_target_holds'" ); >+ } >+ }, >+}; >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index 4ce20a82efe..49d8a28a635 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -5074,6 +5074,20 @@ CREATE TABLE hold_groups ( > ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; > /*!40101 SET character_set_client = @saved_cs_client */; > >+-- >+-- Table structure for table `hold_group_target_holds` >+-- >+DROP TABLE IF EXISTS `hold_group_target_holds`; >+/*!40101 SET @saved_cs_client = @@character_set_client */; >+/*!40101 SET character_set_client = utf8 */; >+CREATE TABLE hold_group_target_holds ( >+ `hold_group_id` int unsigned NOT NULL UNIQUE COMMENT 'foreign key, linking this to the hold_groups table', >+ `reserve_id` int(11) DEFAULT NULL UNIQUE COMMENT 'foreign key, linking this to the reserves table', >+ CONSTRAINT `hold_group_target_holds_ibfk_1` FOREIGN KEY (`hold_group_id`) REFERENCES `hold_groups` (`hold_group_id`) ON DELETE CASCADE, >+ CONSTRAINT `hold_group_target_holds_ibfk_2` FOREIGN KEY (`reserve_id`) REFERENCES `reserves` (`reserve_id`) ON DELETE CASCADE >+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; >+/*!40101 SET character_set_client = @saved_cs_client */; >+ > -- > -- Table structure for table `old_reserves` > -- >diff --git a/koha-tmpl/intranet-tmpl/prog/js/holds.js b/koha-tmpl/intranet-tmpl/prog/js/holds.js >index 24883d040e7..bed19e2c90f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/holds.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/holds.js >@@ -259,6 +259,14 @@ $(document).ready(function () { > "</span>"; > } > >+ if (oObj.is_hold_group_target) { >+ var link = __("target of hold group"); >+ title += >+ '<br><span class="fw-bold fst-italic">(' + >+ link + >+ ")</span>"; >+ } >+ > return title; > }, > }, >diff --git a/svc/holds b/svc/holds >index a755a7f422a..80c7f4d25ab 100755 >--- a/svc/holds >+++ b/svc/holds >@@ -115,6 +115,7 @@ while ( my $h = $holds_rs->next() ) { > itemtype_limit => $itemtype_limit, > hold_group_id => $h->hold_group_id, > visual_hold_group_id => $h->hold_group ? $h->hold_group->visual_hold_group_id : q{}, >+ is_hold_group_target => $h->is_hold_group_target, > reservedate_formatted => $h->reservedate() > ? output_pref( { dt => dt_from_string( $h->reservedate() ), dateonly => 1 } ) > : q{}, >-- >2.39.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 40529
:
184868
|
184869
|
184870
|
184871
|
184872
|
185137
|
185138
|
185139
|
185140
|
185141
|
185210
|
185211
|
185212
|
185213
|
185214
|
185215
|
185303
|
185304
|
185305
|
185306
|
185307