diff --git a/Koha/Hold.pm b/Koha/Hold.pm
index efb5b916c5..252a8bf3ed 100644
--- a/Koha/Hold.pm
+++ b/Koha/Hold.pm
@@ -271,6 +271,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 864056f443..78d6db6391 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/api/v1/swagger/definitions/hold_group.yaml b/api/v1/swagger/definitions/hold_group.yaml
index 271c262b58..4f12257950 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 0000000000..4d06435136
--- /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 998007871e..b78ace7c19 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -5113,6 +5113,20 @@ CREATE TABLE `old_issues` (
) 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 93108133a8..4b449f2741 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 () {
"";
}
+ if (oObj.is_hold_group_target) {
+ var link = __("target of hold group");
+ title +=
+ '
(' +
+ link +
+ ")";
+ }
+
return title;
},
},
diff --git a/svc/holds b/svc/holds
index 864841851a..4170f4585b 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{},