Commit Graph

58683 Commits

Author SHA1 Message Date
Tomas Cohen Arazi 3e2551a956
Bug 40275: Introduce `Koha::Patrons->find_by_identifier()`
In our codebase, there's a pattern we tend to use for searching patrons
by userid and falling back to find them by cardnumber:

* C4::Auth
* C4::SIP::ILS::Patron
* (slightly different) Koha::REST::V1::Auth::Password
* (slightly different) Koha::REST::V1::Auth
* C4::Circulation
* C4::Auth_with_cas

It generally uses the following pattern:

```perl
my $patron = Koha::Patrons->find( { userid => $identifier } );
$patron //= Koha::Patrons->find( { cardnumber => $identifier } );
```

The problem with this is that `find` actually produces a DBIX::Class
warn because `find` is being called without primary key parameters. I
haven't seen it in the wild, until the latest change in
`checkpw_internal` which made it throw warnings in SIP. My
interpretation is that SIP's special approach with the Trapper.pm class
made it show where other places just get it hidden.

That said, I implemented this using `search()` to overcome this.

To test:
1. Apply the patches
2. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Koha/Patrons.t
=> SUCCESS: Tests pass!
3. Sign off :-D

Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 3f19d4bf85)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:36 +02:00
Tomas Cohen Arazi 1d0ba36aec
Bug 40275: Unit tests
Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 666223d61e)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:36 +02:00
Paul Derscheid f719d3e2cf
Bug 36789: (follow-up) Adjust bookings/list.tt to handle bookings completed status
- Add fa-check-circle as an icon to "Transform to checkout" button
- Remove unncessary booking_id input, placeholder and value in format call.
- Include completed in
    - editable property of vis-timeline
    - filters array of additional filters include
    - init call to AdditionalFilters lib
    - onChange handler of AdditionalFilters lib
    - condition for rendering actions

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 78983569dd)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:35 +02:00
Thibaud Guillot 9f3ebef35b
Bug 36789: (follow-up) Fix CSRF Token missing
Sponsored-by: LMS Cloud <https://www.lmscloud.de/>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Olivier V <olivier.vezina@inLibro.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 087ffd0eea)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:34 +02:00
Thibaud Guillot e7526d0169
Bug 36789: Transform a booking into checkout
Directly from the bookings list, you can perform a checkout with booked
item.

Test plan:

1) Got an item booked :)
2) Click on transform to checkout
3) Normally you will be redirected to circulation.pl checkout view with
   form infos from booking.
4) If issue is confirmed, the booking will be completed.

Sponsored-by: Association de Gestion des Œuvres Sociales d'Inria (AGOS)
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Olivier V <olivier.vezina@inLibro.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 8efe9aee5c)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:34 +02:00
Martin Renvoize 1fe7bb8be4
Bug 40656: (QA follow-up) Destroy formatting for QA script
We really need a better fix at the translation script level for bug
18675. This change makes the template so much less readable!

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit dd73f9b0ce)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:33 +02:00
Martin Renvoize 7483aa554f
Bug 40656: (follow-up) Always display Status column in bookings table
The Status column was previously only visible when filters were applied,
making the interface inconsistent and potentially confusing. This change
ensures the Status column is always displayed regardless of filter state.

Test plan:
1. Navigate to a biblio record with bookings
2. Go to the Bookings tab
3. Verify the Status column is visible in the bookings table
4. Apply filters (Include expired/Include cancelled)
5. Verify the Status column remains visible
6. Remove all filters
7. Confirm the Status column is still visible and shows appropriate
   status badges (New, Pending, Active, etc.)

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 3e168c7176)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:33 +02:00
Paul Derscheid 5751aa982f
Bug 40656: (follow-up) Correct inverted logic for column visibility
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit e655cbd95f)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:32 +02:00
Paul Derscheid 563e93225b
Bug 40656: (follow-up) Create reusable additional filters library for DataTables
This follow-up patch extracts the filter functionality into a reusable library:
- Create AdditionalFilters.js library with chainable API for filter
functionality
- Rename table-filters.inc to additional-filters.inc for clarity
- Refactor to use explicit element IDs instead of interpolation for
better greppability (filter-expired vs filter-${id})
- Include proper cleanup methods (destroy) for memory management

The library provides a fluent API:
AdditionalFilters.init(['filter-expired', 'filter-cancelled'])
    .onChange((filters, { anyFiltersApplied }) => { ... })
    .build({ status: ({ filters, isNotApplied }) => ... });

Test plan remains identical except for applying both patches on step 1.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit e358823091)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:32 +02:00
Paul Derscheid bdb6a1a0ed
Bug 40656: Refactor bookings/list.tt to use better patterns and improve code organization
This patch aims to improve bookings/list.tt:
- Converting filter attributes to boolean data attributes (presence-based)
- Creating a reusable table-filters.inc for filter controls
- Moving inline styles to proper SCSS files for better caching and separation of concerns
- Fixing a runtime error when cancelling bookings from the timeline
- Improving JavaScript readability with helper functions
- Addressing the QA complaints from Bug 36789:
    - Cleaning up the long lines for the button elements by moving them into template literals
    - Using the format method instead of direct interpolation
    - Using escape_str for all values received from the API.

Test plan:
1. Apply the patch and compile css
2. Navigate to a biblio record with bookings (Catalog > Search > View record > Bookings)
3. Verify the filter buttons (Exclude expired/cancelled) appear correctly
4. Click each filter button and verify:
 - The button text toggles between "Include" and "Exclude"
 - The table updates to show/hide the appropriate bookings
 - The status column appears when any items are filtered
5. In the timeline view:
 - Verify cancelled bookings show with a strikethrough pattern
 - Try to cancel a booking by clicking the X on a timeline item
 - Confirm the cancel modal opens without JavaScript errors
6. Check that the table actions (Edit, Cancel) work correctly
7. Verify no inline styles remain in the page source
8. Confirm the filter styles are properly loaded from compiled CSS

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 3aac509787)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:31 +02:00
Lucas Gass 93d2e29507
Bug 9762: (follow-up) Mock the user branch in NoIssuesChargeGuarantees.t and dateexpiry.t tests
Without the patch:

t/db_dependent/Circulation/NoIssuesChargeGuarantees.t fails
t/db_dependent/Circulation/dateexpiry.t fails

With the patch:

t/db_dependent/Circulation/NoIssuesChargeGuarantees.t passes
t/db_dependent/Circulation/dateexpiry.t passes

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 1ea765d3bd)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:31 +02:00
Lucas Gass 3bc4add338
Bug 9762: Adjust number of tests in CanBookBeIssued.t
Without this patch:

t/db_dependent/Circulation/CanBookBeIssued.t failes

With this patch:

t/db_dependent/Circulation/CanBookBeIssued.t passes

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit a12b523113)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:30 +02:00
Lucas Gass 9f7222f44c
Bug 9762: (follow-up) Add Test::NoWarnings to CanBookBeIssued.t
Without this patch:

prove -v /kohadevbox/koha/xt/use-test-no-warnings.t fails

With this patch:

prove -v /kohadevbox/koha/xt/use-test-no-warnings.t passes

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 942df980da)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:28 +02:00
Martin Renvoize 3334d14cae
Bug 9762: (follow-up) Add integration tests and improve AddRenewal logging consistency
This commit adds two key improvements to the Bug 9762 circulation override logging:

1. **Consistent JSON Logging**: Updated AddRenewal to always log in JSON format,
   matching AddIssue behavior. Previously AddRenewal only logged JSON when
   confirmations/forced were present, otherwise logged just the item number.

2. **Integration Tests**: Added comprehensive tests for both AddIssue and AddRenewal
   JSON logging functionality:
   - Test normal operations (empty confirmations/forced arrays)
   - Test override operations (populated confirmations/forced arrays)
   - Verify JSON structure and content accuracy

The AddRenewal function now consistently logs:
```json
{
  "issue": 123,
  "itemnumber": 456,
  "confirmations": [...],
  "forced": [...]
}
```

This ensures uniform action log format across all circulation operations and
provides better integration test coverage for the override logging functionality.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit b31f8c566d)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:28 +02:00
Martin Renvoize df6a9ab122
Bug 9762: (follow-up) Fix failing Circulation.t test
The test was failing with RegisterRequired exception because payin_amount()
requires a cash register when UseCashRegisters preference is enabled.

Fixed by setting UseCashRegisters to 0 in the lost item return policies test
to allow payments without requiring a cash register.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 4bcbbd8722)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:27 +02:00
Martin Renvoize 71e462f7ef
Bug 9762: (follow-up) Fix failing CanBookBeIssued test
The test was failing because:
1. IssuingInProcess preference was not explicitly set, affecting the code path for message logging
2. The patron category had a random noissuescharge value that overrode the system preference

Fixed by:
- Setting IssuingInProcess to 0 to ensure correct code path
- Setting patron category noissuescharge to undef to use system preference

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 1660f68690)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:27 +02:00
Hammat Wele 7d038428a5
Bug 9762: (follow-up) Add branchcode to Log circulation and add some override confirmations in action logs, fix typos
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 489780f3f9)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:26 +02:00
Martin Renvoize 4921bb669a
Bug 9762: (Alternative) Handle renewals
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 255c0897f2)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:26 +02:00
Martin Renvoize 3cb8cccf7e
Bug 9762: (Alternative) Log circulation overrides
An alternative approach to the original submission for bug 9762. Instead
of recording a distinct action log line for a set of override messages
in addition to the standard issue record, this patch updates the
existing issue log to include any confirmation or impossible responses
from the preceeding CanBookBeIssued call.

We continue to record these as a JSON structure as the prior patch did,
but instead of human messages we use the predefined codes as returned
from the existing CanBookBeIssued response.

To test:

After each step, a single action log message should be displayed under
`Tools > Log viewer`. The message itself will now consist of a JSON
string with an array of 'confirmations' and 'forced' strings
representing the overriden feedback from CanBookBeIssued.

Circulation -- Checking out

1) Check out an item that is age-restricted (AgeRestrictionOverride syspref)
2) Check out an item that has a “not for loan” status (AllowNotForLoanOverride
   syspref)
3) Check out an item that has a “lost” status (IssueLostItem syspref)
4) Check out an item to a patron who has reached the checkout limit
   (AllowTooManyOverride syspref)
5) Check out an item to a patron who is not allowed to borrow this item type
6) Check out an item to a patron who has unpaid fines (AllFinesNeedOverride
   and/or AllowFineOverride + noissuescharge sysprefs)
7) Check out an item on hold for someone else
8) Check out an item on hold ready for pickup by someone else
9) Check out an item already checked out to someone else
   (AutoReturnCheckedOutItems syspref)
10) Check out to a patron who has restrictions

Circulation -- Checking in

11) Ignore a hold upon check in
12) Ignore a hold and transfer upon check in

Circulation – Renewing

13) Renew an item on hold for someone else
    (AllowRenewalOnHoldOverride syspref)
14) Renew an item that has reached the maximum number of renewals
    (AllowRenewalLimitOverride syspref)

Holds

15) Place a hold for a patron who is not allowed to place this item
    type on hold (AllowHoldPolicyOverride syspref)
16) Place a hold for a patron who has reached the maximum number of
    holds
17) Place an item-level hold when rules dictate that this is not
    allowed

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 5350a9276e)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:25 +02:00
Martin Renvoize ff28b821c1
Bug 9762: (QA follow-up) Remove superflous string construction
We never actually pass `$message` back to anywhere so there's no reason
to create it in the first place.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 86f4eb93aa)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:24 +02:00
Martin Renvoize 0ee5113117
Bug 9762: (QA follow-up) Fix failing test
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit b4e26e9c48)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:24 +02:00
Martin Renvoize de137f2b66
Bug 9762: (QA follow-up) Add missing issueconfirmed check
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit ee74749058)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:23 +02:00
Martin Renvoize ec2fbaf888
Bug 9762: (QA follow-up) Fix executable bit
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit e51399c332)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:23 +02:00
Matthias Le Gac ed145d5a37
Bug 9762: Test CanBookBeIssued.pm
To test:

1) Apply the patch
2) run prove t/db_dependent/Circulation/CanBookBeIssued.t

--After each step, a message will be displayed in the action_logs table and in Tools > Log viewer --

Circulation -- Checking out

1) Check out an item that is age-restricted (AgeRestrictionOverride syspref)
2) Check out an item that has a “not for loan” status (AllowNotForLoanOverride syspref)
3) Check out an item that has a “lost” status (IssueLostItem syspref)
4) Check out an item to a patron who has reached the checkout limit (AllowTooManyOverride syspref)
5) Check out an item to a patron who is not allowed to borrow this item type
6) Check out an item to a patron who has unpaid fines (AllFinesNeedOverride and/or AllowFineOverride + noissuescharge sysprefs)
7) Check out an item on hold for someone else
8) Check out an item on hold ready for pickup by someone else
9) Check out an item already checked out to someone else (AutoReturnCheckedOutItems syspref)
10) Check out to a patron who has restrictions

Circulation -- Checking in

11) Ignore a hold upon check in
12) Ignore a hold and transfer upon check in

Circulation – Renewing

13) Renew an item on hold for someone else (AllowRenewalOnHoldOverride syspref)
14) Renew an item that has reached the maximum number of renewals (AllowRenewalLimitOverride syspref)

Holds

15) Place a hold for a patron who is not allowed to place this item type on hold (AllowHoldPolicyOverride syspref)
16) Place a hold for a patron who has reached the maximum number of holds
17) Place an item-level hold when rules dictate that this is not allowed (In circulation rules put "On shelf holds allowed" to "If any unavailable")

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 3a084d020e)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:22 +02:00
Matthias Le Gac f68278ad20
Bug 9762: Change how to pass the param
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 9183fca07d)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:22 +02:00
emilyrose 832536e991
Bug 9762: Log circulation overrides
This patch allows you to save commands that have been overridden by someone.

The patch has been updated but is not yet completed. Tests 10, 13, 14, and 17 are still not functional. Tests 15 and 16 need to be fixed as they do not display the barcode. All other tests should be functional.

To test:

--After each step, a message will be displayed in the action_logs table and in Tools > Log viewer --

Circulation -- Checking out

1) Check out an item that is age-restricted (AgeRestrictionOverride syspref)
2) Check out an item that has a “not for loan” status (AllowNotForLoanOverride syspref)
3) Check out an item that has a “lost” status (IssueLostItem syspref)
4) Check out an item to a patron who has reached the checkout limit (AllowTooManyOverride syspref)
5) Check out an item to a patron who is not allowed to borrow this item type
6) Check out an item to a patron who has unpaid fines (AllFinesNeedOverride and/or AllowFineOverride + noissuescharge sysprefs)
7) Check out an item on hold for someone else
8) Check out an item on hold ready for pickup by someone else
9) Check out an item already checked out to someone else (AutoReturnCheckedOutItems syspref)
10) Check out to a patron who has restrictions

Circulation -- Checking in

11) Ignore a hold upon check in
12) Ignore a hold and transfer upon check in

Circulation – Renewing

13) Renew an item on hold for someone else (AllowRenewalOnHoldOverride syspref)
14) Renew an item that has reached the maximum number of renewals (AllowRenewalLimitOverride syspref)

Holds

15) Place a hold for a patron who is not allowed to place this item type on hold (AllowHoldPolicyOverride syspref)
16) Place a hold for a patron who has reached the maximum number of holds
17) Place an item-level hold when rules dictate that this is not allowed (In circulation rules put "On shelf holds allowed" to "If any unavailable")

Sponsored-by: Solutions inLibro inc. <https://inlibro.com/>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 89811768b6)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:21 +02:00
Nick Clemens db39dc1607
Bug 40331: (follow-up) Adjust t/db_dependent/Circulation/transfers.t
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit e327039ba1)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:21 +02:00
Nick Clemens 93b5d837cf
Bug 40331: Return existing transfer if requesting a new transfer that is identical
Currently request_transfer checks for the existence of a current transfer on the item, and a new one can either be
enqueued or replace this transfer. This patch adds a check to see if the requested transfer matches an existing transfer
on the item. In the case that it does we simply return that transfer rather than create a new transfer.

This has the effect of eliminating 'WrongTransfer' generation if an item is checked in twice at the same branch, which feels correct.

To test:
 1 - place a hold on an item that is currently at branch A, for pickup at branch B
 2 - check your item in at Branch A, click to confirm the hold and transfer (print slip if you want to)
 3 - sudo koha-mysql kohadev: SELECT * FROM branchtransfers -- See one transfer
 4 - check your item in at Branch A again, get a message that the item is supposed to go to Branch B. Don't click on the modal yet
 5 - repeat 3 -- See two transfers, one cancelled as WrongTransfer, one pending
 6 - Click 'Confirm and transfer' on the modal
 7 - repeat 3 -- See three tranfers - the two from before and a new active transfer
 8 - DELETE FROM branchtransfers
 9 - Apply patch, restart all
10 - repeat 3 - no transfers
11 - Check item in at branch A again and confirm
12 - repeat 3, one transfer
13 - Check item in, don't confirm the modal
14 - repeat 3, one transfer
15 - Confirm the modal
16 - repeat 3, one transfer
17 - Check the item in at branch C
18 - repeat 3, two transfers - one cancelled WrongTransfer, one active
19 - Confirm modal
20 - repeat 3, two transfers
21 - Check item in at branch B
22 - repeat 3, two transfers, one cancelled, one completed

Signed-off-by: Christine Lee <chlee@pascolibraries.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit acdc512cea)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:20 +02:00
Nick Clemens b71d4d3e94
Bug 38906: Use SUBSTRING and LOCATE over REGEXP_REPLACE
To test:
1 - Check out an old version of Koha and set some columns settings for holdings tables, or:
    UPDATE columns_settings
    SET columnname = CONCAT("holdings_",columnname)
    WHERE module = 'catalogue' AND page='detail' AND tablename = "holdings_table";
    UPDATE columns_settings
    SET columnname = CONCAT("otherholdings_",columnname)
    WHERE module = 'catalogue' AND page = 'detail' AND tablename = "otherholdings_table";
2 - perl -e 'use C4::Installer; my $result = C4::Installer::run_db_rev("/kohadevbox/koha/installer/data/mysql/db_revs/240600064.pl"); warn Data::Dumper::Dumper($result)'
3 - SELECT columnname FROM columns_settings WHERE module="catalogue" AND page="detail" AND ( tablename="holdings_table" OR tablename="otherholdings_table");
4 - Confirm column names are correct
5 - repeat 2
6 - Confirm column names are not affected on subsequent runs (items_group does not become group)

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit c1f4e2712b)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:20 +02:00
Lucas Gass 3519f90fdd
Bug 40739: Use correct block/noblock class in item-transfer-modal
To test:
1. Set TransfersBlockCirc to 'Don't block'
2. Check in some items not from your library to initiate a transfer.
3. See the modal pop-op, "Transfer to home library"
4. However, you cannot continue to scan the next item unless you first dismiss the modal.
5. APPLY PATCH
6. Try again, this time at step 4 the barcode input should have focus and you'll be able to scan the next item.

Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit a9d55676a6)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:19 +02:00
Tomas Cohen Arazi 01a59be6ff
Bug 40672: Reset desk_id when reverting waiting holds
This patch adds desk_id reset functionality to the revert_found method,
but only for waiting holds where desk_id is actually relevant.

Changes:
* Modified revert_found() to conditionally reset desk_id
* Only resets desk_id for waiting holds (found=W)
* Leaves desk_id unchanged for in transit (T) and in processing (P) holds
* Added comprehensive test coverage for all scenarios
* Updated POD documentation to explain desk_id behavior

The logic is conservative and only clears desk_id when it makes sense:
waiting holds have their desk assignment cleared since they are no longer
waiting at a specific desk, while transit and processing holds remain
unchanged as they do not use desk_id.

To test:
1. Apply patch
2. Run tests:
   $ ktd --shell
  k$ cd /kohadevbox/koha
  k$ prove t/db_dependent/Koha/Hold.t
=> SUCCESS: All tests pass including new desk_id handling tests
3. Verify all hold test suites still pass:
  k$ prove t/db_dependent/Koha/Hold*.t
=> SUCCESS: All hold-related tests pass
4. Sign off :-D

Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 2da5c04c2d)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:19 +02:00
Thibaud Guillot a3abffea85
Bug 40691: Add ccode label on inventory table
Test plan:

1) Perform an item inventory, be sure to have some items with problems
   :) like 'wrong place'
2) On table if item has 'wrong place' problem (maybe others cases ?) if
   it's linked to collection code just the AV code appears not the label
3) Apply this patch
4) Refresh page, normally that's okay now

Sponsored-by: BibLibre
Signed-off-by: Owen Leonard <oleonard@myacpl.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 25b9895c8d)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:18 +02:00
Owen Leonard 550e8c4848
Bug 40557: Fix layout of enrollment period fields in onboarding
This patch makes updates to CSS and markup in order to fix the layout of
the enrollment period fields during the onboarding process.

To test, apply the patch and rebuild the staff interface CSS.

- Drop and recreate your Koha database.
- Restart all services
- Follow the web installer until you reach the onboarding stage "Create
  a patron category."
- The enrollment period fields should look correct.

Sponsored-by: Athens County Public Libraries
Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit fce45b4279)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:18 +02:00
Owen Leonard d044ba1899
Bug 40497: Item add form does not respect framework maxlength setting
This patch corrects the template variable which populates the maxlenth
attribute on text fields in the add/edit item form.

To test, apply the patch and go Administratoin -> MARC bibliographic
frameworks -> (framework) -> Tag 952 -> Edit subfields.

- Click the "p" tab and set the "Max length" field to "20"
- Save the framework and go to Cataloging.
- Locate a bibliographic record that uses the framework you edited.
- Add or edit an item on that bibliographic record.
- Check the "Barcode" field. The input tag should limit your entry to 20
  characters.

Sponsored-by: Athens County Public Libraries
Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit c7eae54f82)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:17 +02:00
Nick Clemens f6e0424add
Bug 40645: Prevent 'rows' class fieldset from floating
To test:
1 - In the staff client do a search
2 - Select all results
3 - Add to list -> new list
4 - Scroll down, list name field is cut off
5 - Apply patch
6 - Close the list window and add to list again
7 - List name field is now visible

Signed-off-by: Owen Leonard <oleonard@myacpl.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 5cff1c453e)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:17 +02:00
Nick Clemens 6a7bf9a8d5
Bug 39072: Only select exact matches when populating search terms
This patch simply reduces our matching pattern to ensure the string is an exact match, rather than partial

To test:
- Create LOC authorized values of ADULT with description "Adult" and ADULTG with description "Adult - Grab and Go"
- Find a record with items and set one item to shelving location "Adult"
- Find a second record with items and set one item to shelving location "Adult - Grab and Go"
- Create an Item Search for Shelving location and select 'Adult' only
- Search and get one result from the record selected above
- Click Copy shareable link and paste/go in new tab
- See that the results now include both records from above
- Click Edit search button and notice that the Shelving location 'Adult - Grab and Go'  was added to the selected criteria for the search
- Apply patch
- Repeat original search for 'Adult' location
- Click 'Copy shareable link'
- Open in new tab and confirm correct results
- Repeat with a search for 'Adult - Grab and Go' and confirm shareable link gets the correct results

Signed-off-by: Brendan Lawlor <blawlor@clamsnet.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 4d3ebcbe69)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:16 +02:00
Paul Derscheid 11c0675696
Bug 40643: Prevent keypress buildup in circulation
We have reports of progressive slowdown on the circulation page during
long sessions. A likely cause might be a block in `circ/circulation.tt`
that attaches a new keypress handler to `#barcode` on every submit. Some
submits do not navigate (e.g. waiting holds modal, quick slip on empty
barcode), and pages restored from the bfcache keep previously attached
handlers. Over time, listeners accumulate and the UI becomes sluggish.

This patch installs a single, namespaced keypress handler at page load,
guarded by an in-flight flag toggled on submit. The handler shows the
“Barcode submitted” modal and prevents typing only while a submit is
in flight. The flag is reset on bfcache restores via `pageshow`. This
preserves existing UX while keeping the listener count constant.

Test plan:
1. Before applying the patch, open circ/circulation.pl for any patron.
2. In the browser console, run:
   (function () {
     const el = $('#barcode')[0];
     const dataFn = jQuery._data || jQuery.data;
     const ev = (dataFn && dataFn(el, 'events')) || {};
     return (ev.keypress || []).length;
   })()
   Note the keypress handler count.
3. Enter a barcode and submit. Use the browser Back button to return.
4. Re-run the IIFE from step 2. The count has increased.
5. Repeat steps 3–4 a few times and observe the count continues to grow.
6. Apply the patch.
7. Reload the page and re-run step 2; count should be ~1.
8. Enter a barcode and submit. Use Back to return. Re-run step 2.
   The count remains ~1 across submits and back/forward navigations.
9. Confirm UX is preserved:
   - While submit is in flight, pressing keys in `#barcode` shows the
     “Barcode submitted” modal and prevents typing.
   - Waiting holds flow still shows its modal and behaves as before.
   - Submitting with an empty barcode still triggers the quick slip
     behavior per system preference and does not add handlers.
10. Optional: Simulate scanner behavior by pressing Enter rapidly after
    submit. Verify the handler count remains stable.

Signed-off-by: krimsonkharne <philip.orr@posteo.de>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit b3c1261777)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:16 +02:00
Laura_Escamilla f72596c441
Bug 40609: Improve button visibility in Identity providers
To test:
1. Go to Administration > Additional Parameters > Identity providers
2. Click on +New identity provider
3. Notice that the "Add default OAuth configuration" and "Add default
   OAuth mapping" buttons are not too visible. They just look like text
   unless they are hovered on.
4. Apply the patch, restart all
5. Refresh the page and view the buttons again. The button visibility
   has improved.
6. Sign off and have a nice day!

Signed-off-by: Owen Leonard <oleonard@myacpl.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit e20b9c8359)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:15 +02:00
Fridolin Somers b3704edcac
Bug 36155: Improve perfs of suggestion.pl when there are many budgets
Page suggestion/suggestion.pl calls CanUserUseBudget() in a loop,
will must use a uniq Koha::Patron object of the logged in user.
When there are many budgets and funds this takes some time.

Test plan :
Compare performance with and without patch with many budgets and funds
(see test plan of Bug 35921)

Signed-off-by: David Cook <dcook@prosentient.com.au>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 10c8a373fb)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:15 +02:00
David Cook ad886b5869
Bug 40690: Fix if/else/end logic for checkout
This change fixes the Checkout status on moredetail.pl so that it
actually shows "Not checked out" when it's not checked out.

Test plan:
0. Apply the patch
1. Go to /cgi-bin/koha/catalogue/moredetail.pl?biblionumber=29 on a fresh KTD
2. Note that the "Checkout status" is "Not checked out"
3. Check out the item to someone
4. Go to /cgi-bin/koha/catalogue/moredetail.pl?biblionumber=29
5. Note that it says "Checked out to <person> Due back on <date>"
6. Renew the item
7. Go to /cgi-bin/koha/catalogue/moredetail.pl?biblionumber=29
8. Note that it says "Checked out to <person> Last renewed <date>, Due back on <date>"

Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 59d43e8d48)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:14 +02:00
CJ Lynce e7e8ec8073
Bug 36536: Make REST APIs validateUserAndPassword update borrowers.lastseen
This patch added the option to update borrowers.lastseen when a patron username
    and password is verified via the REST API. This can be enabled or disabled
    selectively using the TrackLastPatronActivityTriggers system preference
    using the [ ] Patron authentication via API option..

To test:
1.  Create a new user, ensuring to set the Username and password fields.
	    *Import to do this first*
2.  Edit the TrackLastPatronActivityTriggers syspref and check all options.
3.  Ensure the RESTBasicAuth syspref is set to Enable.
4.  Check the lastseen date of your new user using a SQL report
        SELECT borrowernumber, userid, lastseen FROM borrowers WHERE userid = 'USERNAME'
        (Replace USERNAME with your chosen username for the new patron)
        NOTE: **Ensure the cache expiry of the SQL report is set to 0**
5.  The lastseen for your new user should be null
6.  'restart_all' Koha services to clear plack cache.
7.  Run the attached api_verify_lastseen.pl test script
        **Change P_USERNAME and P_PASSWORD to the username and password of your new user.
        (script contains expected output for successful verification)
8.  Re-check the lastseen date of your new user again via SQL (step 4)
        The lastseen should still be null.

9.  Apply Patch
10. 'restart_all' Koha services

11. Edit the TrackLastPatronActivityTriggers syspref and check the '[ ] Patron authentication via API' option
12. Rerun the api_verify_lastseen.pl
13. Re-check the lastseen date of your new user again via SQL (step 4)
        The lastseen should now be updated to the time of the last script run.

For good measure:
14. Edit the TrackLastPatronActivityTriggers syspref and **UNcheck** the '[ ] Patron authentication via API' option
15. 'restart_all' Koha services to clear plack cache.
16. Rerun the api_verify_lastseen.pl
17. Re-check the lastseen date of your new user again via SQL (step 4)
        The lastseen should have remained the same as previous.

Sponsored-by: Westlake Porter Public Library <https://westlakelibrary.org>
Signed-off-by: Bernard Scaife <bernard.scaife@openfifth.co.uk>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit ba43483f4d)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:14 +02:00
Tomas Cohen Arazi 91db420099
Bug 36536: Unit tests
This patch introduces tests for the feature enabling patron's `lastseen`
attribute be updated when a successful password validation happens
through the API.

To test:
1. Apply this patch
2. Run:
   $ ktd --shell
  k$ prove t/db_dependent/api/v1/password_validation.t
=> FAIL: Tests fail! The feature is not implemented!

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit bab2635f5b)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:13 +02:00
Baptiste Wojtkowski afb9c9c531
Bug 40515: Fix regexp for cud-mark_as_lost_and_notify
Signed-off-by: David Flater <flaterdavid@gmail.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 6cfac72f7e)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:13 +02:00
Lucas Gass c0cb2e6b85
Bug 40678: Add hidden value to remember exemptfine selection
To test:
-Same test plan as with "Book drop mode" but for "Forgive overdue charges"

Signed-off-by: CJ Lynce <cj.lynce@westlakelibrary.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 771815b88d)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:12 +02:00
Lucas Gass 6d4be440f5
Bug 40678: Add hidden value to remember dropboxmode selection
To test:
1. Put an item in transfer to a different library than the logged in branch
2. Go to Circulation > Check in
3. Choose the "Book drop mode" option and check in a few items NOT from step 1.
4. See the "Book drop mode" choice is remembered after every selection.
5. Check in the item from step 1 to make a wrong transfer
6. The modal pops up for wrong transfer, click confirm
7. Now the choice of "Book drop mode" is forgotten.
8. APPLY PATCH
9. Try again, this time the "Book drop mode" selction should be retained

Signed-off-by: CJ Lynce <cj.lynce@westlakelibrary.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 13b82826cb)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:12 +02:00
Pedro Amorim 7be62e1dc7
Bug 40653: Add cookie to output_html
Test plan, k-t-d, don't apply patch yet:
1) Install a plugin that sends the cookie to output_html e.g.:
https://github.com/openfifth/koha-ill-libkey-lending-tool/releases/tag/v2.3.8
2) Log out. Access this plugin's tool link directly:
<staff_url>/cgi-bin/koha/plugins/run.pl?class=Koha%3A%3APlugin%3A%3ACom%3A%3APTFSEurope%3A%3AIncDocs&method=tool
3) Notice you're presented the login screen. Login using koha:koha
4) Notice you're shown the plugin's respective tool page. It looks like you're authenticated but you're not. Click on any of the top links e.g. 'Circulation' or 'Patrons'.
5) Notice you're shown the login page again.
6) Apply patch. Repeat. Step 5 should no longer show the login page but instead the page you clicked on.

Signed-off-by: Tomas Jiglind <tomas.jiglind@mariestad.se>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit f16187e605)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:11 +02:00
Lucas Gass 58fb7cd002
Bug 40709: Use data-colname for adding filters
To test:
1. Set the 'item-level_itypes' system preference to 'Bibliographic record'
2. Go to any record that contains items and look at the holdings table.
3. Click 'Show filters'.
4. Notice that the Status column doesn't appear to have a filter.
5. APPLY PATCH
6. Try again, the Status filter should appear correctly. Make sure all other filters appear correct.
7. Set 'item-level_itypes' back to 'specific item'.
8. Make sure the filter still appears correctly. Make sure all other filters appear correct.

Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit d5adba9101)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:11 +02:00
Caroline Cyr La Rose 8e6e70cd35
Bug 40071: MARC21 Addition to relator terms in technical notice 2025-06-04
This patch adds a relator term that was added to the MARC code list for
relators in the June 4, 2025 technical notice. The new term is waw -
Writer of afterword.

To test:
1. Apply patch and reset_all
2. Go to Administration > Authorized values
3. Search for the RELTERMS list and click on it
4. Search for waw
   --> There should be an entry for waw - Writer of afterword

Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 17acb0c157)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:10 +02:00
Caroline Cyr La Rose 4e0697968c
Bug 40072: MARC21 Addition to relator terms in technical notice 2025-04-03
This patch adds a relator term that was added to the MARC code list for
relators in the April 3, 2025 technical notice. The new term is wfw -
Writer of foreword. This technical notice also deprecates an existing
term, aui (author of introduction), in favour of the new term.

To test:
1. Apply patch and reset_all
2. Go to Administration > Authorized values
3. Search for the RELTERMS list and click on it
4. Search for wfw
   --> There should be an entry for wfw - Writer of foreword
5. Search for aui
   --> Term should not exist

Note : This update includes a term deprecation. I decided to go ahead
and remove it from the authorized values list because, unlike for MARC
frameworks, a nonexistent value will not delete data from the records.
It will simply say "aui (Not an authorized value)". Furthermore, this
only affects new installations. Nothing will be deleted from existing
installations, unless the libraries themselves remove the authorized
value. They can make a batch modification before deleting it if
necessary.

Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 38a5b8190d)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:10 +02:00
Caroline Cyr La Rose 4eaea617ce
Bug 40073: MARC21 Addition to relator terms in technical notice 2025-02-06
This patch adds new relator terms that were added to the MARC code list
for relators in the Februrary 2, 2025 technical notice. The new terms
are ink - Inker, and pnc - Penciller.

To test:
1. Apply patch and reset_all
2. Go to Administration > Authorized values
3. Search for the RELTERMS list and click on it
4. Search for ink
   --> There should be an entry for ink - Inker
5. Search for pnc
   --> There should be an entry for pnc - Penciller

Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit add898d8a9)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
2025-09-20 10:43:09 +02:00