Commit Graph

60669 Commits

Author SHA1 Message Date
Jacob O'Mara 5cff6cee62
Increment version for 25.11.05 release
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-06-08 16:16:09 +01:00
Jacob O'Mara abc625b727
Revert "Bug 27826: (RMaint follow-up) Attempt to fix SCO_spec tests"
This reverts commit 8a0e970650.

Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-06-08 16:16:09 +01:00
David Cook d3260658f7
Bug 42361: Fix SQL injection in catalogue_out.pl
This change removes an SQL injection vulnerability from catalogue_out.pl

Test plan:
0. Apply the patch
1. Go to koha-conf.xml and change the following:
<strict_sql_modes>1</strict_sql_modes>
to:
<strict_sql_modes>0</strict_sql_modes>
2. sudo koha-plack --restart kohadev
3. Go to /cgi-bin/koha/reports/catalogue_out.pl
4. Try out the various options and note no errors occur

Signed-off-by: Sanjar Tulkinov Anvar o'g'li <sanjarbiy11@gmail.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-06-08 16:16:09 +01:00
Jacob O'Mara 8a0e970650
Bug 27826: (RMaint follow-up) Attempt to fix SCO_spec tests
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-26 18:11:09 +01:00
Jacob O'Mara c3b487d46a
Bug 42163: (RMaint follow-up) Tidy wrapper-staff-tool-plugin.inc
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 18:00:44 +01:00
Jacob O'Mara e105a9d469
Bug 27826: (RMaint follow-up) revert test fix from main
This seems to not be necessary for 25.11.x. Inputting correctly on this
branch

Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 18:00:44 +01:00
Jacob O'Mara 346f697708
Rmaint: DBIC
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 18:00:44 +01:00
Roman Dolny 2d416b8992
Bug 41940: Remove uninitialized value warnings in circulation.pl
The warnings:

[WARN] Use of uninitialized value $patron_session_confirmation in split
   at /kohadevbox/koha/circ/circulation.pl line 493.
[WARN] Use of uninitialized value $patron_for_session in numeric eq (==)
   at /kohadevbox/koha/circ/circulation.pl line 494.
[WARN] Use of uninitialized value $session_confirmations in split
   at /kohadevbox/koha/circ/circulation.pl line 495.

appears in the plack-intranet-error.log.

Test plan:
==========
1. Use a fresh KTD, observe plack-intranet-error.log.
2. Have a barcode of existing item.
3. Find any patron and go to "Check out" tab.
4. Check out item.
==> Warnings should appear in plack-intranet-error.log
5. Apply the patch; restart_all.
6. Repeat 2-4 with another barcode.
==> No warnings in plack-intranet-error.log.

Sponsored-by: Ignatianum University in Cracow
Signed-off-by: David Nind <david@davidnind.com>

Bug 41940: (follow-up) Syntax corrections

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 171f727734)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Owen Leonard eb7d288a66
Bug 42638: Cannot delete an identity provider domain
This patch updates the identity provider domain page so that clicking
the "Delete" button from the list of existing identity providers works
correctly.

There's a lot of unfinished copy and paste from the SMTP servers page,
including a missing chuck of modal dialog HTML.

To test, apply the patch and go to Administration -> Identity providers.

- If necessary, add at least one identity provider.
- Click the "Manage domains" button for an identity provider.
- If necessary, add at least one identity provider domain.
- Click the delete button corresponding to the domain you added.
  - A confirmation modal should appear.
  - Clicking "Close" should close the modal without triggering any
    action.
  - Clicking "Delete" should delete the domain.

Sponsored-by: Athens County Public Libraries
Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 6572a5aec0)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Jonathan Druart c57a3117e5
Bug 42467: Init mmtas to an empty array
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit c1a369d274)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Owen Leonard 0e9b3edb0c
Bug 42467: Remove event attributes from MARC modification templates template
This patch removes several "onChange" event attributes from
marc_modification_templates.tt and moves the event handlers into
marc_modification_templates.js.

The patch also corrects a view minor zxlinting errors in the JS file.

To test, apply the patch and clear your browser cache if necessary.

- Go to Cataloging -> MARC modification templates.
- Create a new template if necessary.
- Click "New action."
- Test the behavior of dropdowns and checkboxes in the new action form.
  - Fields should be correctly shown or hidden based on the selected
    actions
  - Fields should be correctly shown or hidden based on the "RegEx"
    checkbox.
  - Text the conditional dropdown along with the "matches" dropdown.
    - Test that the "matches" regex fields are correctly displayed
      according to the checkbox.
- The browser developer console should show no "Content-Security-Policy"
  errors.

Sponsored-by: Athens County Public Libraries
Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 561e8180ce)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Owen Leonard 281f826ee7
Bug 42448: Staff Interface News (newsfooter) text does not have sufficient color contrast
This patch updates the CSS which controls the display of the news item
footer ("Posted by" and edit/new links) in order to improve
accessibility.

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

- If necessary, create at least one news item with the display location
  "Staff interface."
- On the staff interface home page, look at the news items in the
  left-hand sidebar. The "Posted by" line should be clear. A check of
  the text's contrast should show that the contrast is appropriate.

Sponsored-by: Athens County Public Libraries
Signed-off-by: Lawrence O'Regan-Lloyd <loreganlloyd@clamsnet.org>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 754659d9d0)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Owen Leonard d594231ac9
Bug 42445: Remove event attributes from list creation template
This patch removes a couple of "onChange" event attributes from the
lists template in favor of defining the event handler in the footer JS.

To test, apply the patch and go to Lists -> New list.

- Choose "Private" from the public dropdown.
- In the "Allow changes to contents from" dropdown select "Permitted
  staff only"
  - A note should appear about the setting having no effect.
- You should see a similar note displayed when you select "Staff only"
  or "Anyone seeing this list"

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

Amended-by: Jonathan Druart
Tidy

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 1275a24115)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Owen Leonard 415e170a66
Bug 42442: Remove event attributes from bibliographic record merge template
This patch moves a couple of "onclick" event attributes from the
bibliographic record merge template, moving the event handling to the JS
block.

This patch also makes a minor change to make sure that the
framework code dropdown preselects the framework of the first of
the records to merge. This brings it in line with the authority
merge template.

To test, apply the patch and perform a catalog search which will return
multiple results including results with different frameworks. In the
standard test data a search for "green" will return two results with two
different frameworks.

- Check the checkbox for at least two records in your search results.
- Click "Edit -> Merge records" in the toolbar at the top of the
  results.
- On the "Merging records" page you should see a frameowrk dropdown. It
  should have preselected the framework corresponding to the first of
  the records you selected.
- When you click the radio buttons next to your records to merge the
  framework selection should change to match your selection..

Sponsored-by: Athens County Public Libraries
Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 01a1696058)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
David Cook 2a15ee39b6
Bug 42317: Update minimum version for MARC::File::XML
This patch updates cpanfile to reflect the real minimum version
needed for MARC::File::XML. This is particularly important
due to vulnerabilities in version 1.0.1

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

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: mason james <mtj@kohaaloha.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 00655de4d0)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Lucas Gass 743dc1c253
Bug 42545: (RM follow-up) Tidy test file
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 1ed156ef40)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Martin Renvoize ac35cf5a59
Bug 42545: (QA follow-up) Add unit tests for holiday subtraction when return time is before due time
Adds a dedicated subtest covering the specific scenario: daily loans have a
due time of 23:59, so a return earlier in the day on a holiday would
previously cause days_between to exit its loop before processing the end
date, silently skipping the holiday subtraction.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 0a0dcee152)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Martin Renvoize ca022fa960
Bug 42545: (QA follow-up) Add POD for _init and _holidays and fix incorrect test expectation
The existing 'days: 289 hours, 2 holidays' test asserted 8-1=7 but its own
description named 2 holidays. The expected value matched the buggy behaviour
(loop exiting before the holiday end date) rather than the correct result.
Update to 8-2=6 to reflect the fix.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 6ca7c1118b)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
apirak 05ab096150
Bug 42545: Koha::Calendar::days_between skips holiday subtraction for end date if time is early
In Koha::Calendar::days_between, the holiday-subtraction loop uses a comparison
that includes time. If the end_dt is a holiday and its time is earlier than
the start_dt time (common in renewals), the loop terminates before processing
the end_dt, leading to an extra fine day.

This patch truncates both dates to the beginning of the day after cloning
and setting the time zone, ensuring the loop correctly processes all
calendar days between the two dates.

Test Plan:
1. Set 'finesCalendar' syspref to 'noFinesWhenClosed'.
2. Set 'CalculateFinesOnReturn' syspref to 'Yes'.
3. Set 'finesMode' syspref to 'Production'.
4. Define a special holiday for today in the library calendar.
5. Identify an overdue item for a patron. Manually set its 'date_due' in the
   database to several days ago with a time of 23:59:00.
6. Renew the item today at any time BEFORE 23:59:00 (e.g., 10:00 AM).
7. Observe that an extra day of fine is charged because today (the holiday)
   was not subtracted.
8. Apply this patch.
9. Repeat the test and observe that the holiday is now correctly subtracted.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 9c38d74c98)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Jan Kissig 4d90375f65
Bug 42412: Fix Incorrect date error in db-revs when using MySQL
In Bug 36466 db_revs/251200019.pl was introduced to update wrong date values (0000-00-00) with NULL.
This can fail on MySQL as it is running with sql_mode NO_ZERO_DATE activated which does not allow to select or update date fields with values='0000-00-00'.

This patch changes the update queries in db_revs/251200019.pl to use Installer::sanitize_zero_date on both columns.

Test plan:
As the test shall be done using MysQL and Mariadb start 2 ktds:
MySQL) DB_IMAGE=mysql:8.0 ktd --proxy --name mysql8 up -d
MariaDB) ktd --proxy --name maria up -d

a) checkout a version prior 36466: git checkout v24.11.14-1
b) reset_all
c) Connect to staff interface (mysql8-intra.localhost and maria-intra.localhost)
d) Go to Serials and create a new subscription
e) run the following to enter database client in each ktd shell: koha-mysql kohadev
f-mysql) run the following commands to be allowed to change planneddate and publisheddate to '0000-00-00':
 SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
 update serial set planneddate = '0000-00-00', publisheddate = '0000-00-00';
f-maria)
 update serial set planneddate = '0000-00-00', publisheddate = '0000-00-00';
g) verify via: select * from serial;
h) checkout main via: git checkout main
i-mysql) run  updatedatabase
 Upgrade to 25.12.00.019  [09:35:55]: Bug 36466 - Fix the incorrect 0000-00-00 date in planneddate and publisheddate field
        ERROR: {UNKNOWN}: DBI Exception: DBD::mysql::db do Incorrect date error in db-revs when using MySQL

        In 36466 db_revs/251200019.pl
        for column 'planneddate' at row 1 at /kohadevbox/koha/C4/Installer.pm line 818
i-maria) do not run updatedatabase yet
j) apply patch
k-mysql) run  updatedatabase
Upgrade to 25.12.00.019  [09:37:02]: Bug 36466 - Fix the incorrect 0000-00-00 date in planneddate and publisheddate field
        Incorrect date planneddate and publisheddate fixed
...
-> is successful now
k-maria) run updatedatabase
l) verify via: select * from serial;

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit cf984da25a)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Lucas Gass ebce7f999d
Bug 42262: encodeURIComponent for the 006 value
To test:
1- have a MARC record with Type of Material "BKS - Books" that does not have an 006 defined (biblio 1 in the KTD default data will work)
2- edit the biblio in the basic editor
3- open the tag editor for the 006
4- observe that the values along the top of the tag editor window show a value of "" (blank) in position 17
5- click Save in the tag editor window
6- confirm that the values in the 006 tag end with a space
7- open the 006 tag editor again
8- observe that the values along the top of the tag editor window no longer show any value for position 17. Instead, they end with the zero in position 16
9- click Save in the tag editor window
10- confirm that the values in the 006 tag now end with a zero, not followed by a space
11- save your biblio
12- edit the biblio in the basic editor again, get warning "The following fixed-length control field(s) have an invalid length: 006. Please fix."
13- APPLY PATCH and restart_all
14. Try editing the 006 value again, the whitespace should be preserved and you get no error.

Signed-off-by: Justin Swink <Justin.Swink@littleelm.gov>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 1a0501f5e8)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Laura_Escamilla 829fb941f3
Bug 42236: Add accessible label to OPAC user lists actions column
To recreate:
1. Log in to the OPAC
2. Create at least 1 list
3. Go to the "Your lists" page (opac-userlists)
4. Inspect the table header for the Edit/Delete column
5. Confirm the header contains no text

Test the patch:
1. Apply the patch
2. Repeat steps 1-3
3. Inspect the table header for the Edit/Delete column
4. Confirm the header now contains accessible text
5. Confirm Edit and Delete actions still function as expected
6. Run an accessibility checker and confirm the issue is resolved
7. Sign off and have a wonderful day! :D

Signed-off-by: John Vinke <jvinke@austinseminary.edu>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 88676495e0)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Kyle M Hall dcba4f470c
Bug 42547: Fix SIP performance if sip2_resource_last_modified not set in cache
In Koha, the sip2_resource_last_modified key is updated any time the SIP config is edited from the SIP2 editor in the staff interface ( institutions, accounts, system preference overrides ).

If sip2_resource_last_modified is missing from memcached, Koha SIP emits "Couldn't find sip2_resource_last_modified, considering configuration not up to date" in the logs, and fetches the entire configuration from the database, *for each request*.

This causes SIP performance to drop significantly. In my production testing with 83 institutions and 171 accounts the login message response time dropped from 0.283 seconds to 2.899 seconds.

I think the solution is pretty simple. If there is a cache miss on sip2_resource_last_modified, SIP should load the config from database as it does already, but then it should also set sip2_resource_last_modified!

Test Plan:
1) Apply this patch
2) Prove t/db_dependent/Koha/SIP2/SIP2ModuleMigration.t

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 7dc223b30a)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Kevin Carnes 4ad623a936
Bug 42176: Can cancel add authorized value
The cancel add authorized value button has no type, so it will submit the form.
This patch makes it a button so it does not submit the form.

Test plan:
1.  Ensure that the CreateAVFromCataloguing preference is enabled.
2.  Edit an item.
3.  Enter an authorized value that does not exist (e.g. shelving location).
4.  Select it to be able to create it.
5.  Click the Cancel button to not create a new authorized value.
6.  Observe that the form was sent or that a new authorized value was created.
7.  Delete the new authorized value.
8.  Apply the patch.
9.  Repeat steps 2-5.
10. Observe that the form was not sent or that a new authorized value was not
    created.
11. Sign off.

Sponsored-by: Lund University Library
Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit c7ee854d9f)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:53 +01:00
Jonathan Druart 1aed4fb193
Bug 42581: Exclude plugins' routes from xt/api.t
If some plugins are installed and inject REST API routes, xt/api.t may fail.

Test plan:
You can install the Jump plugin (https://gitlab.com/joubu/koha-plugin-jump) and run xt/api.t
It will fail:
```
get /contrib/jump/parse -> uses tag 'parse' not present in top level list
get /contrib/jump/search -> uses tag 'search' not present in top level list
get /contrib/jump/search -> uses tag 'objects' not present in top level list
get /contrib/jump/static/static_files/commandPalette.js -> uses tag 'Jump' not present in top level list
get /contrib/jump/static/static_files/jump.css -> uses tag 'Jump' not present in top level list
[...]
```

Apply this patch and run `prove xt/api.t` again
=> It should pass

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit e109e09ae4)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:52 +01:00
Jonathan Druart 2eee1b9e9d
Bug 42578: Prevent Koha/Hold.t to fail on date comparison
We must use t::lib::Dates::compare to compare dates in test.

Test plan:
Confirm that `prove t/db_dependent/Koha/Hold.t` still returns green
after this patch

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 4da822b6a1)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:52 +01:00
Jonathan Druart 8c66f2175d
Bug 42521: (bug 39055 follow-up) Fix login from suggestion.pl
If you try to login from suggestion/suggestion.pl you get a 500

DBIx::Class::Storage::DBI::_dbh_execute(): DBI Exception:
DBD::mysql::st execute failed: Unknown column 'login_op' in 'WHERE' at
/kohadevbox/koha/Koha/Objects.pm line 401

Test plan:
Logout
hit /cgi-bin/koha/suggestion/suggestion.pl
login
=> Without this patch you get a 500
=> With this patch applied you get the suggestion list view

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 26abf4c73d)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:50 +01:00
Eric Phetteplace 7d2782203e
Bug 42244: Fix JS TypeError on patrons ILL table
The multipleSelect plugin is used on the ILL requests table but is not
present when viewing a patron's ILL request history. This patch avoids a
JS TypeError by checking if the plugin exists before calling it.

To test:
- Enable ILLModule setting
- ILL Requests > New ILL Request
- Metadata doesn't matter but attach to a patron account, e.g. use the
"Acevedo" surname on KTD
- Go to the Patron > ILL requests history
- View browser's JS console, note TypeError
- Apply patch
- Refresh page, TypeError goes away

Signed-off-by: Chris Mathevet <chris.mathevet@inLibro.com>

Amended-by: Jonathan Druart
Tidy

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit f7071e91fe)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:50 +01:00
elias 055f2d9503
Bug 41373: Fix Mana report sharing when only one language is enabled
Test plan :
- Disable all but one language in system preference
  StaffInterfaceLanguages
- Start a local instance of Mana
  - Clone the mana repo on your machine (from
    https://gitlab.com/koha-community/koha-mana)
  - Edit compose/base.yml and uncomment the line:
    ${PWD}/sql/mana-sample.sql:/docker-entrypoint-initdb.d/test-data.sql
  - Run `bin/mana --skip-email-validation up -- -d` to launch mana and
    create a docker network koha will connect to
- Run `ktd --mana up -d` to connect koha to mana
- In Koha staff interface, go to "Administration » Share content with
  Mana KB":
  - Set "Share content with Mana KB" to "Yes", click "Save"
  - Fill the form under "Configure Mana KB", click "Send to Mana KB"
- Try to share a report to mana. Go to Mana UI to verify that the report
  was correctly shared

Signed-off-by: Julian Maurice <julian.maurice@biblibre.com>
Signed-off-by: Emmanuel Bétemps <e.betemps@gmail.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 850f1f224f)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:50 +01:00
Jan Kissig 3e3c57afb8
Bug 42398: Reimplement form validation to news
This patch reimplements form validation on news (additional contents). The form.validate() call which adds a submitHandler is moved outside the document ready block in order to work again.
Markup like class=required is added to meet JS10 guidelines. JS alerts (when default title or default content was empty) were replaced by setting focus the required field.

Test plan:

a) go to /cgi-bin/koha/tools/additional-contents.pl?category=news (Tools -> News)
b) click either 'New entry' or 'New entry using text editor'
c) enter a required publication date
d) save the form. You will not be required to enter a default title or content.
e) apply patch followed by a restart_all
f) go to /cgi-bin/koha/tools/additional-contents.pl?category=news (Tools -> News)
g) click either 'New entry' or 'New entry using text editor'
h) check that title and content in the 'Default' tab are marked as required
i) try to send form f.e. when only title and content in 'English' tab are set
j) check if default title or content is missing the default tab is shown and the field gets focused

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit f4678e5b23)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:50 +01:00
Andrew Fuerste Henry cce8bf77f6
Bug 42570: Use count_holds for OPAC patron summary pending holds
To test:
1 - enable DisplayAddHoldGroups
2 - place two ungrouped holds for a patron
3 - log into the opac as your patron, see 2 pending holds
3 - group the two holds
4 - reload OPAC, still see 2 pending holds
5 - Apply patch, restart_all
6 - reload OPAc, see 1 pending holds
7 - ungroup holds
8 - reload OPAC, see 2 pending holds

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 186ec335db)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:50 +01:00
Pedro Amorim 5ca8f35a10
Bug 42255: Add tests
prove t/db_dependent/Reserves.t

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit e931157dc7)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:50 +01:00
Pedro Amorim 53b6f704ad
Bug 42255: Maximum total holds allowed (count)
Make 'Maximum total holds allowed (count)' (aka max_holds) consider hold groups

Test plan:
Same as the previous test plan, but set 'Maximum total holds allowed (count)' as 2 and instead set 'Holds allowed (total)' as unlimited.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit e56c9cc9bb)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:50 +01:00
Pedro Amorim 108f7d56d2
Bug 42255: Holds allowed (total)
Make 'Holds allowed (total)' (aka reservesallowed) consider each hold group as an individual hold

Test plan:
1) Enable DisplayAddHoldGroups sys pref
2) Set Holds allowed (total) to 2, visit:
http://localhost:8081/cgi-bin/koha/admin/smart-rules.pl
3) Scroll to the right, click the 'Edit' button under 'Actions' column.
4) On the 'Holds allowed (total)' column cell, enter '2' and click 'Save' under the 'Actions' column to the right.
5) Search  for 'test':
http://localhost:8081/cgi-bin/koha/catalogue/search.pl?q=test
6) Tick the checkbox next the first and second results, click 'Place hold' button at the top toolbar
7) Search for 'koha' user and pick Koha (42)
8) Set a pickup location for each hold and tick the 'Treat as hold group' checkbox. Click 'Place holds'.
9) Try to place another single hold for the same patron. Should succeed, because the 2 grouped holds count as 1. Patron now should have 1 group + 1 ungrouped hold = effective count of 2.
10) Try to place yet another hold, should be blocked with a tooManyHolds error.
11) Prior to this patch, step 9 would've failed because the 2 grouped holds counted as 2.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit d5f130da5a)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:50 +01:00
wainuiwitikapark acab81737a
Bug 38009: Add a generate next button in serials receive page
Adds a generate next button to the serials receive page (serials-edit.pl) that works similar to the button on the serials collection page.

To test:

1. Go to Staff Client > Serials
2. Find an existing subscription or create a new one
3. Go to the Serials collection page for your serial e.g. /cgi-bin/koha/serials/serials-collection.pl?subscriptionid=1
4. Click on the "Generate next" button and notice that the table adds
   another row
5. Click on the "Receive" button at the top of the page
6. Notice that the page also shows the issues like the rows in the
   previous page
7. Apply patch
8. Repeat steps 1-5
9. Notice that the page also has a "Generate next" button at the top
10. Check that the button generates a new issue row on the page

Sponsored-by: Pymble Ladies' College
Signed-off-by: esther <esther@bywatersolutions.com>
Signed-off-by: Brendan Gallagher <brendan@bywatersolutions.com>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 7b1a348ac9)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:50 +01:00
Owen Leonard 8362e6b7c5
Bug 42439: Remove event attributes from label-edit-batch.tt
This patch removes an "onload" event attribute from the label batch edit
template. An "onload" event attribute on the body tag can be easily
moved to the $(document).ready block.

To test, apply the patch and go to Cataloging -> Label creator -> Label
batches -> New label batch. As soon as the page loads the "Add by
barcodes" textarea should get focus.

Sponsored-by: Athens County Public Libraries
Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit b8832e7d7e)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:49 +01:00
Owen Leonard f3482ddb93
Bug 42438: Remove event attributes from icon selection include file
This patch removes an "onmousedown" event attribute from the include
file used by item types and authorized values administration in icon
selection. The event handling is copied to each page's JS block.

To test, apply the patch and go to Administraion -> Item types.

In the "Choose an icon" section, click the "Remote image" tab. Click
the text input field. The corresponding radio button should be
checked.

Perform the same check on Administration -> Authorized values.

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 3160983a6d)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:49 +01:00
Nick Clemens 3ca9f8d2c4
Bug 42424: Javascript error prevents saving when an instance of an 'important' or 'required' subfield is deleted
In the loop to check fields, we enter a conditional when the element is null - but then we try to adjust the element.
This patch removes the condition and prevents accessing NULL fields

To test:
 1 - Go to Administration->MARC Bibliographic framework
 2 - Under Default click Action->MARC Structure
 3 - Search for 020
 4 - Click Actions->Edit subfields
 5 - Click on tab 'a'
 6 - Check important, save
 7 - Cataloging->New from Z39
 8 - Search for ISBN: 9798225048921 (or any record you want)
 9 - Ensure the result has more than one ISBN and click Actions->Import
10 - Delete one of the ISBN fields
11 - Click 'Save'
12 - Check the console (F12)
     Uncaught TypeError: Cannot read properties of null (reading 'nodeName')
13 - Apply patch
14 - Repeat 8-10
15 - Click save (and clear any other fields that need edited)
16 - Confirm record can be saved

Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit c85f9a02a9)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:49 +01:00
Jonathan Druart ff20b92727
Bug 41769: Translate "%s, by %s"
Instead of translating ", by" we add more flexibility for languages that
need to invert author and title for instance.

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit f1c3c2d89a)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:49 +01:00
Ayoub Glizi-Vicioso ef28b9dedd
Bug 41769: Make ', by' string translatable in suggestions
This fixes a translation issue in the purchase suggestions
table in the staff interface - a ", by" is added between the
title and the author in the suggestion column, the "by" is
not translated when the language for the staff interface
is a language other than English.

Test plan:

1. Add another language to Koha:
   ./misc/translator/translate install fr-CA

2. Enable the new language in StaffInterfaceLanguages:
   2.1. Go to Administration > System preferences
   2.2. Search for StaffInterfaceLanguages
   2.3. Check the new language
   2.4. Click Save all I18N/L10N preferences

3. Create a new purchase suggestion:
   3.1. Go to More > Suggestions
   3.2. Click New purchase suggestion
   3.3. Fill out the title AND the author at least
   3.4. Click Submit your suggestion

4. View the suggestion in the table
   --> It says title, by author

5. Switch language
   --> The ", by" is still in English

6. Apply patch.

7. Run these commands to update the translation:
   7.1 ./misc/translator/translate update fr-CA
   7.2 ./misc/translator/translate install fr-CA

8. Reload page.

9. Notice that ", by" is now translated.
   --> in this instance, you will see ", par"

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 97b4b2f1db)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:49 +01:00
Jacob O'Mara 9d60ad2a37
DBRev 25.11.04.012
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:49 +01:00
Emily Lamancusa 76345c7eba
Bug 39107: (QA follow-up) Use existing foreign_key_exists function
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 4a57c1f779)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:49 +01:00
Saiful Amin 205a9c27d5
Bug 39107: Remove illrequests_safk FK constraint on illrequests.status_alias as required by MySQL 8.4+
MySQL 8.4 requires foreign keys to reference PRIMARY KEY or UNIQUE keys.
Since authorised_values.authorised_value is only unique in combination
with category (composite UNIQUE key av_uniq), the FK constraint is not
compatible with MySQL 8.4+.

Data integrity for illrequests.status_alias is maintained at the application layer:
- Koha::ILL::Request->status_alias() validates values against
  authorised_values (category='ILL_STATUS_ALIAS') before storing
- All ILL request operations in Koha use this object layer
- CASCADE behaviors (ON DELETE SET NULL, ON UPDATE CASCADE) are already
  handled by the application layer when modifying/deleting authorised values.

Test Plan, using KTD:
1. Prepare KTD for MySQL 8.4
    - In koha-testing-docker, edit 'compose/db-mysql.yml'
    - Comment out the line 5:
    `# command: --default-authentication-plugin=mysql_native_password`

    Note: This is required because MySQL 8.4 doesn't support the native password plugin.

2. Start a new instance with MySQL 8.4
    - `DB_IMAGE=mysql:8.4 ktd up`
    - Observe that it fails to start with the errors such as 'DBD::mysql::st execute failed'

3. Apply the patch
    - `git bz apply 39107`

4. Start the instance again
    - `DB_IMAGE=mysql:8.4 ktd up`
    - Observe that it starts successfully

5. Update the database (Optional, only for existing instances)
    - `perl installer/data/mysql/updatedatabase.pl`

6. Access Koha Staff and OPAC interfaces and verify that everything works as expected

7. Sign off

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit fe24b5030e)
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:44 +01:00
Lucas Gass b58cf6df96
Bug 29016 [25.11.x]: (RM follow-up) Add action_logs tag to swagger def
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:44 +01:00
Martin Renvoize 99ffc00e62
Bug 29016 [25.11.x]: (QA follow-up) Document the action_logs list controller
Replace the empty =head3 stub with a proper synopsis explaining the URL,
the supported filtering / ordering / embed surface, and the permission
requirement. Aligns the controller with the documentation density of
other Koha REST controllers and removes the "Missing POD" QA noise.

Test plan:
  1. perl -MKoha::REST::V1::ActionLogs -e ''  (still loads)
  2. perl -c Koha/REST/V1/ActionLogs.pm        (still parses)
  3. perldoc Koha/REST/V1/ActionLogs.pm        (renders the new POD)

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:44 +01:00
Martin Renvoize 3089c74f6f
Bug 29016 [25.11.x]: (QA follow-up) Restore biblio<->item log expansion
The catalog detail page links to the modification log with
modules=CATALOGUING&object_type=biblio&object=<biblionumber>. The old
server-rendered viewer matched both biblio-level entries (object =
biblionumber, info LIKE 'biblio%') and item-level entries (object IN
(itemnumbers of this biblio), info LIKE 'item%'). Converting to the
AJAX DataTable kept that expansion only in the CSV export branch, so
the on-screen view silently dropped item-level history.

Recreate the expansion in the AJAX path:

  * tools/viewlog.pl: when (single CATALOGUING module + object_type
    =biblio + non-empty object) collect the biblio's itemnumbers and
    expose them, along with object_type, to the template.
  * viewlog.tt: include object_type and biblio_itemnumbers in the
    search_params JSON the inline script builds for the JS.
  * viewlog.js: when those params are present, build the same -or
    clause the old SQL produced and skip the regular per-object filter.
    The info substring filter is also suppressed in that branch (the
    old code did the same: it dropped %info% in favour of the -or).

Test plan:
  1. Enable CataloguingLog.
  2. Edit the biblio and a couple of its items.
  3. From the biblio detail page, open "Modification log".
  4. Verify the table shows both the biblio MODIFY rows and the item
     MODIFY rows for that biblio (and only those).
  5. From Tools -> Log viewer, plain Cataloguing filter still returns
     the unfiltered log set as before.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:44 +01:00
Martin Renvoize 2b165d347e
Bug 29016 [25.11.x]: (QA follow-up) Translate circulation overrides in info column
CIRCULATION rows whose info payload is a JSON object can carry `forced`
and `confirmations` arrays listing the override codes a librarian
acknowledged when checking out, renewing or otherwise circulating an
item (e.g. DEBT, AGE_RESTRICTION, BIBLIO_ALREADY_ISSUED). The old
server-rendered template ran these through the translate_log_override
SWITCH block in action-logs.inc; in the new AJAX-driven viewer the JS
default branch was just escapeHtml()-ing the raw JSON, leaving the
codes unlocalised and unreadable.

Port the override -> human-readable label map into str/viewlog.inc as
override_labels, mirroring the module/action/interface label maps
already there. Add a renderCircInfo() helper that recognises the JSON
shape and emits the same div.forced / div.confirmed blocks the old
template did, so the existing CSS continues to apply.

renderInfo() now falls through CIRCULATION -> renderCircInfo, the
generic record-info renderer (CATALOGUING / AUTHORITIES from bug 42032)
and finally escapeHtml(), so non-JSON payloads (item barcodes,
ID-only info, ...) keep displaying as before.

Test plan:
  1. Enable IssueLog.
  2. Trigger an override checkout (e.g. patron with debt, item not for
     loan) and confirm.
  3. Tools -> Log viewer, filter by module=Circulation.
  4. The override row's Info column should show one or more localised
     "Patron had debt", "Item was not for loan", ... lines instead of
     a raw JSON blob.
  5. Plain ISSUE / RETURN rows (no overrides) keep showing the raw
     itemnumber / barcode payload as before.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:44 +01:00
Martin Renvoize 78a9da8e33
Bug 29016 [25.11.x]: (QA follow-up) Render embedded patron, fix JS i18n drift
QA review pointed out three regressions and a label gap in the new
DataTable-driven log viewer:

  1. The Librarian column showed a bare borrowernumber linked to the
     patron page; the old server-side template showed the librarian's
     full name with the borrowernumber in parentheses.

  2. The Object column for MEMBERS / CIRCULATION / FINES / APIKEYS rows
     showed only the borrowernumber; the old template showed the
     patron's full name and used "API keys for <name> (<id>)" wording.

  3. Several user-visible strings in renderObject() were hard-coded
     English ("Bibliographic record ", "Subscription ", "Authority ",
     "Basket ") and would never have been picked up by the translator.

  4. The form's Actions list still includes RESTORE but the new
     str/viewlog.inc action_labels map missed the corresponding entry,
     so the rendered Action cell fell through to escapeHtml("RESTORE")
     instead of the localised "Restore".

This patch:

  * Asks the API to embed both `librarian` and `patron` and uses those
    objects when rendering the Librarian and Object columns. When the
    embed is absent (e.g. because the relation does not match for a
    non-MEMBERS row) the renderers fall back to the bare id, preserving
    backwards compatibility.

  * Wraps the four hardcoded strings in __() with %s placeholders so
    the translator extracts them. The Basket markup is also assembled
    via __("Basket %s").format(...) rather than string concatenation
    so that translators can re-order the link text.

  * Adds RESTORE: _("Restore") to str/viewlog.inc.

Test plan:
  1. Tools -> Log viewer with various modules selected.
  2. Verify the Librarian column shows "Firstname Surname (id)" and
     links to the moremember page.
  3. Filter to MEMBERS / CIRCULATION / FINES; verify the Object column
     shows the patron's full name, and the API keys row uses the
     "API keys for <name> (<id>)" wording.
  4. Filter to CATALOGUING / SERIAL / AUTHORITIES / ACQUISITIONS; verify
     "Bibliographic record N", "Subscription N", "Authority N" and
     "Basket N" still link correctly.
  5. Restore a deleted biblio (CataloguingLog must be on); verify the
     Action column shows "Restore" rather than "RESTORE".

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:44 +01:00
Martin Renvoize 3a05b239db
Bug 29016 [25.11.x]: (QA follow-up) Expand action_logs API and test coverage
Build on the new ActionLog DBIC relations to expose them as opt-in
embeds, and shore up gaps in the test coverage that QA flagged.

Swagger
  * paths/action_logs.yaml declares an x-koha-embed header parameter
    constrained to the supported relations (librarian, patron).
  * definitions/action_log.yaml adds the corresponding optional
    `librarian` and `patron` object fields.

Tests
  * Convert the single 24-test subtest into focused subtests:
    - authorization (403 vs 200)
    - simple typed filters
    - q-DSL: multi-value module, info LIKE, combined filter
    - embeds: librarian and patron, with and without x-koha-embed
    - pagination + X-Total-Count and order_by
  * Mock AuthSuccessLog/AuthFailureLog/BorrowersLog to 0 to remove the
    flakiness where the API GET itself appended an AUTH log row between
    delete and assertion.
  * Build the test librarian with both `tools` and `borrowers` flags so
    embedded patron fields are not redacted by Koha::Patron->is_accessible.
  * Use a small build_fixtures() helper to avoid copy-pasting setup
    across subtests.

Test plan:
  1. yarn build && restart_all  (refresh swagger bundle)
  2. prove t/db_dependent/api/v1/action_logs.t  (all subtests green)
  3. curl -H 'x-koha-embed: librarian,patron' \
       /api/v1/action_logs?module=MEMBERS  -- patron and librarian
       objects appear in the response.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:26 +01:00
Martin Renvoize 52fe8c72b2
Bug 29016 [25.11.x]: (QA follow-up) Add librarian/patron relations to ActionLog
QA review noted that the new /api/v1/action_logs endpoint exposed only
column data, so the log viewer ended up showing bare borrowernumbers in
the Librarian and Object columns where the old server-side rendering
showed firstname/surname (borrowernumber). Add the DBIC plumbing needed
to support x-koha-embed for those relationships.

Two belongs_to relationships are declared below the auto-generated
marker on Koha::Schema::Result::ActionLog:

  * librarian -> borrowers.borrowernumber via action_logs.user
  * patron    -> borrowers.borrowernumber via action_logs.object

The patron relation is intentionally polymorphic; the action_logs.object
column holds different identifiers per module (biblionumber for
CATALOGUING, subscriptionid for SERIAL, ...) so callers must filter by
module before trusting the joined patron - this is documented in both
schema and Koha::ActionLog comments.

Koha::ActionLog gains explicit librarian() and patron() accessor methods
following the Koha::Hold pattern, returning Koha::Patron objects (or
undef when the relation does not match). The accessors deliberately
avoid `use Koha::Patrons` at compile time: Koha::ActionLog is loaded
very early via C4::Log and Koha::Patron is not yet defined at that
point - the accessors reach for it lazily at call time.

koha_object_class / koha_objects_class overrides are also added to bring
the result class in line with the rest of the codebase.

Test plan:
  1. prove t/db_dependent/api/v1/action_logs.t  (still green)
  2. perl -MKoha::ActionLog -e 'print "ok"' (no circular import)

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jacob O'Mara <Jacob.omara@openfifth.co.uk>
2026-05-24 13:42:26 +01:00