From 3f8594d0ebe3bd2c6d0e982350023150f1ac0bc1 Mon Sep 17 00:00:00 2001 From: Brendan Lawlor Date: Tue, 19 Aug 2025 19:16:00 +0000 Subject: [PATCH] Bug 39419: Enable Holds API to set expiration_date and patron_expiration_date independently This patch adds patron_expiration_date as a new parameter to the Holds API for the add and edit methods. To test: 1. Apply patch and restart_all 2. Make some requests to add holds like POST /api/v1/holds example body: { "biblio_id": "22", "patron_id": "42", "pickup_library_id": "FFL", "expiration_date": "2099-12-31", "patron_expiration_date": "3099-01-01" } 3. Verify that you can set the expiration_date and patron_expiration_date indepdently 4. Confirm that patron_expiration_date is a new field in the API response 5. Make note of the hold_id in the response for the next step 6. Make some requests to edit the hold like PATCH /api/v1/holds/{hold_id} example body: { "patron_expiration_date": "2999-09-19", "expiration_date": "2031-09-19" } 7. Verify that you can set the expiration_date and patron_expiration_date indepdently 8. Make sure making and modifying holds isn't broken in the staff intterface or opac --- C4/Reserves.pm | 27 +++++++---- Koha/Hold.pm | 2 +- Koha/REST/V1/Holds.pm | 70 +++++++++++++++------------- api/v1/swagger/definitions/hold.yaml | 6 +++ api/v1/swagger/paths/holds.yaml | 12 +++++ 5 files changed, 73 insertions(+), 44 deletions(-) diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 87a645a3e3..f17d4423b6 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -150,6 +150,7 @@ BEGIN { priority => $priority, reservation_date => $reservation_date, expiration_date => $expiration_date, + patron_expiration_date, => $patron_expiration_date, notes => $notes, title => $title, itemnumber => $itemnumber, @@ -184,7 +185,8 @@ sub AddReserve { my $biblionumber = $params->{biblionumber}; my $priority = $params->{priority}; my $resdate = $params->{reservation_date}; - my $patron_expiration_date = $params->{expiration_date}; + my $expiration_date = $params->{expiration_date}; + my $patron_expiration_date = $params->{patron_expiration_date}; my $notes = $params->{notes}; my $title = $params->{title}; my $checkitem = $params->{itemnumber}; @@ -250,6 +252,7 @@ sub AddReserve { itemnumber => $checkitem, found => $found, waitingdate => $waitingdate, + expirationdate => $expiration_date, patron_expiration_date => $patron_expiration_date, itemtype => $itemtype, item_level_hold => $checkitem ? 1 : 0, @@ -1081,15 +1084,16 @@ itemnumber and supplying itemnumber. sub ModReserve { my ($params) = @_; - my $rank = $params->{'rank'}; - my $reserve_id = $params->{'reserve_id'}; - my $branchcode = $params->{'branchcode'}; - my $itemnumber = $params->{'itemnumber'}; - my $suspend_until = $params->{'suspend_until'}; - my $borrowernumber = $params->{'borrowernumber'}; - my $biblionumber = $params->{'biblionumber'}; - my $cancellation_reason = $params->{'cancellation_reason'}; - my $date = $params->{expirationdate}; + my $rank = $params->{'rank'}; + my $reserve_id = $params->{'reserve_id'}; + my $branchcode = $params->{'branchcode'}; + my $itemnumber = $params->{'itemnumber'}; + my $suspend_until = $params->{'suspend_until'}; + my $borrowernumber = $params->{'borrowernumber'}; + my $biblionumber = $params->{'biblionumber'}; + my $cancellation_reason = $params->{'cancellation_reason'}; + my $date = $params->{expirationdate}; + my $patron_expiration_date = $params->{patron_expiration_date}; return if defined $rank && $rank eq "n"; @@ -1134,6 +1138,9 @@ sub ModReserve { if ( exists $params->{expirationdate} ) { $properties->{expirationdate} = $params->{expirationdate} || undef; } + if ( exists $params->{patron_expiration_date} ) { + $properties->{patron_expiration_date} = $params->{patron_expiration_date} || undef; + } $hold->set($properties)->store(); diff --git a/Koha/Hold.pm b/Koha/Hold.pm index c44d46a56a..4610992de3 100644 --- a/Koha/Hold.pm +++ b/Koha/Hold.pm @@ -1084,7 +1084,7 @@ sub to_api_mapping { itemnumber => 'item_id', waitingdate => 'waiting_date', expirationdate => 'expiration_date', - patron_expiration_date => undef, + patron_expiration_date => 'patron_expiration_date', lowestPriority => 'lowest_priority', suspend => 'suspended', suspend_until => 'suspended_until', diff --git a/Koha/REST/V1/Holds.pm b/Koha/REST/V1/Holds.pm index 33c885774c..422f4faa1f 100644 --- a/Koha/REST/V1/Holds.pm +++ b/Koha/REST/V1/Holds.pm @@ -76,16 +76,17 @@ sub add { my $biblio; my $item; - my $biblio_id = $body->{biblio_id}; - my $item_group_id = $body->{item_group_id}; - my $pickup_library_id = $body->{pickup_library_id}; - my $item_id = $body->{item_id}; - my $patron_id = $body->{patron_id}; - my $item_type = $body->{item_type}; - my $expiration_date = $body->{expiration_date}; - my $notes = $body->{notes}; - my $hold_date = $body->{hold_date}; - my $non_priority = $body->{non_priority}; + my $biblio_id = $body->{biblio_id}; + my $item_group_id = $body->{item_group_id}; + my $pickup_library_id = $body->{pickup_library_id}; + my $item_id = $body->{item_id}; + my $patron_id = $body->{patron_id}; + my $item_type = $body->{item_type}; + my $expiration_date = $body->{expiration_date}; + my $patron_expiration_date = $body->{patron_expiration_date}; + my $notes = $body->{notes}; + my $hold_date = $body->{hold_date}; + my $non_priority = $body->{non_priority}; my $overrides = $c->stash('koha.overrides'); my $can_override = C4::Context->preference('AllowHoldPolicyOverride') // 0; @@ -193,19 +194,20 @@ sub add { my $hold_id = C4::Reserves::AddReserve( { - branchcode => $pickup_library_id, - borrowernumber => $patron_id, - biblionumber => $biblio->id, - priority => $priority, - reservation_date => $hold_date, - expiration_date => $expiration_date, - notes => $notes, - title => $biblio->title, - itemnumber => $item_id, - found => undef, # TODO: Why not? - itemtype => $item_type, - non_priority => $non_priority, - item_group_id => $item_group_id, + branchcode => $pickup_library_id, + borrowernumber => $patron_id, + biblionumber => $biblio->id, + priority => $priority, + reservation_date => $hold_date, + expiration_date => $expiration_date, + patron_expiration_date => $patron_expiration_date, + notes => $notes, + title => $biblio->title, + itemnumber => $item_id, + found => undef, # TODO: Why not? + itemtype => $item_type, + non_priority => $non_priority, + item_group_id => $item_group_id, } ); @@ -274,21 +276,23 @@ sub edit { } $pickup_library_id //= $hold->branchcode; - my $priority = $body->{priority} // $hold->priority; - my $hold_date = $body->{hold_date} // $hold->reservedate; - my $expiration_date = $body->{expiration_date} // $hold->expirationdate; + my $priority = $body->{priority} // $hold->priority; + my $hold_date = $body->{hold_date} // $hold->reservedate; + my $expiration_date = $body->{expiration_date} // $hold->expirationdate; + my $patron_expiration_date = $body->{patron_expiration_date} // $hold->patron_expiration_date; # suspended_until can also be set to undef my $suspended_until = $body->{suspended_until} || $hold->suspend_until; my $params = { - reserve_id => $hold->id, - branchcode => $pickup_library_id, - rank => $priority, - suspend_until => $suspended_until, - itemnumber => $hold->itemnumber, - reservedate => $hold_date, - expirationdate => $expiration_date, + reserve_id => $hold->id, + branchcode => $pickup_library_id, + rank => $priority, + suspend_until => $suspended_until, + itemnumber => $hold->itemnumber, + reservedate => $hold_date, + expirationdate => $expiration_date, + patron_expiration_date => $patron_expiration_date, }; C4::Reserves::ModReserve($params); diff --git a/api/v1/swagger/definitions/hold.yaml b/api/v1/swagger/definitions/hold.yaml index af3cd55087..3ce0d92cae 100644 --- a/api/v1/swagger/definitions/hold.yaml +++ b/api/v1/swagger/definitions/hold.yaml @@ -86,6 +86,12 @@ properties: - "null" format: date description: The date the hold expires + patron_expiration_date: + type: + - string + - "null" + format: date + description: The date the patron sets as not wanted after lowest_priority: type: boolean description: Controls if the hold is given the lowest priority on the queue diff --git a/api/v1/swagger/paths/holds.yaml b/api/v1/swagger/paths/holds.yaml index 8181cfd044..f1b17f4c09 100644 --- a/api/v1/swagger/paths/holds.yaml +++ b/api/v1/swagger/paths/holds.yaml @@ -194,6 +194,12 @@ - string - "null" format: date + patron_expiration_date: + description: Hold not wanted after date + type: + - string + - "null" + format: date notes: description: Notes related to this hold type: @@ -315,6 +321,12 @@ description: Hold's expiration date type: string format: date + patron_expiration_date: + description: Hold's not wanted after date + type: + - string + - "null" + format: date additionalProperties: false consumes: - application/json -- 2.39.5