Commit Graph

27407 Commits

Author SHA1 Message Date
Martin Renvoize 1e0442b847
Bug 41105: (QA follow-up) DRY out gender label rendering
The gender-code-to-label mapping (F/M/O -> Female/Male/Other) was
duplicated between the results table cell and the edit-form select
options in modborrowers.tt. Extract it into a shared
patron-sex-label.inc so there is a single place defining the mapping,
and drop the now-unused "lib" values from the sex options in
tools/modborrowers.pl (labels are supplied by the include, keyed on
the option value, rather than by Perl).

Test plan:
1. Navigate to Patrons and click Search, to display a list of patrons.
2. Select all results and click "Batch patron modification".
3. Verify the "Gender" column displays Female/Male/Other correctly.
4. Verify the "Gender" edit dropdown still offers Female/Male/Other
   and saves correctly.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-14 12:09:18 +00:00
Martin Renvoize b51a3f111a
Bug 41105: (QA follow-up) Fix gender label translation
The batch patron modification "Gender" column and edit dropdown
hardcoded "Female"/"Male"/"Other" as data passed from
tools/modborrowers.pl, and the "Other" gender label was displayed as
plain text.

Values coming from Perl as template data are never picked up by the
PO extractor, so the gender select options in the edit form could
never be translated. Elsewhere in Koha (moremember.tt,
moremember-brief.tt, memberentrygen.tt, opac-memberentry.tt) the
"Other" gender label is wrapped with tp('gender', 'Other') to give
translators context, since "Other" is ambiguous out of context.

This makes the "Gender" dropdown options translatable directly from
the template, and aligns "Other" with the existing tp('gender', ...)
convention used everywhere else gender is displayed.

Test plan:
1. Navigate to Patrons and click Search, to display a list of patrons.
2. Select all results and click "Batch patron modification".
3. Verify the "Gender" column and "Gender" edit dropdown still work as
   expected.
4. Confirm (e.g. via the .pot file or misc/translator/translate) that
   "Female", "Male" and the "Other" (gender) msgctxt string are now
   extracted for translation from this template.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-14 12:09:17 +00:00
Olivia Reynolds 0bb26abd5a
Bug 41105: Add gender to batch patron modification
This patch adds the ability to batch-edit the gender field for patrons.

Test plan:
1.  Ensure there are a number of patrons in the database.
2.  Apply patch.
3.  Navigate to Patrons and click Search, to display a list of patrons.
4.  Select all results and click "Batch patron modification".
5.  Verify the "Gender" column is displayed.
6.  Verify the "Gender" column may be toggled under the "Columns"
    dropdown.
7.  Select a subset of the patrons for modification.
8.  Verify there is a "Gender" option beneath the table.
9.  Select "Female" as the gender, and click "Save".
10. Verify the gender of all selected patrons was set to "Female".
11. Repeat with "Male" and "Other" as the gender.
12. Repeat with clearing the gender field by ticking the checkbox next
    to the dropdown and saving. Verify the gender field is blank for
    each selected patron.

Sponsored-by: Open Fifth
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Amit Gupta <amit.gupta@informaticsglobal.ai>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-14 12:09:15 +00:00
Owen Leonard 55bc6f01e0
Bug 41842: (follow-up) Ensure that tidy doesn't trim wanted whitespace
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-12 16:08:01 +00:00
Owen Leonard 1b00485b27
Bug 41842: (follow-up) Make sure this space doesn't get tidied
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-12 16:07:59 +00:00
Martin Renvoize 3cd648d52f
Bug 41842: Use space-dash-space separator between course name and section
The staff interface templates were using a bare hyphen with no spaces
when displaying course name and section together, while the OPAC templates
(Bug 42654) use ' - ' (space-dash-space). This brings the staff interface
into alignment with the OPAC convention for consistency and readability.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-12 16:07:58 +00:00
Owen Leonard 303ba57409
Bug 41842: Improve translation of course reserves headings
This patch adds some use of I18N functions to course reserves templates
in order to improve the process of translation by adding context and
placeholders. The patch also rewords some headings for clarity and
consistency.

To test, apply the patch and go to course reserves.

- Add a course if necessary.
- Click the course to view it.
- On the course details page, confirm that the page title, breadcrumbs,
  and heading look correct.
- Click "Edit" in the toolbar.
- Check the page title, breadcrumbs, and heading again.
- Return to the course details and click "Add reserves" and check that
  page.
- Submit a barcode or biblionumber and check that page.
- Test the "Batch add reserves" page.

To test the improved I18N, apply the patch and test that the correct
strings are translatable. In this example I'm testing fr-FR:

- Update a translation:

    > gulp po:update
    > cd misc/translator
    > perl translate update fr-FR

- Open the corresponding .po file for the modified strings, e.g.
  fr-FR-messages.po.
- Locate strings pulled from course reserves templates for
  translation, e.g.:

    #: koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course.tt:10
    #: koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course.tt:42
    #: koha-tmpl/intranet-tmpl/prog/en/modules/course_reserves/course.tt:56
    #, fuzzy, perl-brace-format
    msgid "Edit course {course_name}"
    msgstr "Modifier {course_name}"

- Remove the "fuzzy,"
- Edit the "msgstr" string however you want (it's just for testing)
- Install the updated translation:

  > perl translate install fr-FR

Switch to the translation you updated. Walk through the process of
editing a course and adding course reserves to confirm that your translated strings show up.

Sponsored-by: Athens County Public Libraries
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-12 16:07:55 +00:00
Katrin Fischer bb53e653f3
Bug 43239: (QA follow-up) Rephrase hint on subscription form
This is to clarify that the item's current item type will
not be changed, no matter what settings have been used in
the subscription.

Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-12 15:49:50 +00:00
David Nind 5005019b5d
Bug 43239: (follow-up) Update wording for hint
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-12 15:49:50 +00:00
Emmi Takkinen 02515ebcc7
Bug 43239: Preserve item item type if previousitemtype column is undefined
It is possible to create serial item with wrong itemtype if syspreference
makePreviousSerialAvailable is enabled and field "item type for older issues"
isn't filled when creating a subscription for biblio record. This happens
when multiple items are created. In installations where itemtypes differ
between items and biblios, this causes data inconsistencies and leads to
errors in biblios Holdings table.

This patch changes behaviour of serials-edit.pl so that if
makePreviousSerialAvailable is enabled and subscriptions previousitemtype
column is NULL, previous serial items itype column is preserved. It also
adds a hint text to subscription form about this change.

To test:
1. Enable systempreference makePreviousSerialAvailable.
2. Create new biblio record.
3. Create a new subscription for biblio record you made, select option
"Create an item record", select different item type from "Item type"
selection than biblio record has but leave selection "item type for older
issues" empty.
4. Receive a serial item for subscription. Check from biblio records
Holdings table that its item type matches item type selected in step 3.
5. Now receive 3 serial items. After creating them check Holdings table again.
=> Note that first item created now has same item type as biblio record.
6. Apply this patch, restart services.
7. Create new subscription, fill needed fields as in step 3.
=> Note that there is a new hint text after field "item type for older issues".
8. Repeat steps 4. and 5.
=> Note that now all items have same item type.

Sponsored-by: Koha-Suomi Oy
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-12 15:49:49 +00:00
Martin Renvoize 8145e26a93
Bug 42471: (follow-up) prevent XSS in suggestion status
The custom/authorized-value status branch concatenated row.status
directly into a class="..." attribute string. escape_str() only
escapes &, <, > (not quotes), so a status code containing a double
quote could still break out of the attribute.

Build the status <span> via DOM APIs instead, the same way the
reason field was fixed: fixed statuses get a hardcoded class, and
the free-form status code goes into a data-status attribute via
dataset, which the DOM escapes safely regardless of content.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-11 12:39:35 +00:00
David Cook 222dac6c3c
Bug 42471: (follow-up) prevent XSS in suggestion reason
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-11 12:39:34 +00:00
Jonathan Druart acf1184436
Bug 42471: Prevent XSS in suggestion.tt
escape_str all the things

Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-11 12:39:33 +00:00
Owen Leonard 3b5f16adc6
Bug 40498: Improve style of list transfer form
This patch makes some style changes to the list transfer form. Since it
needs the same CSS that is used on the circulation page, the CSS block
is moved from circulation.tt to staff-global.scss.

The patch also changes the behavior of the form so that the "New owner"
line doesn't appear until after a patron has been selected.

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

- If necessary, create a public list.
- From the list of public lists, click the "Transfer" button.
- Verify that the form looks correct. The patron search field should
  match the search field shown when you navigate directly to
  circulation.pl
- Search for a patron who has permission to manage public lists.
  - After you select a patron, a new line should appear:
    "New owner: [name]"
- Click "Transfer" and confirm that the process works correctly.

Sponsored-by: Athens County Public Libraries
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:07:36 +00:00
Jennifer Sutton 4110bcf3bf
Bug 30759: Add hint about the data that is sent via the Google Books API to OPACSuggestionAutoFill
Add information about the data that is sent to Google if the
OPACSuggestionAutoFill system preference is enabled.

Test plan:
1. Go to Administration > System preferences.
2. Search for the OPACSuggestionAutoFill system preference.
3. Note that there is no note about the data that is sent to
   Google if the system prference is enabled.
4. Apply the patch.
5. Refresh the page.
6. There is now a note about the data that is sent to Google.
7. Check that it reads well and makes ense.

Sponsored-by: Catalyst IT
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:07:36 +00:00
Martin Renvoize df7e600587
Bug 41649: Add option to set magnetic flag for item itemtypes
This patch adds the ability to set an item type as magentic for SIP
response purposes.

Test plan:
1) Run included database updates
2) Navigate to admin > itemtypes
3) Edit/Add an itemtype and scroll to the 'Sip media types' input
4) A new 'Sip magnetic' checkbox should be available
5) Confirm setting/unsetting it works as expected
6) The SIP magnetic flag bit should respect the setting
7) To test SIP functionality:
   a) Start the SIP server (e.g., koha-sip service)
   b) Create an item with an itemtype that has sip_magnetic checked
   c) Use misc/sip_cli_emulator.pl to send a checkout request:
      perl misc/sip_cli_emulator.pl -a localhost -p 6001 -su <sip_username> -sp <sip_password> -l <location_code> --patron <patron_cardnumber> --password <patron_password> --item <item_barcode> -m checkout
   d) Check the SIP response to ensure it handles magnetic media correctly (e.g., no desensitization flag)

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Marcus Michel <marcus.michel@rbkc.gov.uk>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:07:33 +00:00
Olivia Reynolds 51e3d5435a
Bug 40668: Don't depend on checkboxes existing in drawCallback
The checkboxes this callback listens to events on are conditionally
rendered, depending on whether the user has permission to edit each
item. When moving from a page with no checkboxes displayed to one with
checkboxes displayed, the checkbox elements may not exist at the time of
this callback, so the listener is not attached and the checkboxes are
inoperable.

This patch fixes this by using a delegated event handler on the row,
which doesn't depend on the checkbox existing at the time.

Test plan:
1.  Enable the system preference EnableItemGroups.
2.  Set up a non-super-librarian patron, with permission to:
    - view the catalogue (catalogue)
    - create update and delete item groups (manage_item_groups)
3.  Place this patron's library in a group by itself, with "limit item
    editing" enabled. The patron should only be able to edit items from
    their own library.
4.  Pick an item in the catalogue, and add at least 40 items to it from
    a library the patron cannot edit items from. Add at least one item
    from the patron's library that they can edit. The 40 items are to
    ensure there is a complete (20 item) page that the patron cannot
    edit anything on.
5.  Create an (empty) item group on this catalogue entry.
6.  Log in as the unprivileged patron and navigate to the holdings view
    for the relevant catalogue entry.
7.  Navigate through the holdings table pages until there is a page with
    no checkboxes.
8.  Navigate to a table page with a checkbox. Select one of the
    checkboxes, and verify no actions appear at the top of table, even
    though you should have permission to add this item to a group.
9.  Apply this patch, and hard refresh to load the new JavaScript.
10. Repeat steps 6-8, verifying the checkbox now appears correctly.
11. Verify you can add the item to an item group using the now-appearing
    action.

Sponsored-by: Open Fifth
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:05:28 +00:00
Pedro Amorim 60725ab4f1
Bug 43204: Fix ILL availability Source column ignoring deep link
ill-availability.js renders results from ILL availability plugins.
Each result can carry a `url` (deep link to the record) and an
`opac_url` (generic fallback). The Title column correctly prefers
`url`, but the Source column links to `opac_url` unconditionally and
never checks `url`, so results always link to the bare OPAC URL even
when a deep link is available.

Make Source prefer `url`, falling back to `opac_url`, same as Title.

To test:
1) Install the latest release of the plugin:
   https://github.com/openfifth/koha-plugin-ill-avail-z3950/releases
2) Enable ILLModule, ILLCheckAvailability.
3) Set AdditionalFieldsInZ3950ResultSearch = 856$a, 999$c, 001.
4) Add Z39.50 server: Name KTD, Hostname localhost, Port 2100,
   Database biblios, Syntax MARC21/USMARC.
5) Configure the ILL z3950 plugin: tick the 'KTD' box, set bib ID
   field 999$c, deep link
   http://localhost:8081/cgi-bin/koha/opac-detail.pl?biblionumber=source_record_id,
   OPAC URL http://localhost:8080, tick the last 3 display
   checkboxes, leave Partner ID blank.
6) Add a new ILL request: type book, ISBN 0879307447, cardnumber 42,
   destination library Centerville.
7) Go to availability search, confirm the result links to the
   correct deep-linked biblio, not a bare fallback.

Signed-off-by: Edith Speller <Edith.Speller@ukhsa.gov.uk>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:05:27 +00:00
Jonathan Druart c39aa5f6a7
Bug 42451: Remove duplicate success message
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:05:26 +00:00
Jonathan Druart fb0fb890e2
Bug 42451: Remove JS error when converting a report
Test plan:
Create a report with: SELECT marcxml from biblioitems
Hit /reports/guided_reports.pl?op=list
Notice the "Update SQL" button in the "Update" column, Click "Update"
=> JS error
"Uncaught TypeError: can't access property "backdrop", this._config is undefined" (in Firefox)
And nothing happens
Apply this patch, reload, click the button
=> Success, the report is updated

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:05:25 +00:00
Laura_Escamilla e9b9509461
Bug 42235: Add message type header to OPAC messaging table
The OPAC messaging table includes an empty first column header. This column
contains the message type, such as Item due, Advance notice, Hold filled, and
Auto renewal. Because the header only contains a non-breaking space, it is
flagged by accessibility tools as an empty <th> element.

Add a translated "Message type" label to the first column header so it has
meaningful accessible text.

Test plan:
1. Log in to the OPAC
2. Go to "Your messaging settings"
3. Inspect the messaging table header
4. Confirm the first column header contains no meaningful text

Apply the patch:
5. Reload the page
6. Confirm the first column header contains "Message type"
7. Confirm the messaging table still displays correctly
8. Run an accessibility checker and confirm the empty table header error is resolved
9. Sign off and have a wonderful day! :D

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:05:24 +00:00
Laura_Escamilla 444cad89c7
Bug 42235: Add accessible label to DataTables control column in OPAC messaging
The OPAC messaging table includes a DataTables responsive control column
with no header text. This results in an empty <th> element and an empty
aria-label, which is flagged by accessibility tools.

Add a translated "Expand" label to the control column header so it has
meaningful accessible text.

Test plan:
1. Log in to the OPAC
2. Go to "Your messaging settings"
3. Inspect the messaging table header
4. Confirm the control column header contains no text

Apply the patch:
5. Reload the page
6. Confirm the control column header contains "Expand"
7. Confirm responsive row expansion still works
8. Run an accessibility checker and confirm the error is resolved
9. Sign off and have a wonderful day!

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:05:23 +00:00
Martin Renvoize 4deb199163
Bug 42656: (QA follow-up) Make error status persistence consistent, with a full trace, across FTP, SFTP and Local
Two related inconsistencies remained across the three transport
backends' error-handling paths:

1) Only Koha::File::Transport::SFTP's _abort_operation() persisted an
   "errors" status snapshot to the status column on every failed
   operation. FTP never did, and Local had no _abort_operation() at
   all - so an SFTP transport's displayed status could reflect a
   single transient failure from real usage (e.g. an EDI cron job)
   while the exact same failure on FTP/Local left the stored status
   untouched (stale, possibly still showing the last explicit
   test_connection() result). This is exactly the kind of unclear
   status reporting bug 42656 is about.

2) FTP's _abort_operation() carried its extra detail under an
   operation_params key, while SFTP (and Local's plain add_message
   calls) used path. The change_directory() success payload had the
   same split: FTP used directory, SFTP and Local used path. The
   admin template's change_directory row display depended on FTP's
   mismatched key names, which meant it silently failed to show the
   tested directory for SFTP transports.

Adds a shared _record_error($operation, \%payload) to the
Koha::File::Transport base class - add_message() plus status
persistence - and routes all three backends' _abort_operation() (Local
gains one) through it. Renames FTP's operation_params/directory keys
to path throughout, matching SFTP and Local, and simplifies the
template to read operation.detail.path unconditionally instead of
ORing two differently-named keys.

_record_error() persists the full trace of operations recorded on the
transport object so far this session (every success leading up to the
failure), not just the failing operation in isolation - the same
"full trace" shape TestTransport::process() already builds for an
explicit test_connection() run. A long-lived transport used across a
multi-step operation (e.g. an EDI download loop touching several files
before one fails) will therefore show every successful step leading up
to the failure. It also logs the failure - including the built trace -
via Koha::Logger at warn level, so it's visible in the Koha logs
without needing to query the transport's status column.

Test plan:
1. prove -r t/db_dependent/Koha/File/ t/db_dependent/Koha/BackgroundJob/TestTransport.t t/db_dependent/Koha/Edifact/Transport.t t/db_dependent/api/v1/file_transports.t
   => All tests successful (48 tests total), including:
      - new "_abort_operation persists status consistently" subtests
        in FTP.t, SFTP.t and Local.t that reload the transport from
        the DB after a simulated failure and confirm the status
        column was updated with the correct operation code and path
        detail;
      - a new "_record_error() tests" subtest in Transport.t proving
        the persisted trace includes a prior success message plus the
        failure (not just the failure alone), and that a warn-level
        log line mentioning the operation and error was emitted.
2. koha-qa.pl -v 2 --more-tests
   => [PASS], no critic/pod warnings.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:05:21 +00:00
Martin Renvoize f8cf2aea42
Bug 42656: (QA follow-up) Fix dead status code in file_transport_test.inc
Two issues in the operation_description BLOCK's status text, both
flagged in review:

1) The IF/SET that computed the " passed."/" failed." status text sat
   between the SWITCH statement and its first CASE. Template Toolkit
   only executes CASE-labelled content inside a SWITCH block, so this
   was dead code - status was never actually set, and every operation
   row silently rendered with no passed/failed text at all. It also
   checked operation.error, a field that doesn't exist on the
   operation hash (the error message lives under operation.detail.error,
   and whether the operation failed is operation.status eq 'error');
   even if the code path were reachable it would always have taken the
   "passed" branch.

2) Relying on a leading space baked into the " passed."/" failed."
   string literals to separate them from the preceding </span> is
   fragile. Made the space explicit in the markup instead, and dropped
   the leading space from the string values.

Moves the status computation above the SWITCH (using operation.status),
and adds an explicit space before [% status | html %] on every CASE line.

Also adds t/db_dependent/Koha/BackgroundJob/TestTransport.t, which was
entirely missing: it exercises process() end-to-end (enqueue, then
process, then reload both the job and the transport) and confirms the
persisted trace records every operation in sequence - successes before
the failure that ended the run - rather than collapsing to just the
final error.

Test plan:
1. prove t/db_dependent/Koha/BackgroundJob/TestTransport.t
   => All tests successful, confirming process() persists the full
      operation sequence (order preserved, at least one success and
      one error present) on both the job and the transport's own
      status column.
2. Manually rendered the fixed operation_description BLOCK with
   Template Toolkit against mock operations (mixed success/error) and
   confirmed every row now shows "Connection passed.", "Change
   directory (/incoming) passed.", ..., "Change directory (/outgoing)
   failed.- error:No such directory" - status text present with
   correct spacing, where before the fix no status text rendered at
   all.
3. prove -r t/db_dependent/Koha/File/ t/db_dependent/Koha/Edifact/Transport.t t/db_dependent/api/v1/file_transports.t
   => All tests successful (47 tests total), no regressions.
4. koha-qa.pl -v 2 --more-tests
   => [PASS], no critic/pod warnings.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:05:20 +00:00
Nick Clemens 7d6dafef6d
Bug 42656: Improve file transport test display
This patch displays the directory tested in the background jobs results

It updates the language when test results are not stored for the transport and
links to the job when results are stored

To test:
1 - Setup an ftp file transport with good credentials
2 - Enter non-existent directories in incoming/outgoing
3 - Save
4 - Verify on save 'Never used' shows for status
5 - Refresh the page, status now:
     Connection ok
     Change directory ok
     Change directory failed
     Change directory ok
     Change directory failed
6 - Apply patch, restart all
7 - Edit/save the transport again, change nothing
8 - Confirm the page says 'No test results stored'
9 - Reload the page
10 - Confirm results are now:
     Connection ok
     Change directory ok
     Change directory failed
     Change directory ok
     Change directory failed
     Test job details
11 - Click on the job details link
12 - Confirm actual directory and errors are shown
13 - Edit the transport, use existing directories
14 - Save, reload
15 - Confirm the success results and link t background job

Signed-off-by: John Vinke <jvinke@austinseminary.edu>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-06 16:05:19 +00:00
Casey Conlin c267c679a1
Bug 16631: Fix: Remove TT tags from kohaTable() initialization in guided_reports_start.tt
Sponsored-by: Ramapo Catskill Library System

Bug 16631: Update saved reports table to use use named DataTables columns.

RM amended: Fix commit title

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-04 10:20:59 +00:00
Martin Renvoize 0d0ba262fe
Bug 42915: (QA follow-up) Defer coded_values declaration until document ready
holds.js declared `coded_values` as a bare top-level global, evaluated
immediately at script-parse time, reading `all_libraries` which is only
ever defined by the including template (request.tt, or
patron-detail-tabs.inc for circulation.tt/moremember.tt). This works
today only because those templates happen to emit their `all_libraries`
script block before Asset.js("js/holds.js") in the rendered HTML - a
fragile, easy-to-break ordering dependency between separate template
files, not something holds.js itself can guarantee.

Move the assignment into the existing $(document).ready() handler,
setting it explicitly on `window` so it remains visible as a global to
datatables.js's build_query(), which reads `coded_values` unqualified.
This defers evaluation until all synchronous inline scripts (including
whichever template defined all_libraries) have already run, regardless
of future include/ordering changes.

To test:
1. Place holds on a title for two different pickup libraries
2. Confirm the holds table on reserve/request.tt, the patron's Holds
   tab (circulation.pl and moremember.pl) all load with no console
   errors
3. Confirm filtering the holds table by pickup library name/branchcode
   still works on all three pages

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-04 10:20:58 +00:00
Martin Renvoize c7d13ee7a3
Bug 40445: (follow-up) Move TT values out of kohaTable script blocks
xt/tt_kohaTable_tidy.t forbids mixing Template::Toolkit tags with
.kohaTable() calls inside the same <script> block, since such blocks
are expected to be pure JS. The cashup modal init calls in
pos/register.tt and pos/registers.tt embedded TT-derived values
(bankable amount, register float, reconciliation note settings,
cashup progress) directly alongside kohaTable() initialisation,
tripping the check.

This moves those TT expressions into the existing TT-tag-only
<script> block that precedes the kohaTable block in each template,
exposing them as a plain JS object (cashupModalData) that the
kohaTable block then reads.

Test plan:
1. Apply the patch.
2. prove xt/tt_kohaTable_tidy.t -- register.tt and registers.tt
   should no longer be listed among the failures.
3. Load the POS register and registers pages, confirm the trigger
   and confirm cashup modals still receive the correct bankable
   amount, register float, and reconciliation note settings.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-04 10:20:56 +00:00
Nick Clemens 0905d6a89f
Bug 42766: (QA follow-up) Add 'SCRIPTS' to log viewer
Apply this patch and confirm you can limit to 'Scripts' and that 'Scripts' is not in
all caps in the results

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-04 10:20:54 +00:00
Martin Renvoize 57cceec6bc
Bug 42766: Add ScriptLog system preference
Adds a new YesNo system preference 'ScriptLog' in the Logging section
of system preferences, adjacent to CronjobLog. When enabled, the start
and end of non-cron Koha scripts (those using bare 'use Koha::Script'
rather than 'use Koha::Script -cron') will be recorded in the action
log under the SCRIPTS module.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-04 10:20:46 +00:00
Paul Derscheid 8ebc1d0f2b
Bug 43091: Stop emitting staff-only Vue islands into the OPAC dist
Both islands builds share modules/islands.ts, which hardcodes every
island. The OPAC compilation therefore emits staff-only lazy chunks
(acquisitions-menu, vendor-menu, admin-menu) into
koha-tmpl/opac-tmpl/bootstrap/js/vue/dist/, and the OPAC islands.esm.js
bundles the staff Pinia stores.

- split modules/islands.ts into shared machinery and per-application
  entry points (islands-intranet.ts, islands-opac.ts)
- declare each application's islands as a Map literal and feed it
  through registerIsland(), the same path plugin islands take
- pass store definitions into hydrate() instead of importing every
  store in the shared module
- keep the full plugin import surface (registerIsland, hydrate, Vue
  re-exports) on both entries via star re-exports
- point the rspack islands entries at the per-application modules

Test plan:
1. yarn build
2. ls koha-tmpl/opac-tmpl/bootstrap/js/vue/dist/
   => only islands.esm.js and a patron-self-renewal chunk are emitted
3. ls koha-tmpl/intranet-tmpl/prog/js/vue/dist/
   => acquisitions-menu, vendor-menu and admin-menu chunks are still
   present
4. In the staff interface, visit pages using the acquisitions, vendor
   and admin menu islands and verify they render
5. Enable self-renewal for a patron's category and put the patron
   inside the availability window, e.g.:
   UPDATE categories SET self_renewal_enabled = 1
     WHERE categorycode =
     (SELECT categorycode FROM borrowers WHERE userid = 'koha');
   UPDATE borrowers
     SET dateexpiry = DATE_ADD(CURDATE(), INTERVAL 7 DAY),
     debarred = NULL WHERE userid = 'koha';
6. Log into the OPAC as that patron and open 'your summary'
   => the patron-self-renewal chunk loads from
   /opac-tmpl/bootstrap/js/vue/dist/ and the self-renewal modal
   completes successfully

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-03 13:00:36 +00:00
Owen Leonard be1bc44511
Bug 43206: cn_browser plugin red background on exact match is hard to read
This patch updates the cn_browser plugin output so that table rows are
highlighted using row classes and in colors which have sufficient
contrast.

To test, apply the patch and set your 952$o tag to use the cn_browser
plugin:

- Administration -> MARC bibliographic frameworks -> BKS -> MARC
  Structure -> Tag 952 -> Edit subfields.
  - Under the "Full call number" tab (o), set the "Plugin" dropdown to
   "cn_browser.pl" and save your changes.
- Go to Cataloging and locate a bibliographic record using the
  cataloging search.
- Add or edit items. NOTE: In the testing data there is only one item
  with a callnumber and it is "FIC/kas"
  - In the "o - Full call number" field, type "FIC" and then click the
    plugin editor image.
    - You should see the record with the "FIC/kas" call number and a
      green row right above it (indicating where an item with
      the call number "FIC" would be in the results).
  - Revise your search using the form at the top, entering "FIC/kas".
    - The record row should now be highlighted in pale yellow.

Sponsored-by: Athens County Public Libraries
Signed-off-by: Gretchen <maxeinergl@gcc.edu>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-03 13:00:35 +00:00
Owen Leonard 76167f6cfe
Bug 43177: Use archived link for Bridge Material Type Icon Set
This patch updates the About page in the section for the Bridge Material
Type Icon Set. The link is updated to use the last valid saved version
on the Internet Archive.

Sponsored-by: Athens County Public Libraries
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-08-03 13:00:29 +00:00
Paul Derscheid 53524b4824
Bug 43174: (QA follow-up) Restore user choices on redraw independent of search state
To test:
- cypress run --spec t/cypress/integration/KohaTable/PatronSearch_spec.ts
- cypress run --spec t/cypress/integration/KohaTable/KohaTable_spec.ts

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-31 13:40:30 +00:00
Jonathan Druart 684c6cb96a
Bug 43174: Restore defer loading for patron searches
On the hold request and the patron search pages, the search is not
deferred when a state exists.

Coming from
  commit 2a34413601
  Bug 41604: Save user decision per column when visibility changes
-        if (default_save_state_search) {
+        if (default_save_state || default_save_state_search) {
             $("#" + settings.nTable.id).data("loaded_from_state", true);
-        } else {
+        }

+        if (!default_save_state_search) {
             delete state.search;
             state.columns.forEach(c => delete c.search);

I think this was a leftover from another try to fix bug 41604. I don't
see how it could help in the context of saving the user decision.
In the different patches from bug 41604 we don't test loaded_from_state.

Test plan:
Go to /cgi-bin/koha/members/members-home.pl
=> The table is not displayed
Search for patrons
=> The table is displayed
Reload the page
=> Without this patch the table is displayed
=> With this patch the table is not displayed

If you have "Save search state on page change" enabled for this table,
the table should be displayed if a previous search was made.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-31 13:40:29 +00:00
Jonathan Druart 21e34086ca
Bug 43053: Simplify code, only 1 return statement
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-31 13:40:26 +00:00
Matt Blenkinsop 2ad5ba09cb
Bug 43053: Fix display of vendor payment methods
Test plan:
1) Add multiple vendor payment method authorised values
2) Create a vendor and add multiple payment methods
3) Click to edit, the payment method will be displaying one option of a "|" concatenated string
4) Apply patch and run yarn js:build
5) Hard refresh the browser, the payment methods should now display correctly
6) Edit the payment methods and save, the saved changes should be correctly displayed on the vendor details page
7) Add a new vendor with multiple payment methods, it should save correctly

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-31 13:40:25 +00:00
David Nind 4b7da59db5
Bug 43173: Update the terminology for the log viewer - "cardnumber" to "card number"
Update the log viewer to change "Modify cardnumber" to
"Modify card number", as per the terminology guidelines
https://wiki.koha-community.org/wiki/Terminology#C

Test plan:
1. Edit a patron and change their card number under the library
   management section.
2. Go to Tools > Additional tools > Log viewer.
3. Note under the actions section that there is an action:
   Modify cardnumber
4. Click "Submit" to see the log viewer results.
5. Note that there is an entry for the patron card number change
   with the action: "Modify cardnumber".
6. Apply the patch.
7. Refresh the log viewer page.
8. Note that "Modify cardnumber" is now "Modify card number"
   in both places.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Gretchen <maxeinergl@gcc.edu>
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-31 13:40:23 +00:00
Kyle M Hall 73380b410c
Bug 42988: Default holds_get_captured to yes for new SIP accounts
The account editor preselects "No" for "Holds get captured" when
creating a new SIP account, but the SIP checkin default is to capture
holds. This patch makes the editor default the option to "Yes" so a
new account behaves the same as one that never set the option.

Test Plan:
1) Apply this patch
2) yarn js:build
3) Restart all the things!
4) Create a new account in the SIP2 administration module
5) Note "Holds get captured" defaults to "Yes"!

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-31 13:40:17 +00:00
Laura_Escamilla ad1d40f0b7
Bug 43134: Add missing colons to OPAC advanced search section headings
To test :
1. Apply the patch
2. Go to the OPAC advanced search page http://kohadev.mydnsname.org:8080/cgi-bin/koha/opac-search.pl
3. Click More options
4. Notice that all section titles now use colons
   - "Search for:" = colon
   - "Limit to any of the following:" = colon
   - "Location and availability:" = colon
   - "Sort by:" = colon
   - "Publication range" = colon
   - "Language" = colon
   - "Audience" = colon
   - "Content" = colon
   - "Format" = colon
   - "Additional content types..." = colon
5. Sign off and have an incredible day! :)

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-31 13:40:15 +00:00
Owen Leonard 32e16ca89a
Bug 43192: Cast escape_str(obj) arg to string to use escapeHtml func
The escape_str function in the OPAC requires the argument to be a string,
and will throw a fatal error if passed a Number. This is because
String.prototype.escapeHtml is created by Koha and is not a JS standard.
This patch converts the object to a string before applying escapeHtml.

To test, apply the patch and log in to the OPAC.

- If necessary, add a list.
- Search for records in the catalog and add one or more of the results
  to your new list.
- Go to Lists -> Your lists.
- In the list of your lists, click the "Delete" link for the list you
  added records to.
  - You should see a confirmation modal, "Are you sure you want to
   delete this list?" showing the name of the list and the number of
   items on it.
  - Clicking "Yes, delete" should delete the list.

Sponsored-by: Athens County Public Libraries
Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-31 13:40:08 +00:00
Martin Renvoize 4b23e5c5d1
Bug 41410: (follow-up) Decouple exclusivity from LocalHoldsPriority
LocalHoldsExclusivity and LocalHoldsPriority are adjacent but distinct
features: priority alters *which patron's hold* gets filled first, while
exclusivity restricts *which items* may fill a hold during a time window.
Each should be usable independently of the other.

Changes:
- Rename LocalHoldsPriorityExclusivityPeriod to LocalHoldsExclusivityPeriod
- Add LocalHoldsExclusivityPatronControl (PickupLibrary/HomeLibrary)
- Add LocalHoldsExclusivityItemControl (homebranch/holdingbranch)
- HoldsQueue: add _flag_local_holdgroup_matches() that flags
  local_holdgroup_match on allocated items using hold-group matching
  and the new exclusivity control prefs, regardless of LocalHoldsPriority
- Reserves: CheckReserves exclusivity check now computes its own
  "is this item local" using the new prefs and hold-group siblings,
  independent of the LocalHoldsPriority matching variables
- Atomicupdate handles both fresh install and rename-from-old-pref paths
- Pref UI note clarifies independence from LocalHoldsPriority

Test plan:
1. Apply patch, run updatedatabase.pl
2. Verify three new sysprefs exist in Administration > System preferences
   > Circulation: LocalHoldsExclusivityPeriod, LocalHoldsExclusivityPatronControl,
   LocalHoldsExclusivityItemControl
3. Set LocalHoldsPriority to "Don't give" (None)
4. Create a library hold group with at least two libraries (e.g. Lib-A, Lib-B)
5. Create a third library (Lib-C) NOT in the hold group
6. Create an item at Lib-B
7. Place a hold for a patron at Lib-A (pickup at Lib-A)
8. Set LocalHoldsExclusivityPeriod to 7, PatronControl to HomeLibrary,
   ItemControl to homebranch
9. Run the holds queue builder (misc/cronjobs/holds/build_holds_queue.pl)
10. Verify hold_fill_targets.local_holdgroup_match = 1 for that hold
    (item at Lib-B is in the same hold group as patron at Lib-A)
11. Check in the item at Lib-C — it should NOT fill the hold (exclusivity
    blocks the non-local item within the 7-day window)
12. Check in the item at Lib-B — it SHOULD fill the hold (local match)
13. Reset: delete the hold, create a new one with a patron at Lib-C
    (pickup at Lib-C). Run the queue again.
14. Verify hold_fill_targets.local_holdgroup_match = 0 for this hold
15. The item at Lib-B should now fill this hold at Lib-C checkin
    (non-local patron, no exclusivity protection)
16. Set LocalHoldsExclusivityPeriod to 0 — verify non-local items can
    fill holds normally regardless of hold_fill_targets flag
17. prove t/db_dependent/Holds/LocalHoldsPriority.t — passes
18. prove t/db_dependent/HoldsQueue.t — passes
19. prove t/db_dependent/Reserves.t — passes

Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:12 +00:00
Martin Renvoize a2ef73fe95
Bug 41410: Add local holds priority exclusivity period
When LocalHoldsPriority is enabled, the holds queue picks a local-group
item for eligible holds.  Until now there was nothing to reserve that
priority at checkin time: if a non-local item was returned first, it
would happily fill the hold and the local-priority decision was lost.

This patch adds a time-bounded exclusivity window so that, for a
configurable number of days after a hold is placed, a hold whose queue
target is a local-group item will not be filled by a non-local item.

Changes:
 - C4/HoldsQueue.pm: in MapItemsToHoldRequests, flag %item_map entries
   that matched on local library (GiveLibrary/GiveLibraryAndGroup) or
   local hold group (GiveLibraryGroup/GiveLibraryAndGroup) with
   local_holdgroup_match => 1, and propagate that into both the
   tmp_holdsqueue and hold_fill_targets INSERTs.
 - C4/Reserves.pm: in the CheckReserves loop, when
   LocalHoldsPriorityExclusivityPeriod is set, the hold is still within
   that window, and the item being evaluated is not itself a local
   match, skip the reserve if its hold_fill_targets row has
   local_holdgroup_match = 1.  Missing hold_fill_targets row means "no
   information" -- fall through so holds are never trapped between
   queue runs.
 - circulation.pref: expose the new LocalHoldsPriorityExclusivityPeriod
   preference next to the existing LocalHoldsPriority* entries.

The feature is a no-op unless both LocalHoldsPriority is set to
something other than "Don't give" AND
LocalHoldsPriorityExclusivityPeriod is > 0.

Test plan:
 1) Apply the patches and run the atomicupdate.
 2) Set up a library group flagged as a local hold group containing
    two libraries (call them A and B).  Add a third library C that is
    NOT in the group.
 3) Add one item to each library (itemA, itemB, itemC) on the same
    biblio.
 4) Administration -> System preferences -> Circulation:
    - Set LocalHoldsPriority to "Give library group".
    - Set LocalHoldsPriorityPatronControl to "home library".
    - Set LocalHoldsPriorityItemControl to "home library".
    - Set LocalHoldsPriorityExclusivityPeriod to 7.
 5) As a patron whose home library is A, place a title-level hold with
    pickup at A.
 6) Run the holds queue (misc/cronjobs/holds/build_holds_queue.pl).
    -> The queue should target itemA (or itemB) for this hold.
    -> Confirm in the database:
         SELECT reserve_id, itemnumber, local_holdgroup_match
           FROM hold_fill_targets;
       The targeted row must have local_holdgroup_match = 1.
    -> Holds to pull / holds queue report should also show the flag
       (tmp_holdsqueue.local_holdgroup_match = 1).
 7) At library C, check in itemC (the non-local item).
    -> The hold must NOT be captured -- itemC simply goes back on the
       shelf.
 8) At library A, check in itemA (the local item).
    -> The hold IS captured for the patron.
 9) Cancel and re-place the hold, run the queue again.  Manually age
    the hold past the window:
         UPDATE reserves
            SET reservedate = DATE_SUB(CURRENT_DATE, INTERVAL 10 DAY)
          WHERE reserve_id = <id>;
    Now check in itemC again.
    -> The hold IS captured (exclusivity window has expired).
10) Re-place the hold but do NOT run the queue.  With no
    hold_fill_targets row for the reserve, check in itemC.
    -> The hold IS captured (we never trap holds between queue runs).
11) Flip LocalHoldsPriorityExclusivityPeriod back to 0 and repeat
    step 7.
    -> The hold IS captured; the feature is fully disabled.
12) Run:
      prove t/db_dependent/Holds/LocalHoldsPriority.t \
            t/db_dependent/HoldsQueue.t \
            t/db_dependent/Reserves.t \
            t/db_dependent/Koha/Hold.t
    -> All tests pass.

Sponsored-by: Main Library Alliance <https://www.mainlib.org/>

Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:09 +00:00
Jan Kissig 2fe11906a7
Bug 42292: (QA follow-up) replace remaining OD_password_required with Koha.prefs.OverDrivePasswordRequired
As in opac-user.tt OD_password_required was replaced by Koha.prefs.OverDrivePasswordRequired. The script overdrive.js checks already for the Koha.prefs variable.

1) Set sysprefs: OPACOverDrive, OverDriveCirculation, OverDrivePasswordRequired
= Enable/Yes; OverDriveClientKey, OverDriveClientSecret, OverDriveLibraryID =
any non-empty value (e.g. 123).
2) Go to <opac_url>/cgi-bin/koha/opac-user.pl, click "Log in to your OverDrive
account" - password modal appears (correct).
3) Go to <opac_url>/cgi-bin/koha/opac-overdrive-search.pl?q=music, click the
same link, it fails with "No password provided" instead, no modal.

4) apply patch and repeat 3) The modal appears now.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:07 +00:00
Jan Kissig c2514018b4
Bug 42292: (QA follow-up) remove unused reference OverDriveEnabled in opac-shelves
As OverDriveEnabled is declared via SET in the template and not a system preference and after all not used in that script it is removed.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:06 +00:00
Jan Kissig 87d4eac98e
Bug 42292: (QA follow-up) Fix evaluation of OpacHighlightedWords to be numeric in opac-results
OpacHighlightedWords was set in quotation marks and resulted in either "1" or "0".
As "0" and "1" always evaluates to true in JS the following error was thrown when OpacHighlightedWords was set to Don't highlight: Uncaught TypeError: $(...).highlight is not a function

To test:
a) Set system preference OpacHighlightedWords to Don't highlight
b) search a title in the opac with open dev console and check that no error (like above) is thrown.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:05 +00:00
Paul Derscheid 71b121bb6f
Bug 42292: (follow-up) Fix OverDrive/OpenLibrary references in opac-results.tt
Three issues introduced by the OPAC port of opac-results.tt:

- The tt-allowed block sets OverDriveEnabled via
  `Koha.Preference("OverDriveEnabled")`, but OverDriveEnabled is a
  TT-side SET variable (computed from OverDriveLibraryID +
  OverDriveClientKey + OverDriveClientSecret), not a system
  preference, so Koha.prefs.OverDriveEnabled is always "".
  The code at line 621 then reads an unprefixed `OverDriveEnabled`
  identifier which is not declared -- the OverDrive result block
  never fires.
- The neighbouring block `if (OpenLibrarySearch) { ... }` reads an
  unprefixed identifier for a value that is only exposed on
  Koha.prefs, so the OpenLibrary result block also never fires.
- Both blocks build a throbber <img> with
  `src=\`${interface}/${theme}/images/spinner-small.gif\`` inside a
  single-quoted JS string; the backticks are literal characters
  there, so the rendered src ends up as that literal template
  text, not a usable URL.

Replace the OverDriveEnabled addPrefs entry with a plain
`const OverDriveEnabled = [% OverDriveEnabled ? 1 : 0 | html %];`
that reads the TT SET variable, prefix OpenLibrarySearch with
Koha.prefs, and rebuild the throbber src via normal string
concatenation.

To test:
- With OverDrive configured (OPACOverDrive, OverDriveLibraryID,
  OverDriveClientKey, OverDriveClientSecret), run a search in the
  OPAC: the OverDrive results panel shows the spinner and then
  the API results.
- With OpenLibrarySearch enabled, the OpenLibrary panel does the
  same.
- In both cases the spinner image loads (no broken-image icon).
- Disable both prefs -> neither panel is rendered, no console errors.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:04 +00:00
Paul Derscheid b4035c5a0c
Bug 42292: (follow-up) Fix duplicate NovelistSelectProfile declaration
In the new tt-allowed block, the NovelistSelect fallback declarations
redeclare `NovelistSelectProfile` instead of also exposing
`NovelistSelectPassword`:

    var NovelistSelectProfile = "[% NovelistSelectProfile | html %]";
    var NovelistSelectProfile = "[% NovelistSelectPassword | html %]";

So `NovelistSelectProfile` ends up holding the password, and
`NovelistSelectPassword` is never declared. The later
`novSelect.loadContentForQuery(..., NovelistSelectProfile,
NovelistSelectPassword, ...)` call then throws ReferenceError and
NovelistSelect content never loads on biblio detail pages.

Rename the second declaration to `NovelistSelectPassword` to match
the original template behaviour.

To test:
- Configure the NovelistSelect sysprefs (NovelistSelectEnabled,
  NovelistSelectProfile, NovelistSelectPassword) in the OPAC. Real
  NovelistSelect content only loads with valid EBSCO subscription
  credentials -- with dummy values the JS path still runs but the
  tab stays empty; that is still sufficient to verify this fix.
- Open an OPAC biblio detail page with a known ISBN.
- In the browser console, run
  console.log(NovelistSelectProfile, NovelistSelectPassword)
  and confirm both values are printed (before the fix,
  NovelistSelectPassword is undefined).
- With valid subscription credentials, NovelistSelect content loads
  in its tab/panel instead of throwing a ReferenceError in the
  console.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:03 +00:00
Paul Derscheid a8da9a5f14
Bug 42292: (follow-up) Rename opac-shelves print flag to avoid shadowing window.print
The port declares `var print = [% print ? 1 : 0 | html %];` at the
top of the tt-allowed block, then later calls `window.print()` inside
`if (print) { ... }`. Declaring `var print` at top-level overwrites
the built-in `window.print` with 0 or 1, so the subsequent
`window.print()` call throws "print is not a function" and the print
view never fires its actual print dialog.

Rename the flag to `should_print` and update the single `if (print)`
check accordingly.

To test:
- Open a public list with items in the OPAC.
- Click "Print this list" (or load the page with op=print).
- The browser print dialog opens and the window closes afterwards.
- No "print is not a function" error in the console.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:02 +00:00
Paul Derscheid ed7fef7dd7
Bug 42292: (follow-up) Replace removed dateformat_pref var in OPAC calendar.inc
The OPAC port moved the dateformat pref into Koha.addPrefs and dropped
the local `var dateformat_pref = ...;` declaration, but four usages of
`dateformat_pref` remain in the same file (the debug alert, two
`switch` statements, and the get_dateformat_str call in validate_date).
At runtime the switches throw ReferenceError, so flatpickr ends up
with the default 'Y-m-d' format and date validation via validate_date
crashes before showing the invalid-date alert.

Replace all remaining occurrences with Koha.prefs.dateformat, which is
populated by the new addPrefs block at the top of the include.

To test:
- Set dateformat syspref to each of us / metric / dmydot / iso.
- Open any OPAC page using a flatpickr input (e.g. hold date, patron
  dob on the registration form).
- Confirm the widget renders dates in the expected format and
  entering an invalid string triggers the validate_date alert.
- No ReferenceError in the browser console on page load.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:01 +00:00
Jonathan Druart e53b7346c9
Bug 42292: Tidy all script tags - OPAC (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:50:00 +00:00
Jonathan Druart 5e822ff613
Bug 42292: Tidy all script tags - OPAC
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the OPAC module.

Non-trivial changes, we modify the whole OPAC in a single patch.
Testing this patch should focus on:
* date formatting
* the cover images on the search result and shelves views

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:49:59 +00:00
Jan Kissig 8812de46fe
Bug 42279: (QA follow-up) Fix straying TT variable, auto tidy
Removes a left over TT variable from a JS script block without data-tt-allowed="true" attribute. Auto tidy

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:49:58 +00:00
Paul Derscheid 3dbe00ccbe
Bug 42279: (follow-up) Restore numeric compare of quantityrec
The port quoted [% quantityrec | html %] into a string const, but
the value is used as `$(this).val() < quantityrec` where both sides
are now strings and JS does a lexicographic compare ("10" < "5" is
true), giving the wrong branch when the user enters a multi-digit
quantity.

Render quantityrec as a JS number (with a 0 fallback) so the
comparison stays numeric, matching the original template output.

To test:
- Modify an existing order with quantityrec, e.g. 5 items received.
- Change quantity to 10 (higher than received): "can't add new item"
  alert fires, value reverts.
- Change quantity to 2 (lower): "don't forget to delete" alert fires.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:49:57 +00:00
Jonathan Druart af445bdeba
Bug 42279: Tidy all script tags - acqui (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:49:56 +00:00
Jonathan Druart 3113ca088e
Bug 42279: Tidy all script tags - acqui
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the acquisition module.

The 2 main changes are in the following files:
* basket.tt
It's mostly about table settings and the visibility of columns depending
on syspref:
  - "supplier report" / EDIFACT
  - "modify" / if basket is not closed
  - "cancel" / CancelOrdersInClosedBaskets
* neworderempty.tt
trivial changes, no error or warning in the console should appear.
Confirm than createing a new order works as expected.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:49:55 +00:00
Owen Leonard 707878312b
Bug 41116: (follow-up) Fix template variable filter
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:49:54 +00:00
Owen Leonard 56928506ae
Bug 41116: (follow-up) Some more fixes for consistency
- There was a mix of "patronphone" and "patron-phone" and I fixed it to
  standardize on "patron-phone" (and patron-email) which I find easier
  to read.
- I made similar changes to the branchtransfers template
- Corrected the TT filter on mailto links from "html" to "uri"

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:49:53 +00:00
Andrew Fuerste Henry 1b2dd6ab54
Bug 41116: Standardize selectors in patron contact information in hold found modals
This patch modifies both hold-found-modal and hold-found1. It adds a
class to the patron phone number. For patron email, it changes the
existing id to a class, expands the selector to include the bullet
point in hold-found-modal, and standardizes the name (changing from
"#boreamil' to ".patronemail").

To test:
1 - have a patron with both a phone number and an email address
2 - create a hold for your patron
3 - check an item in to fill your hold, triggering the hold-found-modal
4 - inspect the patron contact info, confirm there is no class on the
    phone number
5 - confirm there is an id on the patron email but it does not include
    the bullet point and is inconsistent with the names of other classes
    in the modal
6 - click Confirm Hold
7 - check your item in again, triggering the hold-found1 modal
8 - confirm there is no class on the patron phone number
9 - confirm there is an id on the patron email with an inconsistent
    name
10 - revert the waiting status of your hold
11 - apply patch, restart_all
12 - check your item in again, triggering hold-found-modal
13 - confirm the patron phone now has a class, .patronphone
14 - confirm the patron email now has a class, .patronemail, that the
     class includes the bullet point, and that the #boremail id has been
     removed
15 - click Confirm Hold
16 - check your item in again, triggering hold-found1 modal
17 - confirm the patron phone now has a class, .patronphone
18 - confirm the patron email now has a class, .patronemail, and that
     the #boremail id has been removed

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:49:52 +00:00
Phil Ringnalda 67da9d31ec
Bug 36897: Make it possible to use select[multiple] and select[size] in a sidebar
Currently, if you put either <select multiple> or <select size="10"> in
an <aside><fieldset> sidebar, you get a height of "one fat line" rather
than the bigger box you would expect.

Test plan:
 1. Without the patch, load Reports - Use saved
 2. Open Firefox developer tools to the Inspector tab
 3. With the "Pick an element from the page" tool, click on the word
    "Filter" in the Reports page's sidebar
 4. Just above that line in the HTML display is a <fieldset
    class="brief"> - right click that and choose Edit As HTML
 5. After the fieldset element, paste

<select multiple><option>one</option><option>two</option></select><select size="10"></select>

 6. Click outside the editor to save your changes
 7. Note that both new selects are only one line high
 8. Apply patch, run yarn build, Shift+reload to clear your cache
 9. Repeat steps 3 through 6
10. Note that both selects are more than one line high
11. Set the preference EnableAdvancedCatalogingEditor to Enable
12. Cataloging - Advanced editor
13. In the left sidebar, verify that the Clipboard is still 10 lines high,
    not one fat line like it was before bug 36589

Sponsored-by: Chetco Community Public Library
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-29 15:49:51 +00:00
Owen Leonard 7dfa99f237
Bug 42118: Update various admin pages to use grid layout for forms - Part 2
This patch updates several more administration templates with new markup
and CSS for layout forms using CSS grids.

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

Check the following pages, confirming that the "New" and
"Edit" versions of the form look correct in each case:

- Administration -> Item search fields
- Administration -> OAI sets
  * Updated OAI set mappings form to add maxlength attributes to field
    and subfield inputs.
- Administration -> OAI repositories
- Administration -> SMS cellular providers
- Administration -> SMTP servers

Sponsored-by: Athens County Public Libraries
Signed-off-by: Felicie <felicie.thiery@biblibre.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:33:03 +00:00
Jan Kissig 415d1bf087
Bug 42284: (QA follow-up) Fix missing query param index
This restores the param "index" to the popup window URL.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:33:02 +00:00
Jan Kissig 848dce7c95
Bug 42284: (QA follow-up) biblionumber must not be null
Presetting biblionumber to null (when adding a new record) will lead to a query parameter biblionumber=null when performing a z39.50 search followed by  importing a result. This patch will default biblionumber to "".

Testplan:
a) go to More -> Cataloging -> New Record ->  Z39.50/SRU search
b) search for a title f.e. "Programming Perl"
c) import one of the results
d) check that the opened URL has a param biblionumber=null and the addbiblio page displays an error:  The record you are trying to edit doesn't exist.
Add a new record or do a catalog search.
e) apply patch and redo steps a) - d) and check that query param biblonumber is 0 and addbiblio loads correct carrying the imported data.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:33:01 +00:00
Jan Kissig e30141ac7c
Bug 42284: (QA follow-up) Add missing Koha.prefs
Fix call of marcflavour which is saved in Koha.prefs store.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:59 +00:00
Paul Derscheid 3e3708f65b
Bug 42284: (follow-up) Restore hide_marc polarity for marc tag visibility
The original UNLESS/ELSE block kept MARC tag links visible by
default and hid them only when the hide_marc syspref was enabled:

    [% UNLESS Koha.Preference("hide_marc") %]
        toggleMARCTagLinks(true)
    [% ELSE %]
        toggleMARCTagLinks(false);
    [% END %]

The JS port inverted the test without swapping the branches, so
when hide_marc was off the tag links were hidden and when it was
on they were shown -- the opposite of the pref's intent.

Flip the condition back (!Koha.prefs.hide_marc).

To test:
- Set hide_marc = 0: open addbiblio.pl, MARC tag numbers and
  subfield codes are visible on first load.
- Set hide_marc = 1 and clear the marctags cookie (devtools ->
  Application -> Cookies): reload addbiblio.pl, tag numbers and
  subfield codes are hidden on first load.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:58 +00:00
Paul Derscheid bdc88607e1
Bug 42284: (follow-up) Use z3950_mandatory name as query param, not marc_lib
GetMandatoryFieldZ3950 (in cataloguing/addbiblio.pl and
authorities/authorities.pl) populates subfield_loo.z3950_mandatory
with the z3950 query-field name expected by z3950_search.pl
(isbn, title, author, issn, lccn, ...). The pre-port JS copied
this value into mandatories_label and used it as the URL parameter
name in GetZ3950Terms.

The BIG_LOOP rewrite stored subfield_loo.marc_lib as `label`
instead. marc_lib is the human-readable field label ("Title
statement"), so GetZ3950Terms started emitting URLs like
&Title+statement=... which z3950_search.pl ignores, and the
z3950 lookup from the editor stopped matching any subfield.

Use subfield_loo.z3950_mandatory for the label in
z3950_mandatory_subfields on both templates.

To test:
- Open addbiblio.pl and fill the ISBN / title / author subfields.
- Click "Z39.50/SRU search".
- In the popup form (or the network request), the pre-filled
  fields should correspond to the entered values (title -> Title,
  isbn -> ISBN, ...). Before this patch they were empty.
- Same flow from authorities/authorities.pl on a matching
  authority type.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:57 +00:00
Paul Derscheid 0cd30ad0e0
Bug 42284: (follow-up) Fix important_fields push and id concatenation
The BIG_LOOP rewrite introduced two regressions in the mandatory /
important field collector at the top of addbiblio.tt:

- `important_fields.push([ tag: ..., id: ..., ... ])` wraps the
  object in brackets instead of braces. `[a: 1]` is not a valid
  array literal, so the parser aborts the whole script tag and
  AreFieldsNotOk / PopupZ3950 never run for any record whose
  framework marks fields as "important".
- The `id` interpolation joins index and random with a literal `$`
  (`"[% index %]$[% random %]"`), but the DOM ids rendered
  elsewhere in the template (and looked up by AreFieldsNotOk via
  `divid = "tag_" + tag + "_" + id`) concatenate them with no
  separator.

Use `{...}` for important_fields and drop the `$` so the collector
shape and ids match the rest of the template.

To test:
- Open addbiblio.pl for a framework that has mandatory and
  important fields (e.g. default MARC21).
- Submit a new record with mandatory subfields empty: the error
  panel lists them and focuses the first empty input.
- Submit with only important subfields empty: the warning panel
  (not blocking) lists them under "The following important
  subfields aren't filled".
- Browser console has no SyntaxError on page load.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:56 +00:00
Jonathan Druart 3560c28bd0
Bug 42284: Tidy all script tags - addbiblio/authorities (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:55 +00:00
Jonathan Druart 5848c185f2
Bug 42284: Tidy all script tags - addbiblio/authorities
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the edition of biblio and authority records.

We rethink how (the ugly) BIG_LOOP works:
* push all mandatory and important fields in a JS array
* use objects/hashes instead of array to store/access tag, id, index and
  tab (vs arr[0], arr[1], ...)

For testing you need to focus on the mandatory and important fields and
subfields. Confirm that there is no change in behaviour introduced by
this patch.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:54 +00:00
Jan Kissig 043396c8ae
Bug 42293: (QA follow-up) Fix hiding of additiona fields in serials-search
This fixes the hiding of additional fields in mana search by generating an array of additional field ids instead of calling To.json(additional_fields_for_subscription) which led to an Template process error.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:53 +00:00
Jonathan Druart b54bfa2670
Bug 42293: Tidy all script tags - serials (auto tidy)
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:52 +00:00
Jonathan Druart 2ecbac6060
Bug 42293: Tidy all script tags - serials
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the serials module.

The 3 main changes are in the following files:
* routing.tt
* serials-search.tt
* subscription-detail.tt

Changes are trivial.

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:50 +00:00
Hammat Wele 8d9d749c53
Bug 41988: (follow-up) Fix opac-news-rss page title
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:49 +00:00
Hammat Wele 30cc4af870
Bug 41988: OPAC News RSS links with HTML not working
The news RSS link on the OPAC appears to be invalid when the news
content contains HTML. Users cannot subscribe to the feed using
standard RSS readers or email clients.

To reproduce:

1- Go to Tools -> HTML customizations -> News
2- Click New Entry with the following settings:
   2-1- Display location: OPAC
   2-2- Publication date: today
   2-3- Title: "News test"
   2-4- Content: click on <> and paste some HTML code, for example:
        <span style="color: #ba372a; font-size: 12pt;">Le Pr&ecirc;t
        entre biblioth&egrave;ques est mis en pause.
        D&eacute;sol&eacute;s de
        l'inconv&eacute;nients.<br />Merci de votre
        compr&eacute;hension.</span>
3- Save the entry.
4- Go to the OPAC and copy the "RSS feed for system-wide library news"
   link.
5- Execute: curl -v
   http://opac/cgi-bin/koha/opac-news-rss.pl?branchcode= and copy the
   XML output to https://validator.w3.org/feed/ to check the feed.
     ==> The feed is not valid.
6- Try to create a subscription to this link in an email client (e.g.,
   Thunderbird).
     ==> It does not work, giving the error "Feed URL is not valid".
7- Apply the patch.
8- Repeat steps 5 and 6.
     ==> The feed is now a valid RSS.
9- Repeat step 7.
     ==> You can now subscribe to the RSS feed using standard readers
         and email clients.

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:48 +00:00
Emily Lamancusa 0aa5820916
Bug 40492: Improvements to offline circ actions table
Update the pending offline circulation actions page to link each item
barcode directly to the item details, rather than the biblio record, and
open the links in a new tab.

Add a column to show the last seen date of the items being processed,
with a warning if the item's last seen date is more recent than the
offline circulation action date.

To test:
1. Upload a Koha Offline Circulation (koc) file
   (the file attached to this bug can be used if you are using a
   sandbox or KTD with the standard sample data)
   i. Go to Circulation > Upload offline circulation file
   ii. Upload the file
   iii. Click "Add to offline circulation queue"
2. Go to Circulation > Pending offline circulation actions
3. Click on the item barcodes in the table
--> Note that each barcode links to the biblio record, and navigates
    away from the page within the same tab.
4. Apply patch and restart_all
5. Return to (or refresh) the pending offline circulation actions page
   and click on the item barcodes again
--> The barcodes now open the item details page in a new tab
--> There is a new column for the item last seen date
6. Without processing the offline circulation actions, check in one of
   the items listed in the table
7. Return to the Pending offline circulation actions page
--> Confirm that the last seen date of the item you just checked in is
    highlighted in red with a warning icon, since its last seen date is
    newer than the offline transaction date
8. Hover over the warning icon
--> Confirm that a tooltip appears with an explanation of why the date
    is in red

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:44 +00:00
Cameron E. Tidd 67a37a07c3
Bug 16631: Institute library limits
This patch implements the library_limit concept for Report/Reports. Staff with the correct permission and superlibrarians can set libaries to which the report should be visible, if the system preference is enabled.

Test plan:
Confirm Initial Settings
1. Log in to Koha staff with username: koha and password: koha and set your library as Centerville if it's not already.
2. Visit the Saved reports page, and create and save three reports: Report 1, Report 2, and Report 3. The SQL query for each report doesn't matter, it should just be something valid.
3. Visit the Patrons page and create two staff users: StaffReportLimitUser and StaffNoLimitPermission. Set their home libraries to Centerville and Fairfield, respectively.
4. Under Allow access to the reports module, ensure both users have report management permissions for Create, Delete, Execute.

Verify Patch Settings
5. Apply the patch and restart services. If using Koha Testing Docker (KTD): from the Koha repo directory, apply the patch (e.g. `git bz apply 16631`, or check out the patched branch with `git fetch && git checkout <branch>`), then run `ktd --shell` to enter the KTD shell and run `restart_all`. If the patched branch is already checked out, just enter the KTD shell and run `restart_all`.
6. Click Patrons in the top navbar to go to the Patrons page.
7. Search for "StaffReportLimitUser" in the patron search field.
8. Click StaffReportLimitUser to edit the patron record for this user.
9. Click More -> Set permissions to access the permissions screens for the StaffReportLimitUser.
10. In the row for Allow access to the reports module (reports), click Show details to view relevant permissions.
11. Confirm Manage Report Limits (manage_report_limits) is an option under Allow access to the reports module (reports).
12. Click the checkbox for Manage Report Limits to give this user this permission, and click Save.
13. Go to the System Preferences page (Click the More dropdown from the top nav bar, click Administration, click System Preferences).
14. Verify Reports is an option in the left side navigation bar, and that when clicked, you see the LimitReportsByBranch option.
15. Enable LimitReportsByBranch as described in step 14.
16. Go back to Saved reports as in Step 2.
17. Click Edit in the row menu for Report 1.
18. At the bottom of the Report 1 edit page, you should see a Library limitation select box.

Verify the Library Limitation Settings are Persisted
19. Choose Centerville from the select box and click Update SQL.
20. Reload the page, or navigate away from the page and go back to the edit screen for Report 1.
21. Verify that Centerville is still in the Library limitation select box.
22. Add Fairfield in the Library limitation select box and click Update and run SQL.
23. Go back to editing Report 1.
24. Confirm the Library limitation select box has both Centerville and Fairfield selected.
25. Duplicate Report 1.
26. Confirm the Library limitation select box has both Centerville and Fairfield selected.
27. Click Save Report.
28. Confirm the Library limitation select box has both Centerville and Fairfield selected.

Verify Reports are Limited Based on Library Limitations
29. Edit Report 1 to add Centerville in the Library limitation select box as the only choice and click Update SQL.
30. Edit Report 2 to add Fairfield in the Library limitation select box as the only choice and click Update SQL.
31. Report 3 should have no library limitations, so it should be visible to all libraries.
32. Go to Saved reports as in Step 2.
33. Confirm you do not see Report 2, and only Report 1 and Report 3.
34. In the upper right corner, click the drop down that says koha Centerville and click Set library to change your library.
35. Set your library to Fairfield.
36. Go to Saved reports as in Step 2.
37. Confirm you do not see Report 1, and only Report 2 and Report 3.

Verify Disabling LimitReportsByBranch Preference Shows All Reports
38. Disable LimitReportsByBranch preference as in steps 13 to 15.
39. Go to Saved reports as in Step 2.
40. Confirm Report 1, Report 2, Report 3 are visible.
41. Click to edit Report 1 and verify there is no Library limitation select box.

Verify Library limitations are Persisted When EnableFilteringReports is Toggled On or Off
42. Enable LimitReportsByBranch preference as in steps 13 to 15.
43. Ensure your library is set to Fairfield as in step 35.
44. Go to Saved reports as in Step 2.
45. Confirm Report 1 is not visible, and Report 2 and Report 3 are visible.
46. Click to edit Report 2 and verify the Library limitation select box is at the bottom of the page and that it has Fairfield selected.

Verify the Show all reports option shows all reports for users with the Manage Report Limits permission and superlibrarians
47. Go to Saved reports as in Step 2 and in the Show reports dropdown, select Show all reports, and click Apply filter.
48. Confirm the page reloads with all reports visible: Report 1, Report 2, and Report 3 should be visible.
49. Select Show my branch reports from the dropdown and click Apply filter.
50. Confirm Report 1 is not visible, and Report 2 and Report 3 are visible (you should only see reports for your branch, Fairfield).

Verify Report filters return the correct results
51. Go to Saved reports as in Step 2.
52. Verify you're viewing only your branch's reports in the filter.
53. Under Filter in the left sidebar, type "2" in the Keyword field and click Apply filter.
54. Confirm only Report 2 is visible.
55. Under Filter in the left sidebar, type "1" in the Keyword field and click Apply filter.
56. Confirm there are no reports visible, and the message "No saved reports match your criteria" is displayed.

Verify Library Limits column is available to superlibrarians and users with the Manage Report Limits permission
57. Go to Saved reports as in Step 2.
58. Click the Columns dropdown and ensure that the Library limits column is available to select for display. Select it.
59. Confirm that the Library limits column is now visible in the list of reports and that it shows the correct library limitations for each report (e.g., Report 1 should show 1 library limitation and Centerville (CPL) on hover, Report 2 should show 1 library limitation and Fairfield (FFL) on hover, and Report 3 should show no limitation).

Verify the Show all reports and Limit reports options are available to users that are not superlibrarian but have the Manage Report Limits permission
60. For the StaffReportLimitUser, add the permission for Manage Report Limits as described in steps 9 to 12. This will allow this user to see the Show all reports and Limit reports options.
61. Log out of the koha admin account. In the upper right corner, click the drop down that says koha Fairfield and click Log out.
62. Log in as StaffReportLimitUser, the previously created staff user with report permissions.
63. Confirm the staff user's library is Centerville in the upper right corner of the screen.
64. Go to Saved reports as in Step 2.
65. Confirm the filter option for Show reports is visible.
66. Click to edit Report 1.
67. Verify there is a Library limitation select box and that it can be interacted with.

Verify the Show all reports and Limit reports options are not available to users that are not superlibrarian and do not have the Manage Report Limits permission
68. Log out of the StaffReportLimitUser account.
69. Log in as StaffNoLimitPermission, the previously created staff user without the Manage Report Limits permission.
70. Confirm the staff user's library is Fairfield in the upper right corner of the screen.
71. Go to Saved reports as in Step 2.
72. Click the Columns dropdown and ensure that the Library limits column is not in the list of available columns to select for display.
73. Confirm the filter option for Show reports is not available.
74. Click to edit Report 2.
75. Verify there is no Library limitation select box at the bottom of the page.

[NEW] Verify library limits are auto-assigned and preserved correctly for non-permissioned users
76. Still logged in as StaffNoLimitPermission (Fairfield) from the previous section. Go to Saved reports and click New report. Enter "Limit Auto-Assign Test" as the report name and SELECT 1 as the SQL. Confirm there is no Library limitations select box visible on the form. Click Save.
77. Go back to Saved reports. Click Edit for Report 2 (limited to Fairfield). Add `-- test` as a trailing SQL comment and click Update SQL. This simulates a non-permissioned user saving an existing report that already has limits.
78. Go back to Saved reports. Click Edit for Report 3 (no library limits). Add `-- test` as a trailing SQL comment and click Update SQL. This simulates a non-permissioned user saving an existing report that has no limits.
79. Log out and log back in as StaffReportLimitUser (Centerville, has manage_report_limits).
80. Go to Saved reports. Use Show all reports if needed. Find "Limit Auto-Assign Test" and click Edit. Confirm the Library limitations select box shows Fairfield as the only selected library — the report was automatically limited to the creator's home library on create.
81. Find Report 2 and click Edit. Confirm the Library limitations select box still shows only Fairfield — the existing limit was preserved when the non-permissioned user saved the report.
82. Find Report 3 and click Edit. Confirm the Library limitations select box is empty — no limits were introduced when the non-permissioned user saved a report that had no existing limits.

Verify limited reports are not visible to users without permissions
83. While still logged in as StaffReportLimitUser from step 79, copy the URL for the edit page of Report 1.
84. Log out of the StaffReportLimitUser account.
85. Log in as StaffNoLimitPermission, the user without the Manage Report Limits permission.
86. Paste the copied URL for the edit page of Report 1 into the browser and navigate to it.
87. Confirm that you see an error message that says "This report is restricted and cannot be accessed by the current user." and that the page does not load the report details.

Run Unit Tests
88. Using Koha Testing Docker, in the Koha home directory run the command: ktd --shell to start the ktd shell.
89. Run command: reset_all to drop and recreate the koha database.
90. Run command prove t/db_dependent/Koha/Reports.t to run the test.
91. This file contains the unit tests for the reports_branches table and the new subtest `library limits enforcement on save and update`, which covers auto-assignment of branch limits on create and preservation of limits on update for non-permissioned users.
92. All tests should pass.
93. Run command prove t/Koha/Auth/Permissions.t
94. Permissions unit tests in this file were updated.
95. All tests should pass.
96. Run command prove t/db_dependent/Reports/Guided.t
97. The Guided report tests were updated to account for the new library limitations and permissions.
98. All tests should pass.

Signoff
99. Sign off if the steps above check out.

Sponsored-by: Ramapo Catskill Library System
Co-authored-by: Casey Conlin <casey.conlin@gmail.com>
Signed-off-by: Emmi Takkinen <emmi.takkinen@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-28 14:32:25 +00:00
Andrii Nugged a445bb0ab3
Bug 42845: Add ILL config endpoint for Vue app
The ILL Vue app currently reads ILLModule and ILLPartnerCode through the system preferences service. That service requires parameters/manage_sysprefs, so a staff user with ILL permissions but without system preference administration permissions cannot load the ILL module.

Add an ILL-specific /ill/config REST endpoint protected by the ill permission, and switch the ILL Vue app to load its configuration from that endpoint. This follows the module-specific configuration endpoint pattern introduced by bug 33606 for the same manage_sysprefs problem in the ERM Vue app.

Security/compatibility considerations: the endpoint returns only allow-listed, non-secret ILL configuration values needed by the ILL Vue app. It does not expose the generic system preferences API, and /api/v1/sysprefs remains restricted to parameters/manage_sysprefs.

Regression test coverage: the new API test verifies that a staff user with the ill permission can read /ill/config, that a staff user without the ill permission cannot read it, and that the same ILL-only user still cannot access /api/v1/sysprefs.

Test plan:

1. prove -I. -It/lib t/db_dependent/api/v1/ill_config.t

2. prove -I. -It/lib t/db_dependent/api/v1/ill_users.t

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

Amended-by: Jonathan Druart
chmod +x t/db_dependent/api/v1/ill_config.t

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:48 +00:00
Emily Lamancusa 769e565890
Bug 38361: (QA follow-up) Set required variable for input validation
Built-in validation checks weren't functioning because the variable
required.sex was not getting set. Ensure that variable gets set, and
remove manual validation code that is no longer needed.

Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:47 +00:00
Bo Gustavsson 9d40cdee7f
Bug 38361: Gender field does not include a Required if the field is set to required in PatronSelfRegistrationBorrowerMandatoryField
Solves this bug and enhances the user experiance by replacing the old radio buttons with a less-confusing dropdown menu.

Test plan:

1. Open the setting "PatronSelfRegistrationBorrowerMandatoryField", find Gender(sex) and mark it as not required.
2. Go to the self registration form. No 'Required' label under gender.
3. Go back to the setting  "PatronSelfRegistrationBorrowerMandatoryField", find Gender(sex) and mark it as required.
4. Go to the self registration form. The 'Required' label is there.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:46 +00:00
Slava Shishkin ac31d8ae25
Bug 41227: Respect SuspendHoldsIntranet on patron holds page
Test plan:
1. Set SuspendHoldsIntranet to "Don't allow"
2. Place a hold for a patron
3. Open the patron holds table
4. Confirm the Suspend button is visible in the Suspend column
5. Apply the patch
6. Reload the patron holds table
7. Confirm the Suspend button is no longer visible
8. Set SuspendHoldsIntranet to "Allow"
9. Reload the patron holds table
10. Confirm the Suspend button is visible again

Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:45 +00:00
Fridolin Somers ea185b6833
Bug 43098: Typo edit_formid in guided_reports_start.tt
Typo in edit SQL when authorised values category is wrong : 'op=edit_formid='

Test plan:

1) Create a new authorised values category WRONG
2) Create a new SQL report with : SELECT * FROM biblio WHERE title LIKE <<val|WRONG>>
3) Save the report
4) Delete authorised values category WRONG
5) Run the SQL report
6) You see message 'The authorized value category (WRONG) you selected does not exist.'
7) Click on 'Edit SQL'
=> You comme back to editing the correct SQL report

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:44 +00:00
Jonathan Druart 34da25f751
Bug 42632: Fix "Manage bundle" after filters are shown/hidden
If "Show/Hide filters" link is clicked, the "Manage bundle" buttons do not longer work.

Test plan:
Edit a record, set leader 7=collection
In the holding list click "Manage bundle"
Click "Show filters"
Click one of the "Manage bundle" button
=> Without this patch nothing happens
=> With this patch applied the table displays the nested table with the
bundle details

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Anni <anni.maki-mantila@turku.fi>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:41 +00:00
Paul Derscheid 15dfbc2f08
Bug 41898: (QA follow-up) Only list uncollected bookings on the pending list
The pending bookings page lists items that have not been collected yet,
but the status filter added when the server-side active pre-filter was
removed included 'issued' bookings, so bookings reappeared on the list
after the item had been checked out.

- restrict the status filter to 'new'

Test plan:
1. Place a booking starting today and open Circulation > Bookings to
   collect; the booking is listed
2. Check the item out to the booking patron; reload the list and
   confirm the booking is gone

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:37 +00:00
Martin Renvoize 91556ada91
Bug 41898: Load additional-filters.js on the circulation page
The rewrite of js/tables/bookings.js in this patchset builds on
AdditionalFilters, which is provided by js/additional-filters.js. The
patron details page loads that asset but the circulation page did not,
so the bookings tab on circ/circulation.pl died with 'AdditionalFilters
is not defined' and the table never initialised.

Test plan:
1) Check out to a patron with bookings and open the Bookings tab on
   the checkout page; confirm the table renders and no JS error is
   logged in the console

Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:36 +00:00
Martin Renvoize bf8237ae54
Bug 41898: Fix callers of bookings API after removing server-side active filter
The bookings REST controller previously applied filter_by_active (status IN
'new','issued') as a server-side pre-filter. Removing that pre-filter means
callers that relied on it must now supply an explicit status filter.

- pendingbookings.tt: add status filter to additional_filters so the
  pending-bookings-to-collect page still shows only new+issued bookings
- place_booking.js: correct status values from the obsolete 'pending','active'
  (never valid in the schema) to the correct 'new','issued'

Test plan:
1. Navigate to Circulation > Bookings to collect.
   - Confirm only bookings with status "New" or "Issued" are listed.
   - Complete a booking (check out then return the item) and confirm it
     disappears from the list.
2. On any biblio with multiple bookings, open the Place booking modal.
   - Create overlapping bookings where one is completed or cancelled.
   - Confirm the modal does not treat completed/cancelled bookings as active
     conflicts when checking availability.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:34 +00:00
Martin Renvoize c7673a9d6a
Bug 41898: Introduce 'issued' status and update booking display/filtering
Implements a 4-state booking lifecycle: new → issued (on checkout) →
completed (on return), plus cancelled at any point.

Backend changes:
- AddIssue sets booking status to 'issued' (was incorrectly 'completed')
- AddReturn transitions 'issued' → 'completed' via booking_id on the issue
- filter_by_active updated to status-based: status IN ('new', 'issued');
  previously it filtered by date range — active/inactive now reflect booking
  lifecycle rather than the current date relative to start/end dates
- _is_final_status_transition reverted to only skip clash detection for
  terminal statuses 'cancelled' and 'completed'; 'issued' is active and does
  not bypass clash detection
- GET /api/v1/bookings no longer pre-filters to active bookings server-side;
  callers must supply an explicit status filter if they need active-only

Display changes:
- Patron bookings tab: replaces the date-based expired/active toggle with
  per-status filters (completed, cancelled) using the AdditionalFilters
  framework; active bookings (new/issued) are shown by default
- Biblio bookings list: same status-based filters; removes the date-based
  expired filter that was still present
- Status column is always visible on both views (was previously hidden on
  the patron tab unless expired bookings were shown)
- Status badges: new=bg-success, issued=bg-info, completed/cancelled=bg-secondary
- Timeline isActive check corrected to ['new','issued']
- patron-detail-tabs.inc: rename expired_bookings_count → closed_bookings_count
  to reflect status-based (not date-based) counting
- Filter button colour fixed to use $link-color so both views are consistent

Test plan:
1. Enable the EnableBookings system preference.
2. Create a biblio with at least one bookable item.
3. Place a booking for a patron via the biblio's Bookings tab.
   - The booking should appear with status badge "New" (green).
4. Check out the booked item to that patron (Circulation → Check out).
   - Reload the Bookings tab; the booking should now show "Issued" (blue).
5. Return the item (Circulation → Check in).
   - Reload the Bookings tab; the booking should now show "Completed" (grey).
6. Place a second booking and cancel it from the Bookings tab Actions menu.
   - The booking should show "Cancelled" (grey), with the reason if provided.
7. On the biblio Bookings tab:
   - Completed and cancelled bookings are hidden by default.
   - Clicking "Include completed" shows completed bookings.
   - Clicking "Include cancelled" shows cancelled bookings.
   - Both can be toggled independently.
   - The Status column is always visible.
8. Navigate to the patron's detail page → Bookings tab.
   - Active bookings (new/issued) are shown by default.
   - Completed and cancelled can be toggled independently using the same
     filter buttons.
   - The Status column is always visible.
9. Confirm via the REST API that GET /api/v1/bookings (no filters) returns
   bookings of all statuses, not just active ones.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:33 +00:00
Lucas Gass 47dd1f1844
Bug 41879: Disallow moves to invalid pickup locations for next available holds
Signed-off-by: Eric Phetteplace <phette23@gmail.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:25 +00:00
Lucas Gass 560efd018b
Bug 41879: Disallow moves to invalid pickup locations for items
To test:

1. Set ReservesControlBranch is set to 'item's home library'
2. Set the deafult 'Holds and bookings policies by item type' for the itype BK to allow holds from patrons from any library, but pickup at CPL only
3. Have a bib owned by another library ( I used MPL ), and bib owned by CPL. Both are the item type BK, and each has one item on the bib.
4. Place a hold for a patron on bib A for pickup at MPL
5. Move the hold to bib B
6. Note that the hold moves successfully, and is still set for pickup at MPL
7. Login and try to trigger the hold, nothing happens
8. APPLY PATCH, restart_all
9. Try spets 3 - 6 again. This time on step 6 you should see a message that the hold cannot be moved.

Signed-off-by: Eric Phetteplace <phette23@gmail.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 15:53:24 +00:00
Paul Derscheid fd3addf35f
Bug 38358: (QA follow-up) Return opened panel from dateChanged
Builds on the panel-detection logic by having dateChanged report which
panel it opens, so onChange can adjust that panel's "To date" picker
directly without waiting on the slide animations to settle.

- dateChanged returns "showHoliday" when editing, "newHoliday" when adding
- onChange maps that to datecancelrange/dateofrange, in place of the
  setTimeout and the :visible check

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:13:07 +00:00
Emmi Takkinen aaa3954c8f
Bug 38358: Do not allow selecting past dates when editing existing holidays "To date" input
When you are editing holidays "To date" inputs calendar doesn't follow the
"From date" date. Instead calendar offers you today's date/month and
you must click calendar forward to the right date/month. This patch
adds check to determine if user is adding new holiday or editing
existing one and adjusts the code to disable past dates counting from
selected "From date" in both cases.

To test:
1. Navigate to calendar tool (Tools->Calendar).
2. Add new holiday and select "To date" for it.
=> Note that you are unable to select dates past from "From date".
3. Edit existing holiday and select "To date" for it.
=> Note that "To date" input calendar allows selecting dates past
"From date".
=> If you chosed holiday from incoming month, note that "To date"
calendar still opens up to this month.
4. Apply this patch, restart services if needed.
5. Edit existing holiday again.
=> Note that now "To date" inputs calendar works the same way as
it is working when your adding a new holiday.

Sponsored-by: Koha-Suomi Oy
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:13:06 +00:00
Matt Blenkinsop a5d12147f6
Bug 43121: Convert all groups to use explicit labels
Test plan:
1) Install another language
2) Navigate to a vendor record
3) The group names should translate correctly and display in the split screen view

Signed-off-by: Michaela <michaela.sieber@kit.edu>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:13:03 +00:00
Matt Blenkinsop 53e9d026ce
Bug 43121: Use an explicit label for group and tab names rather than a translated string
Signed-off-by: Michaela <michaela.sieber@kit.edu>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:13:02 +00:00
Matt Blenkinsop 7b199653ed
Bug 43119: Restore item and hold links to the log viewer
INSERT INTO action_logs (timestamp, user, module, action, object, info, interface) VALUES
    (NOW(), 5, 'CIRCULATION', 'ISSUE', 5,
     '{"issue":1,"branchcode":"CPL","itemnumber":1,"confirmations":["TOO_MANY"],"forced":["DEBT"]}', 'intranet'),
    (NOW(), 5, 'CIRCULATION', 'RETURN', 5,
     '1', 'intranet'),
    (NOW(), 5, 'HOLDS', 'CREATE', 7,
     '{"hold":7,"biblionumber":1,"itemnumber":1,"confirmations":["HIGHHOLDS"],"forced":["HOLD_POLICY_OVERRIDE"]}', 'intranet');

Test plan:
1) Without the patch applied, run the populate SQL above against the kohadev database.
2) Go to Tools > Log viewer
3) Under Modules, select only Circulation - leave the date range empty and click Submit.
4) Observe the ISSUE row's Info column shows the raw JSON payload as plain text, and the RETURN row shows the bare itemnumber "1" as plain text - neither is a clickable link to the item.
5) Go back, select only the Holds module, click Submit, and observe the CREATE row's Info column likewise shows raw JSON with no hold/item links.
6) Apply the patch.
7) Run yarn build && restart_all, then hard refresh the browser.
8) Repeat step 3.
9) Confirm the ISSUE row's Info column now shows a link reading "Item <barcode> CPL" (e.g. Item 3999900000001 CPL) - the branchcode comes from the JSON payload - and clicking it opens the item page. Override information is also displayed correctly
10) Confirm the RETURN row's Info column now shows a link reading "Item <barcode>" (no branchcode) opening the same item's detail page - verifying the bare-itemnumber payload path.
11) Repeat step 5. Confirm the CREATE row now shows "Hold 7 on biblio 1" linking to reserve/request.pl?biblionumber=1, followed by " - Item 1" linking to the item detail page. Override information is also displayed correctly

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:13:00 +00:00
Samuel Sowanick 1254997e69
Bug 42928: Update log viewer action terminology - Return to Check-in
The log viewer results table uses "Return" for "Check-in" actions.

See the terminology list:
https://wiki.koha-community.org/wiki/Terminology#C

Test plan:
1. Check out an item to a patron, then check it back in again.
2. Go to the log view (Tools > Additional tools > Log viewer).
3. Click "Submit".
4. Note that the action column for the results shows "Return".
5. Apply the patch.
6. Refresh the log viewer page.
6. Note that the action column now correctly shows "Check-in".

Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:59 +00:00
Tomás Cohen Arazi 058c476bc7
Bug 42732: Migrate catalogue/detail.tt addToBundle $.post to api-client.js
Replace direct $.post() to /api/v1/items/{id}/bundled_items with
ItemAPIClient.bundled_items.add(), which uses http-client.js and
automatically includes the CSRF token header.

The caller passes return_response: true because it needs access to
the raw response status code and body for fine-grained error handling
(different user-facing messages for 409/already_bundled, 409/checked_out,
409/reserved, 404/not_found, 400/failed_nesting). http-client.js
default behavior throws a plain Error on non-2xx responses, losing
the status code and error_code fields the UI needs.

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:57 +00:00
Tomás Cohen Arazi e2b0883811
Bug 42731: Migrate modal-claims.inc $.post to api-client.js
Replace direct $.post('/api/v1/return_claims', ...) with the new
ClaimAPIClient, which uses http-client.js and automatically includes
the CSRF token header.

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:56 +00:00
Tomás Cohen Arazi f5a1f41d35
Bug 42730: Migrate place_booking.js $.post to api-client.js
Replace direct $.post() and $.ajax() calls to /api/v1/bookings with
the new BookingAPIClient, which uses http-client.js and automatically
includes the CSRF token header.

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:55 +00:00
Pedro Amorim f5e8cdb399
Bug 43139: Sort by ID DESC instead of ID ASC
Test plan:
1) Enable ILLModule
2) Ensure at least 2 ILL requests exist
3) Go to <staff_url>/cgi-bin/koha/ill/home
4) Confirm the most recent ILL request (highest ID) shows first

Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:54 +00:00
Jonathan Druart f2cca7c630
Bug 43110: (bug 28308 follow-up) Disable checkboxes on the detail view
Checkboxes must be disabled on the detail page as we cannot submit the
changes.

Test plan:
1 - Edit a patron, set a value for advance notices, do not check any transports
2 - View the details for the patron:
    http://localhost:8081/cgi-bin/koha/members/moremember.pl?borrowernumber=5
3 - Note the checkboxes are disabled

QA: The logic is a bit weird as messaging_form_inactive is not set if the
pref is off, but the table is not displayed in this case.

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:52 +00:00
Lucas Gass 35bbb013ba
Bug 42166: Check for 008 before adding the date to it
To test:
1. Edit or create a framework that does not require the 008.
2. Make or edit a record in that framework without a 008.
3. Turn on EnableAdvancedCatalogingEditor, and make sure you are using the advanced editor.
4. Go to the record from step 2 and click "Edit as new (duplicate)"
5. The record won't load in the advanced editor.
6. APPLY PATCH
7. Try again, this time the record should load when using "Edit as new (duplicate)".

Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:50 +00:00
Jonathan Druart 96de51c53d
Bug 42981: Prevent toLowerCase to fail when comparing int and string
If stateSave is turned on and one of the option has a value with _id set
to an Integer, toLowerCase is not available and a JS error is raised:
 Uncaught (in promise) TypeError: this._id.toLowerCase is not a function

Test plan:
1.) Admin - table settings: cgi-bin/koha/admin/columns_settings.pl#eholdings|packages
Activate checkbox "Save search state on page change"

2.) Go to ERM : cgi-bin/koha/erm/eholdings/local/packages
And create two packages:
 - One package with My Vendor assigned.
 - One package without a vendor.

3.) Filter the package results list by My Vendor. --> List is filtered to one package

4.) Leave the page, for example by navigating to Agreements.
Return to the Packages list and you will see the issue  (See also attached Screenshot)

=> Without the patch
The package results list becomes unresponsive / hangs after returning to the page.

=> With the patch
The package results list should load and display the filtered results correctly.

Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu>
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:49 +00:00
Tomás Cohen Arazi 5345fbf908
Bug 42489: Add RealTimeHoldsQueueUnallocated syspref
Adds a new system preference to control whether the real-time
holds queue processes only unallocated holds (faster, additive)
or rebuilds the entire queue for the affected biblio (current
behavior, more thorough).

Default is off (preserving current behavior).

Test plan:
1. Apply patch
2. Run:
   $ ktd --shell
  k$ perl installer/data/mysql/updatedatabase.pl
=> SUCCESS: New preference added
3. Verify RealTimeHoldsQueueUnallocated appears in
   Administration > System preferences > Circulation
4. Sign off :-D

Signed-off-by: Alex Carver [Acerock7] <alex@rcls.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:46 +00:00
Martin Renvoize 09642be4db
Bug 40445: (follow-up) Add default cud- op value to cashup selected form
The two-phase cashup workflow added a 'Cashup selected registers' modal
whose form's op hidden input had an empty value, populated at runtime by
JavaScript. xt/find-missing-op-in-forms.t parses templates statically and
flagged the empty op value as not starting with 'cud-' (see bug 34478).

Set a sensible default of 'cud-cashup_start'; the JS click handlers still
overwrite the value before submission, so behaviour is unchanged.

Test plan:
1. prove xt/find-missing-op-in-forms.t => now passes

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:44 +00:00
Martin Renvoize a4ba11af06
Bug 40445: (follow-up) Fix TT in Tag issue
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:43 +00:00
Martin Renvoize c51f4b7cca
Bug 40445: (QA follow-up) Add missing [% USE raw %] in cashup_summary.inc
The cashup summary modal include uses the \$raw filter on
Koha.CSPNonce, but never declared [% USE raw %]. The QA template
tester (which processes templates through a fresh Template::Toolkit
instance) reports "valid_template: filter not found" because the
\$raw plugin is not loaded.

Add [% USE raw %] at the top of the include, matching the convention
used by other includes that emit nonce attributes (e.g.
includes/str/cataloging_additem.inc).

Test plan:
1. Run qa-test-tools against the bug branch -- cashup_summary.inc
   passes valid_template.
2. Open the cashup summary modal -- the <style> tag still receives
   a CSP nonce and the embedded styles render correctly.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:40 +00:00
Martin Renvoize 7798332412
Bug 40445: (follow-up) Show actual cash removed alongside expected on discrepancy
The cashup summary modal labelled the per-payment-type cash row "Cash
removed from register", but the value came from the session
transactions (with CASHUP_SURPLUS/DEFICIT lines excluded), so it
represented the *expected* cash, not the amount actually counted at
cashup. When a deficit or surplus existed, the reconciliation row
appeared as the difference between two figures the user could not
both see.

Render two rows when surplus_total or deficit_total is set on a
completed cashup: "Expected cash total" (from total_grouped) and
"Cash removed from register" (from cash_register_actions.amount,
already exposed as data.amount). The reconciliation row below now
visibly equals the difference. Balanced cashups and the in-progress
preview keep the original single-row display, and the negative-cashup
branch flips the labels to "Expected cash to add to register" /
"Cash added to register".

Test plan:
1. Configure a cash register and record a few cash payments.
2. Trigger a cashup, enter the exact expected amount; open the
   summary modal -- a single "Cash removed from register" row is
   shown matching the expected total.
3. Repeat with an amount lower than expected -- "Expected cash
   total" and "Cash removed from register" both appear, and the
   "Cashup deficit" row is the difference.
4. Repeat with an amount higher than expected -- the actual row
   exceeds the expected row and "Cashup surplus" matches the gap.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:39 +00:00
Martin Renvoize 86d034e628
Bug 40445: (follow-up) Clarify cashup summary cash row wording and sign
A cashup is the process of removing cash from the till to send it
to the bank, so labelling the headline cash line "Cash added to
register" was confusing. Re-word it to "Cash removed from register"
in the typical case and "Cash added to register" in the edge case
where the cashier has had to top up the till to cover refunds.

While doing this, align the sign convention of total_grouped with
that of the overall total field on the summary: positive means cash
collected (i.e. removed from the register at cashup time), negative
means cash had to be added back into the register. Previously
total_grouped used the raw accounting sign (credits negative, debits
positive), so a typical $2 cash session would display "Total: 2.00"
and "Cash added to register: -2.00", which was internally
inconsistent. The conditions on the cash and other-payment-type rows
in cashup_modal.js are swapped to match the new convention.

Test plan:
1. Apply the patch and rebuild JS (yarn js:build) inside KTD.
2. As a staff user with permission to manage cash registers, take
   payments via several payment types (some cash, some not).
3. Trigger a cashup and view the cashup summary modal.
4. Confirm the "Total" line and the per-payment-type lines all
   display as positive amounts in the typical "money was collected"
   scenario, with the cash row labelled "Cash removed from
   register".
5. Issue some refunds large enough to exceed cash collected, then
   cash up again.
6. Confirm the cash row is labelled "Cash added to register" with a
   negative amount and the per-non-cash-type rows are labelled
   "{type} to add" where applicable.
7. Run prove t/db_dependent/Koha/Cash/Register/Cashup.t and prove
   t/db_dependent/Koha/Cash/Register.t inside KTD; both should
   pass.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:38 +00:00
Martin Renvoize 463b92df52
Bug 40445: (QA follow-up) Add nonce, POD, and test isolation
This patch resolves three QA findings on the cashup reconciliation
work:

* Add a CSP nonce to the inline <style> block in cashup_summary.inc
  so it is not flagged by the forbidden_patterns check.
* Document the private _get_session_end method on
  Koha::Cash::Register::Cashup so pod_coverage passes.
* Mock CashupReconciliationNoteRequired to 0 in
  t/db_dependent/Koha/Cash/Register/Cashup.t so the test does not
  depend on the site preference value (it previously failed when
  the syspref was set to "Require" because surpluses and deficits
  are created without a reconciliation note in this test).

Test plan:
1. Apply the patch.
2. Set CashupReconciliationNoteRequired to "Require".
3. Run prove t/db_dependent/Koha/Cash/Register/Cashup.t -- it should
   pass.
4. Set CashupReconciliationNoteRequired to "Don't require" and
   re-run -- it should still pass.
5. Run koha-qa.pl on the bug branch -- pod_coverage on
   Koha/Cash/Register/Cashup.pm and forbidden_patterns on
   cashup_summary.inc should now pass.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:37 +00:00
Martin Renvoize b7a68f1f49
Bug 40445: Add configuration options and UI enhancements
This patch adds configuration options for cashup reconciliation and
enhances the user interface with preview functionality and improved
interaction patterns.

Configuration Options:

1. CashupReconciliationNoteRequired (System Preference):
   - Optional validation requiring reconciliation notes when discrepancies exist
   - Ensures documentation of surplus/deficit causes when needed
   - Can be disabled for less stringent workflows
   - Applied at cashup completion time

2. CashupReconciliationNoteAuthorisedValue (System Preference):
   - Allows use of authorized value dropdown for reconciliation notes
   - Provides standardized note options (e.g., "Till count error", "Cash removed")
   - Falls back to free text textarea when not configured
   - Improves consistency and reporting capabilities

UI Enhancements:

1. Cashup Summary Preview:
   - Preview cashup summary for in-progress cashups
   - Shows current transaction totals before completion
   - Clearly indicates preview vs. final summary status
   - Helps staff verify amounts before committing

2. Improved User Experience:
   - Conditional note fields based on configuration
   - Authorized value dropdowns when configured
   - Clear validation messages
   - Responsive UI updates

Backend changes:
- Enhanced Koha::REST::V1::CashRegisters::Cashups with preview support
- Database atomicupdate script for system preferences
- Validation logic for required notes

Frontend changes:
- Preview modal functionality in cashup_modal.js
- Conditional rendering of note input fields
- Authorized value dropdown integration
- Enhanced summary display logic

Test plan:
1. Apply patches and run database update
2. Configure CashupReconciliationNoteRequired:
   - Enable preference
   - Perform cashup with discrepancy without note - should fail
   - Add note and retry - should succeed
   - Disable preference - verify note optional
3. Configure CashupReconciliationNoteAuthorisedValue:
   - Create AV category (e.g., CASHUP_NOTE) with values
   - Set preference to category name
   - Verify dropdown appears in cashup modal
   - Clear preference - verify textarea shown
4. Test cashup preview:
   - Start cashup on register
   - Click "Preview cashup summary"
   - Verify current totals displayed
   - Add transaction and re-preview - verify updated
   - Complete cashup - verify final summary

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:36 +00:00
Martin Renvoize 9db47a47c1
Bug 40445: Implement optional two-phase cashup workflow
This patch implements an optional two-phase cashup workflow for point
of sale operations, along with improved error handling and validation.

Two-Phase Cashup Workflow:
- Staff can initiate cashup (CASHUP_START) and complete later
- Prevents new transactions on registers with cashups in progress
- Tracks cashup sessions with start/end timestamps
- Supports both quick cashup (immediate) and staged cashup workflows
- Updates batch cashup workflow operations across multiple registers

Error Handling & Validation:
- Centralized exception handling for cashup operations
- Clear validation messages for missing parameters
- Prevents cashup when no cash transactions exist
- Improved handling of zero/negative amounts
- Informative error messages for user guidance

Negative Amount Support:
- Supports negative cashup amounts for cashup deficits
- Automatic detection when actual cash is less than expected amount
- Creates appropriate CASHUP_DEFICIT records
- UI handles both positive and negative reconciliation amounts
- Updated calculations and display logic throughout

Modal Refactoring:
- Eliminates code duplication between register.tt and registers.tt
- Centralized cashup modal functionality in cashup_modals.js
- Shared confirm_cashup.inc and trigger_cashup.inc templates
- Consistent user experience across all cashup workflows
- Improved maintainability and code organization

Backend changes (Koha::Cash::Register):
- start_cashup(): Creates CASHUP_START action to begin session
- cashup_in_progress(): Detects active cashup sessions
- add_cashup(): Enhanced with two-phase completion support
- outstanding_accountlines(): Respects cashup session boundaries

Frontend changes:
- Interactive modals for starting and completing cashups
- Real-time calculation displays
- Support for reconciliation with actual amounts
- Batch operations UI for multiple registers
- Responsive error messaging and validation feedback

Test plan:
1. Apply patches and restart services
2. Run prove t/db_dependent/Koha/Cash/Register.t
3. Run prove t/db_dependent/Koha/Cash/Register/Cashup.t
4. Test single register workflows:
   - Start cashup, add transactions, verify blocked
   - Complete cashup with reconciliation amounts
   - Test with positive, negative, and zero amounts
5. Test multi-register workflows:
   - Select multiple registers on registers page
   - Perform batch cashup operations
   - Verify each register processes correctly
6. Test error conditions:
   - Attempt cashup with no transactions
   - Attempt cashup with invalid amounts
   - Verify clear error messages displayed

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:35 +00:00
Martin Renvoize 6d5c2f463f
Bug 40445: Add cashup reconciliation functionality
Implements cashup reconciliation allowing staff to record actual cash
amounts and track surplus/deficit discrepancies.

Backend changes:
- Enhanced add_cashup() to accept actual_amount and optional notes
- Automatic CASHUP_SURPLUS/DEFICIT accountline creation for discrepancies
- Transaction handling ensures atomicity of cashup and reconciliation
- outstanding_accountlines() excludes reconciliation entries

Frontend changes:
- Interactive modal requiring actual amount entry
- Real-time surplus/deficit calculation
- Conditional note field for discrepancies (1000 char limit)
- Enhanced summary modal displays reconciliation details
- Full audit trail with timestamps and manager links

Test plan:
1. Apply all patches and restart services
2. Run prove t/db_dependent/Koha/Cash/Register.t
3. Create test transactions on a register
4. Perform cashup with balanced amount - verify no reconciliation accountlines
5. Perform cashup with surplus - verify CASHUP_SURPLUS credit created
6. Perform cashup with deficit - verify CASHUP_DEFICIT debit created
7. Add notes to reconciliation - verify stored correctly
8. Start new cashup - verify previous reconciliation excluded from outstanding
9. View cashup summary - verify reconciliation displayed prominently

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-27 12:12:34 +00:00
Owen Leonard 8bc90cbb5e
Bug 42440: Remove event attributes from labeled MARC detail template
This patch removes a redundant "onchange" event attribute from the
framework selection dropdown. This event is already registered in the JS
block.

The patch also does a little bit of cleanup to the JS: Combining two
<script> tags which don't need to be separate and moving a function
outside of the $(document).ready block.

To test, apply the patch and search for a bibliographic record in the
catalog.

- From the detail page, click the "Labeled MARC" tag in the sidebar (you
  may need to enable the "viewLabeledMARC" preference).
- Try changing the "With framework" selection. The page should reload
  with the selected framework.

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: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 12:44:51 +00:00
Emmi Takkinen ed992358bf
Bug 36762: Allow to ignore hold when creating a transfer
When one tries to transfer an item that could fill a pending hold
to a library that is not the holds pickup library, Koha gives only
a option to transfer item to pickup library. This patch adds
new option to ignore hold and transfer item to the library user
selected in transfer tool.

To test:
1. Log into Library A.
2. Find or create a biblio with 1 holdable item at Library A.
3. Place a hold for the biblio with pickup at Library B.
4. Navigate to Circulation > Transfers.
5. Attempt to transfer item to Library C.
=> Note that Koha only allows to transfer item to Library B,
cancel hold and attempt transfer or return to the transfer tool.
6. Apply this patch.
7. Attempt to transfer item again.
=> Note that there is now an option to ignore the hold and transfer
item to Library C.
=> When option to transfer item to the Library C is selected, confirm
that Koha tells that transfer was made to Library C and a new transfer
was made to database.

Sponsored-by: Koha-Suomi Oy
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 12:44:49 +00:00
Martin Renvoize 3abe3f1485
Bug 40206: (QA follow-up) Fix JS error and misleading message on disabled curbside pickups page
The early-exit added for the CurbsidePickup syspref check left
policy/curbside_pickups unset, but intranet-bottom.inc's jsinclude
still referenced them unconditionally, causing a client-side
TypeError on every render of the disabled state. Guard the whole
jsinclude block with disabled_for_branch.

Also distinguish the two reasons the page can be disabled: the
CurbsidePickup syspref being off globally vs. this branch simply
not having an enabled curbside pickup policy configured. The
message and link now point staff to the correct admin page for
each case, instead of always suggesting the syspref (which may
already be on).

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 12:44:47 +00:00
Tomas Cohen Arazi c68bacc5c2
Bug 40206: Fix wrong layout in curbside pickups when 'CircSidebar' enabled
This patch solves the following issues:

* Template flow issue: the template called STOP which prevented the
  WRAPPER to complete and affected how things were rendered.
* Redirect to 404 if feature disabled. This is common practice in other
  modules. The fact things can be executed even with the feature
  disabled is not ok (syspref).
* Shortcircuit earlier. Similar to the above, if the feature is
  disabled for the current branch, no DB queries and stuff should take
  place. Notice the lack of checks actually makes the controller perform
  the actions. It is just that it is not displayed afterwards!

To test:
1. Enable the `CurbsidePickup` syspref.
2. 'Activate' the `CircSidebar` syspref.
3. Be on a branch that doesn't have them enabled
4. Go to Circulation > Check in
   => SUCCESS: A nice left-hand sidebar is displayed with access to
      Circulation actions
5. Click on 'Curbside pickups'
   => FAIL: The sidebar doesn't display. boo!
6. Apply this patch
7. Restart plack
   $ ktd --shell
   $ koha-plack --restart kohadev
8. Repeat 4
   => SUCCESS: It renders much better!
9. Sign off :-D

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 12:44:43 +00:00
Pedro Amorim 2f227048ae
Bug 42280: (RM follow-up) Tidy categories.tt
Leftover untidy JS from bug 26355 (multi-line jQuery .on() calls,
missing semicolon) in the clone/clear message handlers.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:16:04 +00:00
Jan Kissig a4a53ea03c
Bug 42280: (QA follow-up) Split JS in uage_statistics to TT and non TT block. Auto tidy
This splits remaining JS into a block with and without TT interpolation. Auto tidy

Small changes on add_to_map() call:

To test:
a) go to Administration -> Shar eyour usage statistics
b) in dev console check Koha.prefs.UsageStatsGeolocation is [] when no coordinates are set
c) add some coordinates to main library (first Geolocation input field) and others
d) check that Main and other libraries are drwan on the map when reentering usage statistics page
e) No console errors should be shown

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:16:03 +00:00
Jan Kissig 8de6874de5
Bug 42280: (QA follow-up) Split JS in transfer_limits to TT and non TT block. Auto tidy
This splits remaining JS into a block with and without TT interpolation. Auto tidy

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:16:02 +00:00
Jan Kissig 5ce434644c
Bug 42280: (QA follow-up) Split JS in restrictions to TT and non TT block. Auto tidy
This splits remaining JS into a block with and without TT interpolation. Auto tidy

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:16:01 +00:00
Jan Kissig 1987d0a930
Bug 42280: (QA follow-up) Split JS in preferences to TT and non TT block. Auto tidy
This splits remaining JS into a block with and without TT interpolation. Auto tidy

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:16:00 +00:00
Jan Kissig 1153112951
Bug 42280: (QA follow-up) Split JS in matching-rules to TT and non TT block. Auto tidy
This splits remaining JS into a block with and without TT interpolation. Auto tidy

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:15:59 +00:00
Jan Kissig c2f1576a3d
Bug 42280: (QA follow-up) Split JS in curbside_pickup to TT and non TT block. Auto tidy
This splits remaining JS into a block with and without TT interpolation. Auto tidy

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:15:58 +00:00
Jonathan Druart f52abf6d79
Bug 42280: Tidy all script tags - admin (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:15:57 +00:00
Jonathan Druart 70bb50988b
Bug 42280: Tidy all script tags - admin
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the administration module.

The 2 main changes are in the following files:
* aqplan.tt
"0" should be correctly formatted
* categories.tt
trivial change about table settings

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:15:56 +00:00
Jonathan Druart 0de23cde12
Bug 42291: Prevent XSS
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:15:54 +00:00
Jan Kissig d194215dfe
Bug 42291: (follow-up) Move remaining JS to non TT script block
This removes all TT interpolations from the build_dropdown function and moves it to the non TT script block.

To test:
a) create several private or public lists via /cgi-bin/koha/virtualshelves/shelves.pl
b) either the number of private or public list should be > 10 to
c) add some items to a list
d) on this lists content site click 'Add to' to open drop down menu
e) the menu should offer up to 10 private or 10 public list options and a [ more lists ] option

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:15:53 +00:00
Jonathan Druart 56036ac098
Bug 42291: Tidy all script tags - shelves (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:15:52 +00:00
Jonathan Druart f73b0db9ae
Bug 42291: Tidy all script tags - shelves
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the virtual shelves module.

Trivial changes, the existing JS variables are moved in a separate
script tag.
We could have gone further with the list of shelves (the build_dropdown
function) , but that's for another day...

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:15:51 +00:00
Jonathan Druart 9ac2f291b3
Bug 41061: Remove unused calendar JS functions
Since the introduction of Maskito by bug 33703 we do no longer need to
valid dates when the flatpickr widget is closed.

This patch removes the following JS function from staff and OPAC:
* is_valid_date
* validate_date
* get_dateformat_str

Test plan:
0. Do not apply this patch and confirm that the date string received by
   those functions has already been correctly formatted
1. Apply the patch and git grep to make sure no occurrence exists in the
   code
2. Confirm that you are still able to select dates with flatpickr

Signed-off-by: Emmi Takkinen <emmi.takkinen@koha-suomi.fi>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-20 09:15:50 +00:00
Lucas Gass 1265f90523
Bug 43005: Remove messaging preferences check
1. Go to Patron record -> Details
2. Under "Library use" click 'Edit'
3. From here change the patron category, no pop-up
4. APPLY PATCH and try again
5. Now you should see the pop-up modal

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:20 +00:00
Martin Renvoize 77fc25f184
Bug 42915: (QA follow-up) Remove unused filters_options variable
filters_options was introduced with the coded_values library filtering
patch but never referenced anywhere in the file.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:18 +00:00
Martin Renvoize 1cf8f9ffc5
Bug 42915: (QA follow-up) Restore fallback message for holds with no patron data
The "Add patron names to data in column def in holds table" patch
dropped the null-patron handling in the patron column's render
function, so a hold row whose patron embed comes back null (e.g. a
user without permission to view the patron on that hold, per Bug
23269's test plan) now renders a blank cell instead of a useful
message.

Restore the fallback, sourced from `all_libraries` (populated by this
same table's include) rather than the separate `libraries` global,
and check `row.patron` directly instead of the now-composite `data`
column key.

To test:
1. Have holds on a bib from patrons the logged in user cannot see
   (e.g. IndependentBranches, or a reduced permission set)
2. View the record's Holds tab
3. Confirm rows with no visible patron show "A patron from library
   <library>" instead of a blank Patron cell

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:17 +00:00
Martin Renvoize e2685f88c9
Bug 42915: (QA follow-up) Declare all_libraries once, unconditionally, in request.tt
holds_table.inc is INCLUDEd in a loop from reserve/request.tt whenever
HoldsSplitQueue splits the holds queue by branch/itemtype, or when
holds for more than one biblio are shown at once (multi_hold). Each
inclusion appended its own <script> block declaring `all_libraries`,
and since top-level `let`/`const` in separate inline <script> tags
share the page's global lexical scope, the second and subsequent
occurrences threw "Identifier 'all_libraries' has already been
declared", breaking those script blocks and the pickup-library
filtering that depends on `all_libraries` being set.

Worse, that script block is only emitted when a biblio's holds are
actually rendered (biblioloo.total_holds > 0), but holds.js is loaded
unconditionally by reserve/request.tt and reads `all_libraries` at
top-level parse time. Placing the very first hold on a title (0
existing holds) therefore threw:

    ReferenceError: all_libraries is not defined

breaking every hold-management handler defined below that line in
holds.js.

Fix both by declaring `all_libraries` exactly once, unconditionally,
in request.tt's existing page-global script block (alongside the
other unconditional globals such as HidePatronName and
HoldsSplitQueue), before Asset.js("js/holds.js") loads, instead of
duplicating it inside the per-title/per-split holds_table.inc
include.

To test:
1. Search for a title with no existing holds and start placing one
2. Without this patch: browser console shows "ReferenceError:
   all_libraries is not defined" as soon as the page loads
3. With this patch: no console errors
4. Set HoldsSplitQueue to "pickup library", place holds on a title
   for two different pickup libraries, confirm both split tables
   render with working patron-name and pickup-library filtering and
   no console errors
5. Confirm the patron's own Holds tab (moremember.pl/circulation.pl)
   still loads without console errors

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:15 +00:00
Brendan Lawlor 6532c4660a
Bug 42915: (follow-up) Fix holds table display on patron record holds tab
To test:
1. Have a patron with multiple holds
2. Go to the patron record's hold tab
3. Confirm the table loads and no errors are logged to the console

Sponsored-by: CLAMS
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:15 +00:00
Brendan Lawlor e4af8e73f3
Bug 42915: Add patron names to data in column def in holds table
This patch adds the patron firstname and surname to the searchable
data in the patron column definition for the holds table and
removes unnecessary code from the render function.
This enables searching holds by patron names.

To test:
1. Have holds on a bib for different patrons and pickup locations
2. Try filtering by a patron name
3. See 'No matching records found'
4. Apply patch and repeat step 2
5. Filtering by patron name works!
6. Confirm filtering by cardnumber still works too
7. Set system preference HidePatronName to 'Don't show'
8. Confirm searching by patron names doesn't work ;)

Sponsored-by: CLAMS
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:13 +00:00
Brendan Lawlor e4a9f1f531
Bug 42915: Use coded value for library filtering in holds table
This patch adds coded_values for libraries to the holds table
and sets the data type in the pickup library column definition.
This enables searching holds by pickup location.

1. Have holds on a bib for different patrons and pickup locations
2. Try filtering by a pickup library name or branchcode
3. See 'No matching records found'
4. Apply patch and repeat step 2
5. Filtering works!
6. Note: if two libraries share the same beginning text
    both results are returned :)
    For example: 'Fair' returns holds for pickup at Fairview and Fairfield

Sponsored-by: CLAMS
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:12 +00:00
Tomás Cohen Arazi 5b3baf4170
Bug 41084: Add EnableZotero system preference
This system preference will be used to enable opac-export.pl?format=utf8
regardless of the OpacExportOptions values, specifically for Zotero
integration support.

Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:07 +00:00
Martin Renvoize 393c9478a0
Bug 42799: (QA follow-up) Close scroll listener leak in apply_sticky
apply_sticky is invoked from a watch() in Toolbar.vue every time the
toolbar element (re)mounts. The scroll listener it registers was never
removed, so long-lived SPA modules (ERM, ILL, Acquisitions,
Preservation, SIP2) that mount/unmount this Toolbar as the user
navigates between records leaked another window-level scroll listener
on every remount.

An IntersectionObserver + sentinel node was tried instead, since it's
the standard technique and doesn't poll on every scroll frame, but
verified against KTD/Cypress it fails
t/cypress/integration/Toolbar_spec.ts consistently: the observer's
callback fires once on attach and never fires again after
cy.scrollTo("bottom"), even though the sentinel is confirmed (via
instrumentation) to have scrolled fully out of the viewport. The
scroll-listener approach passes the same spec reliably across repeated
runs. So the scroll listener stays; apply_sticky now returns a
disconnect() callback and Toolbar.vue calls it before re-applying and
on unmount, closing the leak without touching detection behaviour.

Test plan:
1. Rebuild assets (yarn build) and confirm:
     yarn cypress run --spec t/cypress/integration/Toolbar_spec.ts
   passes consistently across several runs.
2. Manually confirm sticky toolbars in ERM, Acquisitions (vendors),
   ILL, Preservation and SIP2 still float correctly on scroll, and that
   navigating between several records doesn't accumulate extra "scroll"
   listeners on window (DevTools -> getEventListeners(window)).

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:05 +00:00
Jonathan Druart 35d4eebbb0
Bug 42799: Replace IntersectionObserver with scroll listener for sticky behaviour
Assisted-by: Mistral Vibe <vibe@mistral.ai>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:04 +00:00
Jonathan Druart 74b820394d
Bug 42799: Fix sticky behavior by using a sentinel node
Highlighted by the Cypress upgrade (bug 42772): the sticky element is always
visible and IntersectionObserver rely on the visibility of the element.

Cypress test Toolbar_spec.ts use scrollTo("bottom") to test the
behaviour of the sticky toolbar. We test that the "floating" class is
correctly added to the element. To do that we rely on
IntersectionObserver that will check the visibility of the element. But
the sticky element is always visible.
I actually do not recreate the problem when using the UI but the current
code may be broken in some browsers (or new/future versions).

To fix this problem we insert a new "sentinel" element into the DOM and
rely on its visibility to toggle the "floating" class.

Test plan:
Confirm that the sticky toolbar behaviour is the same after this patch
is applied, ie. that the "floating" class is added when we scroll down.

On top of bug 42772 confirm that the following command passes (run it
several times):
  yarn cypress run --spec t/cypress/integration/Toolbar_spec.ts

QA: Note that the apply_sticky function takes only one node in
parameter, that's why it has been renamed nodes => node

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-17 13:49:03 +00:00
Jan Kissig 41cfe9de0c
Bug 42874: Fix missing index param on z3950_auth_search
This patch will enable the forwarding of index param in all z3950_auth_search forms to keep the reference which auth field to fill in addbiblio.

Testplan:
a) edit f.e. 262: /cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=262
b) go to tab 7 and create a new 700 field (icon next to ADDED ENTRY--PERSONAL NAME)
c) click on the icon next to Personal name input field to open Authority search *
d) click create new authority (Adding authority Personal Name) *
e) click Z39.50/SRU search *
f) search an author f.e. Name (any): Dalei
g) on the result list every 'Import' button still has index (via hovering the import button) - but do not click import yet.
h) click on 'Go' to page 1 - see result list again. The 'Import' buttons do not have index param anymore
i) close that search window and go back to page 'Adding authority Personal Name'
j) click Z39.50/SRU search again *
k) search again for an author f.e. Name (any): Dalei
l) click 'Try another search'
m) check that new URL does not have index param anymore
n) search again - the results will not have an index param

Any imported authority will not be set/linked in the biblio that was initially edited.

p) apply patch and redo steps a) - n)
q) Import an author either via a 'Try another search' or via a result on a different page ('Go' button)
r) save authority
s) check that authority is added in your biblio in field 700.

* check that the URL in the popup window has a param like &index=tag_700_subfield_a_13631_9534947903 as this is the reference to the authority you want to add in the biblio.

Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 17:05:20 +00:00
Jonathan Druart e87732a1b6
Bug 42933: Reinstate license.status as a required field
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 17:05:17 +00:00
Nick Clemens 59ac731b1d
Bug 43043: Pass logged in branchcode to OpacMySummaryNote
This patch uses the logged in branchcode to find the correct entries

To test:
1 - Create two new HTML customizations - OpacMySummaryNote - one for all libraries, one for a specific library
2 - Log in to opac as a user from the specific library
3 - Only see the all libaries note
4 - Apply patch
5 - Reload
6 - See both of the notes as expected!
7 - Sign off!

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 17:05:14 +00:00
Baptiste Wojtkowski cb534eb7d3
Bug 8127: Fix filters use in 'Most-circulated items report'
Filters are broken for many reasons. Previous patch contains some
(little) tidying.
There are 3 parts in this patch:
1 - The column name is incorrectly named in the dropdown for "branch",
  it is added in this patch
2 - There is a definition for 'Day' and 'Month', but not for 'Week', it
is also added in this patch
3 - Dbh variables are passed in the string definition AND in the call. I
removed them from the string definition since it violates the coding
guidelines.

Test plan:

1. On an fresh ktd db, run the script provided here (https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=8127#c3)  to fill the database with checkins/checkouts:

Visit http://your_koha:8081/cgi-bin/koha/reports/cat_issues_top.pl
2. Run a baseline test with following params:
Checkout date from 01/01/2020
Checkout date to: tomorrow
Library: Any library
Fill nothing else

Notice it is works

3. Test with some limits (Library, Week, and any other), notice you encounter errors on Library and Week, and that any other is empty, without error.

4. Apply patch
5. Rerun 2-3 and notice you now have results. Check with each possible limit, limiting to 5. Test once with 10 as a limit.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 17:05:12 +00:00
Lucas Gass c997f83cdf
Bug 43001: Restore non-priority hold text to reserve/request.pl
To test:

1. Place a item level hold, making sure to mark it as "Non priority hold"
2. After placing the hold, on reserve/request.pl look at the "Details" column
3. Notice the hold is missing "Non priority hold" text in the details column
4. APPLY PATCH
5. Look again at reserve/request.pl and now the "Non priority hold" text should be restored to 'Details column'

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 17:05:09 +00:00
Martin Renvoize 5a7c328475
Bug 42868: (follow-up) Fix stale comment referencing removed UTC boundary logic
The comment above the day-boundary calculation still described the
previous dayjs.utc() approach, which was replaced by dayjs.tz() in the
parent commit. Update it to describe the current behaviour so it
doesn't mislead future maintainers into re-introducing the timezone
shift bug this patch fixed.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 17:05:07 +00:00
Lucas Gass 084660a6df
Bug 42868: Use local timezone instead of UTC when calculating start and end dates
To test:
1 - Edit koha-conf.xml
2 - Set timezone:
    <timezone>America/New_York</timezone>
3 - In Koha, enable bookings syspref
4 - Find a record, click the items tab, make an item bookable
5 - Place new booking, choose a date range
6 - View the bookings tab - note the booking extends into the date before
7- Check the DB, the start_date and end_date are wrong
8. APPLY PATCH, restart_all, clear browsewr cache
9. Place a new booking.
10. MariaDB [koha_kohadev]> select * from bookings WHERE booking_id={new booking}
11. Notice the start time should be {start_date} 00:00:00 and the end time should be {end_date} 23:59:59

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 17:05:06 +00:00
Pedro Amorim 43b74cba6e
Bug 42617: (41512 follow-up) Remove ownPagination and fix recordsFiltered propagation
ownPagination set recordsFiltered on json.data instead of json, causing
DataTables to display "NaN total entries". Remove the artificial 5000
mechanism, propagate real counts from plugins that provide them, and
fall back to actual result counts for those that don't. Also removes a
dead drawCallback overwritten before it could fire.

Test plan:
1) Install this test version of the unpaywall plugin:
https://github.com/openfifth/koha-plugin-ill-avail-unpaywall/releases/tag/test
2) Enable ILLModule and ILLCheckAvailability
3) Configure the plugin and add any emaill address
4) Create a new ILL request:
<staff_url>/cgi-bin/koha/ill/ill-requests.pl?method=create&backend=Standard
5) Enter '42' for cardnumber, any library, and any DOI e.g. '123'.
6) Verify that pagination works as expected

Before patch, pagination controls dont show and the following label is shown:
No entries to show (filtered from NaN total entries)

Signed-off-by: Edith Speller <Edith.Speller@ukhsa.gov.uk>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:30 +00:00
Samuel Sowanick 4fd2721f9d
Bug 42519: Terminology - Update 'branch' to 'library' in patron categories
The default message in the "Self-renewal failure message" field
(Administration > Patrons and circulation > Patron categories >
 Account expiry and self-renewal) uses incorrect terminology.

Test plan:
1. Go to Administration > Patrons and circulation > Patron categories.
2. Click on a patron category.
3. Scroll down to the "Self-renewal failure message" field (in the
   Account expiry and self-renewal section).
4. Note the text says "...your local branch...".
5. Apply the patch.
6. Reload the page.
7. Note that the text now says "...your library...".

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:29 +00:00
Martin Renvoize fe8f079121
Bug 41819: (follow-up) Reject 'AC' refunds for anonymous transactions server-side
The previous patch hides the 'Account credit' option in the refund modal
when the accountline has no borrowernumber, but that is a UI convenience
only. A crafted POST (or a stale page) could still submit
refund_type=AC against an anonymous accountline, which would create a
REFUND credit with no patron to attach it to and leave the register
unbalanced because the payout branch is skipped.

Add a server-side guard in pos/register.pl that refuses the operation
and surfaces a new error_refund_anonymous_ac flag, rendered in
pos/register.tt in the same style as the other refund errors.

Test plan:
1. Apply the patch
2. Log in as a user with cash_management/anonymous_refund permission
3. Record an anonymous sale against a register
4. Using the browser devtools (or curl), POST to pos/register.pl with
   op=cud-refund, refund_type=AC and the accountline id of the sale
5. => Confirm the request is rejected and the
   "Account credit refunds are not available for anonymous transactions"
   message is shown
6. => Confirm no REFUND accountline was created and the register
   balance is unchanged
7. Repeat the POST with refund_type=CASH (or any non-AC type) and
   confirm the refund + payout are created normally

Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:27 +00:00
Martin Renvoize b236c67e4a
Bug 41819: POS refunds with 'AC' type incorrectly create PAYOUT accountlines
When processing a refund through the POS register with refund type 'AC'
(Account Credit), the system was incorrectly creating both a REFUND credit
and a PAYOUT debit with payment_type = 'AC'.

When 'AC' is selected, the refund should remain as a credit on the patron's
account without creating a payout. This behavior was already correct in the
member account refund workflow (members/boraccount.pl) but was missing
from the POS refund workflow.

This patch:
1. Adds the same check to pos/register.pl that exists in members/boraccount.pl
   to skip payout creation when refund_type is 'AC', making both workflows
   consistent.

2. Fixes the JavaScript in register.tt to properly hide the 'AC' option for
   anonymous transactions. The original check only tested for empty string,
   but borrowernumber can be undefined/null, which needs to be handled.

Test plan:
Part 1: Test patron transaction refund with Account Credit (AC)
1. Find or create a test patron
2. On the patron's Accounting tab, manually add a charge (e.g., Manual fee)
3. Pay the fee off from the patron's Accounting tab
4. Navigate to Point of Sale > Transaction History
5. Find the payment transaction you just created
6. Click "Issue refund" on the payment line item
7. Verify that "Account credit" appears as an option in the "Transaction type"
   dropdown
8. Select "Account credit" as the transaction type
9. Enter the refund amount and click "Confirm"
10. Navigate back to the patron's Accounting tab
11. Verify that a REFUND credit appears on their account
12. Verify that NO PAYOUT debit was created
13. Verify the credit remains on the patron's account (positive balance)

Part 2: Test patron transaction refund with Cash payout
16. Using the same patron, create another manual fee and payment
17. Navigate to Point of Sale > Transaction History
18. Click "Issue refund" on the new payment
19. Select "Cash" (or another payment type) as the transaction type
20. Enter the refund amount and click "Confirm"
21. Navigate back to the patron's Accounting tab
22. Verify both a REFUND credit and a PAYOUT debit appear
23. Verify the PAYOUT has the correct payment_type (e.g., CASH)

Part 3: Test anonymous transaction (no Account Credit option)
24. Navigate to Point of Sale
25. Add an item to sell and complete the payment
27. Navigate to Point of Sale > Transaction History
28. Find the anonymous payment you just created
29. Click "Issue refund" on the payment line item
30. Verify that "Account credit" does NOT appear in the "Transaction type"
   dropdown (only payment types like Cash, Check, etc. should appear)
31. This confirms anonymous transactions cannot have account credits since
    there's no patron account to credit

Expected results:
- Patron transactions show "Account credit" option in refund dropdown
- Anonymous transactions do NOT show "Account credit" option
- AC refunds create only REFUND credit (no PAYOUT debit)
- Non-AC refunds create both REFUND credit and PAYOUT debit
- Run: prove t/db_dependent/Koha/Cash/Register/Cashup.t

Signed-off-by: Laura Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:26 +00:00
Jason Robb e110ef135c
Bug 43046: Checkbox labels in Currencies and EDI accounts have unnecessary colons
Removes unnecessary colons when adding currencies and edi accounts.

1. Enable EDIFACT syspref
2. Navigate to Admin > Currencies.. > New currency
3. Note unnecessary colons after checkbox labels
4. Navigate to Admin > EDI accounts > New account
5. Note unnecessary colons after checkbox labels
6. Apply patch
7. Repeat steps 2 and 4, note colons have been removed

Signed-off-by: Kris Becker <kbecker@jcls.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:25 +00:00
Phil Ringnalda b1b12578e0
Bug 42920: Looking up authority records in Advanced editor shouldn't append spaces
The patch for bug 21453 replaced an Advanced editor-specific (in the "[% IF rancor %]" block) "[%- END -%]‡9[% authid | html %]";" which trims whitespace with several lines of  "[% ... %]" which do not trim whitespace. The result is that when you look up an authority from the Advanced editor, you get extra whitespace between the last subfield from the authority record and the $9 field with the authority id.

Test plan:
 1. Without the patch, set the preference EnableAdvancedCatalogingEditor to Enable
 2. Cataloging - Advanced editor
 3. Click in any line of the editor and press Return to get a blank line
 4. Type 655 and press Tab three times
 5. Type Ctrl+Shift+L to open the authority search popup
 6. Click Search (no need for search terms) and click Choose for any record
 7. Note that the editor shows twenty blank spaces between the end of the subfield a
    contents and the ‡9
 8. Apply patch
 9. Repeat steps 3-6, note that now there is no extra space between the end of the
    content and the ‡9

Sponsored-by: Chetco Community Public Library
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:23 +00:00
Martin Renvoize 04381f6aba
Bug 41358: Apply consistent JSON logging to holds (Bug 40866)
Bug 40866 introduced JSON logging for HOLDS CREATE but stored null for
'confirmations' and 'forced' when no overrides were present. This patch
mirrors the earlier change to CIRCULATION ISSUE by defaulting them to
empty arrays, keeping the two log streams structurally identical and
simplifying reporting queries.

Changes:

C4/Reserves.pm:
- Default confirmations/forced to [] in the AddReserve log payload.

t/db_dependent/Reserves.t:
- Update the Bug 40866 subtest to assert the empty-array defaults on
  normal holds, and fix a 'my $log_data' redeclaration.

tools/viewlog.pl:
- Extend the CSV export JSON-decode block to also cover HOLDS logs,
  guarding the item lookup on itemnumber being present (HOLDS payloads
  may lack one) and filling the CSV item columns from the decoded
  payload. The legacy bare-itemnumber fallback is restricted to
  CIRCULATION so a legacy HOLDS hold_id is not mistaken for an
  itemnumber.

koha-tmpl/intranet-tmpl/prog/js/viewlog.js:
- Extend the info column override rendering (renderCircInfo) to HOLDS
  entries so forced/confirmations arrays display translated, exactly as
  they do for CIRCULATION. The log viewer moved to an ajax datatable in
  bug 29016, so this replaces the earlier json_found change to
  viewlog.pl/viewlog.tt.

misc/maintenance/migrate_action_logs_to_json.pl:
- Extended to handle legacy pre-Bug 40866 HOLDS CREATE logs where info
  is a bare hold_id, recovering branchcode / biblionumber / itemnumber
  from old_reserves / reserves.
- Uses the same keyset-pagination pattern as the circulation loop so
  rows are not skipped under --commit.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:22 +00:00
Martin Renvoize 507545734e
Bug 41358: Log forced overrides for offline and ILL checkouts
This patch updates offline circulation and ILL checkouts to properly
record their nature in circulation logs as forced transactions.

Offline circulation (process_koc.pl):
- Offline transactions have already occurred without access to normal
  circulation checks
- Now marks these as forced with 'OFFLINE_CIRCULATION' override code
- This helps identify historical transactions that bypassed checks

ILL checkouts (Koha/ILL/Request.pm):
- ILL checkouts are system-initiated and may bypass certain restrictions
  by design
- Now marks these as forced with 'ILL_CHECKOUT' override code
- This helps track and report on ILL circulation activity separately

Display updates (action-logs.inc):
- Added translation strings for both new override codes:
  - OFFLINE_CIRCULATION: "Offline circulation checkout"
  - ILL_CHECKOUT: "ILL system checkout"
- These will now display properly in Tools > Log viewer

This ensures these special checkout types are properly identified in
reporting and analysis, making it easier to understand the context
of historical transactions.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:21 +00:00
Jan Kissig c0c0b6bbfe
Bug 42986: Fix Uncaught TypeError on paycollect
This patch introduces a check if the variable change is defined, before its property innerHTML is accessed.
When calling "Write off selected" an Uncaught TypeError is thrown on form submission when accessing change.innerHTML as the variable change is undefined.
This regression was introduced by bug 42466 in a new submit handler which did not check if 'change' was defined at all.

Test plan:
1. In the staff interface, go to a patron's account
2. Go to Accounting > Create manual invoice
3. Fill out the manual invoice form with an amount
4. Click Save
5. Go to Make a payment
6. Click "Write off selected" (not write off on a single row)
7. IMPORTANT : Open the browser console
8. Click Confirm
9. apply patch and redo steps 1 - 8.

Signed-off-by: Caroline Cyr La Rose <caroline.cyr-la-rose@inlibro.com>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:17 +00:00
Owen Leonard abdfe256ec
Bug 42568: Match maxlength attributes to marc_order_accounts column sizes
This patch adds a maxlength attribute to a few form fields in the MARC
order accounts entry form. Text inputs should now allow the user the
enter more characters than the db will accept.

To test, apply the patch and enable the MarcOrderingAutomation system
preference if necessary.

- Go to Administration -> MARC order accounts -> New account.
- Test these inputs to confirm that you can't enter more characters than
  their maxlengths:
  - Description (250)
  - Match field (10)
  - Match value (50)
  - Basket name field (10)

Sponsored-by: Athens County Public Libraries
Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:16 +00:00
Lucas Gass c5b39eb684
Bug 41604: (QA follow-up) Remove unused JS variable
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:15 +00:00
Lucas Gass d74dea01ac
Bug 41604: (QA follow-up) Add a semicolon
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:14 +00:00
Jonathan Druart 1abfc554f0
Bug 41604: Correctly restore alert when bKohaColumnsUseNames is off
If we define visibility_condition we must have implemented
bKohaColumnsUseNames correctly.

Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:13 +00:00
Jonathan Druart 26d0124c6b
Bug 41604: Hide column if the feature is disabled
Example: supplier_report on the basket page
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:12 +00:00
Jonathan Druart 2a34413601
Bug 41604: Save user decision per column when visibility changes
- Modify column-visibility.dt event handler to store the visibility
  preference of the user
- Improve _dt_force_visibility() to correctly pick the correctly visibility value depending
  on visibility_condition, is_hidden, and the user preference
- Add _dt_get_expected_column_visibility() to guess what's the expected visibility
- Force boolean true/false (vs 1/0) using !!
- Rely on a global variable kohaTableUserChoices to store the user
  choice. It will be part of the state and store in localStorage.

Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:10 +00:00
Lucas Gass d20f7bc7a7
Bug 41604: (follow-up) Fix the visibility when visibility_condition is 0 or null, instead of false
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:07 +00:00
Jonathan Druart f1160e7a70
Bug 41604: Fix force display of a column
If a column must be displayed but was hidden before

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:06 +00:00
Jonathan Druart 6e5ee1fdf7
Bug 41604: Fix typo
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:05 +00:00
Jonathan Druart 060c8918d2
Bug 41604: QA fixes
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:04 +00:00
Jonathan Druart 3efad3f74a
Bug 41604: take visibility_condition when save state is disabled
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:03 +00:00
Jonathan Druart 4d2f963f1c
Bug 41604: Use visibility_condition in other places
There are 3 other places where we force the visibility of columns. They
must als use this new visibility_condition flag, so they are all using
it.

Test plan:
The 3 tables are:
1. basket with the columns edifact, modify, cancel
2. hold history with the column itemtype
3. batch edit patron with the columns checkbox, password expiration,
   protected

Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:02 +00:00
Jonathan Druart 7c688774f1
Bug 41604: Centralize visibility condition in datatables.js
We want to hide column if:
 * the feature is not accessible (pref disabled or insufficient
   permissions)
or
 * the column is hidden in the settings
or
 * the column has been hidden by the user

Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:54:01 +00:00
Hammat Wele 306ebc18ea
Bug 41604: Impossible to hide Checkin column in issues-table in circ/circulation.pl
Bug 41314 caused a regression, making it impossible to hide the Checkin column in the issues table in the patron's circulation page.

To recreate:
1. Hide the checkin column by default in circulation issues-table
   1.1. Go to Administration > Table settings > Circulation tab > Jump to page : circulation > Table id: issues-table
   1.2. Check 'Is hidden by default' for 'checkin'
   1.3. Click 'Save'
2. logout and login
3. Checkout an item to a patron
   3.1. In the search bar, set to Checkout, search for Henry
   3.2. In the checkout field, enter the barcode 39999000010114 and press enter
   --> In the table of issues, Checkin column is visible, it should be hidden by default
4. Apply the patch
5. Repeat step 2, 3
   --> In the table of issues, Checkin column is not visible

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-16 10:53:57 +00:00
Lari Taskula fe312b32d1
Bug 41796: "Forgot your password" link is not visible if OpacResetPassword is enabled but OpacPasswordChange is disabled
Before applying this patch, to reproduce the issue:
1. Set system preference OpacResetPassword to 'not allowed'
2. Set system preference OpacPasswordChange to 'Don't allow'
3. Set preference opacuserlogin to 'Allow'
4. Navigate to OPAC
5. Observe no "Forgot your password?" link on the OPAC main page
6. Set system preference OpacResetPassword to 'allowed'
7. Observe no "Forgot your password?" link on the OPAC main page
8. Set system preference OpacPasswordChange 'Allow'
9. Observe "Forgot your password?" link is present on the OPAC main page.

Instead, it should be already present when OpacResetPassword is allowed.

To test this patch:
1. Apply this patch
2. Set system preference OpacResetPassword to 'not allowed'
3. Set system preference OpacPasswordChange to 'Don't allow'
4. Set preference opacuserlogin to 'Allow'
5. Navigate to OPAC
6. Observe no "Forgot your password?" link on the OPAC main page
7. Set system preference OpacResetPassword to 'allowed'
8. Observe "Forgot your password?" link is present

Signed-off-by: Bo Gustavsson <bosse@gustavsson.one>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-13 15:46:41 +00:00
Laura_Escamilla 787eb80e9d
Bug 42339: Make Record display customization cancel return to record display list
1. Go to the staff interface.
2. Go to Tools > Additional contents.
3. Select the Record display customizations tab/category.
4. Add a new Record display customization, or edit an existing one.
5. Click Cancel.
6. Confirm you are returned to:
   /cgi-bin/koha/tools/additional-contents.pl?category=record_display
7. Confirm you are not returned to the HTML customizations category.
8. Repeat with another Additional content category, such as Pages, and
   confirm its Cancel behavior is unchanged.
9. Sign off and have a great day! :D

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-13 15:46:40 +00:00
Owen Leonard b0fa3d7e6a
Bug 42618: Incorrect sidebar menu link to MARC order accounts
The administration sidebar menu has an incorrect link for MARC ordering
accounts. Clicking the link takes you to EDI accounts. This patch fixes
it.

To test, apply the patch and run 'yarn build'

- Go to Administration -> Libraries (for example)
- In the sidebar menu, click the MARC ordering accounts link.
- You should be taken to the MARC ordering accounts page.

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: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-01 09:34:47 +00:00
Caroline Cyr La Rose 2b2b4b74ba
Bug 42885: FineNoRenewals description mentions fines rather than charges
This patch fixes the terminology in the FineNoRenewals system preference
description to use the term 'charges' instead of 'fines'.

To test:

1. Apply patch
2. Go to Administration > System preferences
3. Search for FineNoRenewals
4. Make sure the description is gramatically correct and doesn't have
   contain typos

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-01 09:34:46 +00:00
Chris Mathevet 4003a4aa90
Bug 42579: Added "no-export" class to ratings div
"Title" column of Checkout history export contains too much
informations, making the export file hard to read and understand.

Test plan :
1 - Connect on OPAC
2 - Go to "Your account"
3 - Go to "Checkout history"
4 - Click on "CSV"
5 - Open file
6 - Notice that the "title" column is too long and contains ratings
    informations
7 - Go back on OPAC
8 - Click on "Copy"
9 - Copy to a .txt file
10 - Notice the same problem as the CSV export
11 - Apply patch
12 - Repeat previous instructions
13 - Notice that the "title" column contains only the title

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-01 09:34:45 +00:00
Jonathan Druart cb47e6fad7
Bug 42278: Fix JS error
Uncaught SyntaxError: redeclaration of non-configurable global property ClaimReturnedLostValue

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-07-01 09:34:35 +00:00
Jonathan Druart dd918e0de1
Bug 42522: Add link to biblio from eholding show view
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:19 +00:00
Jonathan Druart 4844c93a23
Bug 42290: Tidy all script tags - suggestion (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:17 +00:00
Jonathan Druart e4293f93d2
Bug 42290: Tidy all script tags - suggestion
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the suggestion module.

Trivial changes, the main changes have been done already, we only move
them to a separate script tag.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:16 +00:00
Jan Kissig 36e00f5aff
Bug 42283: (QA follow-up) Change icons
Changes the icon on concerns resolved filter to suit other filters set via AV TICKET_STATUS.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:14 +00:00
Paul Derscheid a4ec38d5fa
Bug 42283: (follow-up) URI-encode z3950 search params in GetZ3950Terms
The original template rendered each Z39.50 search param with the
"| uri" TT filter, so the generated query string was safe for
values containing spaces, ampersands or other reserved characters.

The JS port concatenates the raw values, producing a broken query
string when any search field (title, author, subject, etc.) is not
already URL-safe.

Wrap name and value in encodeURIComponent to restore the original
behaviour.

To test:
- Import or create a biblio whose title or author includes a space
  and an ampersand (e.g. "Q & A: Practical tests").
- From the cataloging search results, trigger the Z39.50 search for
  that record.
- Confirm the request URL includes correctly encoded parameters
  (space as %20, & as %26) and that the Z39.50 results load.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:13 +00:00
Paul Derscheid c7422c5c78
Bug 42283: (follow-up) Fix checkbox selector in concerns status filter
Porting the per-status click handler out of the TT loop dropped the
"hide_" prefix on the checkbox selectors:

- the `is(":checked")` test looked at `#<av>` instead of
  `#hide_<av>`, so the branch that removes the filter never fired
- the toggle line read `!$("#hide${av}")` (no underscore) before
  writing `#hide_<av>`, so the checkbox state was always forced to
  true and further clicks stopped toggling

Restore `#hide_${av}` in both places so the filter toggles match the
original TT-rendered selectors (IDs `hide_<av>` on the hidden
checkboxes).

To test:
- Set up TICKET_STATUS authorised values and enable CatalogConcerns
  and OpacCatalogConcerns.
- Create concerns in multiple statuses, open
  /cgi-bin/koha/cataloguing/concerns.pl.
- Click a "Filter <status>" link: rows with that status disappear.
- Click the same link again: it flips back to "Include <status>"
  and rows reappear. Repeat across several statuses.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:12 +00:00
Jonathan Druart 2cf1f980d0
Bug 42283: Tidy all script tags - cataloguing (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:11 +00:00
Jonathan Druart 0aeb26417e
Bug 42283: Tidy all script tags - cataloguing
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the cataloguing module.

The 3 main changes are in the following files:
* addbooks.tt
* additem.tt
* concerns.tt

There are non-trivial changes in concerns.tt. You need to create several
authorised values for TICKET_STATUS, turn on CatalogConcerns and OpacCatalogConcerns, create several concerns and go to /cgi-bin/koha/cataloguing/concerns.pl
Confirm that the filters are working correctly

Note that cataloguing/addbiblio.tt is on a separate bug (bug 42284)

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:10 +00:00
Jan Kissig 5988883898
Bug 42282: (QA follow-up) Split JS to TT block in results, auto tidy
Splits JS to TT and non TT block. Auto tidy

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:09 +00:00
Jan Kissig c9bfc66026
Bug 42282: (QA follow-up) Split JS to TT block in advsearch, auto tidy
Splits JS to TT and non TT block. Auto tidy

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:08 +00:00
Jan Kissig 3bf91a73dc
Bug 42282: (QA follow-up): Fix call of HTML5MediaEnabled and HTML5MediaSets.size
This switches the assignment of Koha.prefs.HTML5MediaEnabled from a non existant template param HTML5MediaEnabled to Koha.Preference('HTML5MediaEnabled').
Also a straying template param HTML5MediaSets.size was left in a JS block.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:05 +00:00
Jonathan Druart 8147f968aa
Bug 42282: Avoid JS error
Fix conflict with "Bug 42177: bundlesEnabled fix"
SyntaxError: redeclaration of const bundlesEnabled

Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:04 +00:00
Paul Derscheid 9db99a08e2
Bug 42282: (follow-up) Switch Coce timeout log to console.warn
qa script flags the stray console.log in the Coce wait-for-images
helper under forbidden_patterns. The line is a genuine soft-failure
diagnostic (Coce never resolved after 5s), matching the
console.warn pattern used for AJAX failures elsewhere in the staff
templates.

To test:
- qa script no longer flags forbidden_patterns on detail.tt.
- With IntranetCoce enabled but Coce unreachable, loading a biblio
  logs "Could not retrieve the images" as a warning after ~5s.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:03 +00:00
Paul Derscheid 774c8d1e94
Bug 42282: (follow-up) Fix broken mailto concatenation in Elasticsearch 404 modal
The port folded the admin email into a single string literal
    " <a href='mailto: + Koha.prefs.KohaAdminEmailAddress'>"
so the href became the literal text "mailto: + Koha.prefs..." instead
of mailto:<admin email>.

Close the string and concatenate Koha.prefs.KohaAdminEmailAddress.

To test:
- Set KohaAdminEmailAddress syspref.
- SearchEngine = Elasticsearch, open a biblio detail page.
- Trigger the Elasticsearch preview with a bad id so the 404 branch
  renders, and confirm the "Send email" link points at mailto:<email>.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:02 +00:00
Jonathan Druart f645702cd8
Bug 42282: Tidy all script tags - catalogue (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:01 +00:00
Jonathan Druart ee299e4b86
Bug 42282: Tidy all script tags - catalogue
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the catalogue module.

The 7 main changes are in the following files:
* ISBDdetail.tt
* MARCdetail.tt
* detail.tt
* imageviewer.tt
* labeledMARCdetail.tt
* moredetail.tt
* stockrotation.tt

Several identical changes (logged_in_user_borrowernumber, searchid,
biblio_id, browser, etc.)
detail.tt needs to be tested a bit more thoroughly but the changes are
still trivial.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:20:00 +00:00
Owen Leonard ea62f3b835
Bug 40610: Update OPAC templates to improve ease of translation
This patch updates the markup structure of some OPAC include files in
order to make the translation process easier.

To test, apply the patch and test that the correct strings are
translatable. In this example I'm testing fr-FR:

- Update a translation:

  > gulp po:update --lang fr-FR
  > perl misc/translator/translate update fr-FR

- Open the corresponding .po file for the strings pulled from
  the include file and locate the updated strings.

  - misc/translator/po/fr-FR-messages.po
    - opac-tmpl/bootstrap/en/includes/biblio-title.inc lines 4 & 5
    - opac-tmpl/bootstrap/en/includes/date-format.inc lines 4, 6, 8
    - opac-tmpl/bootstrap/en/includes/holds-table.inc lines 132 & 135
    - opac-tmpl/bootstrap/en/includes/masthead.inc line 498

  - misc/translator/po/fr-FR/fr-FR-opac-bootstrap.po
    - opac-tmpl/bootstrap/en/includes/biblio-title-head.inc
    - opac-tmpl/bootstrap/en/includes/holds-table.inc line 129 & 141

- Edit the "msgstr" string however you want (it's just for testing).
- Remove the "fuzzy, " text if it's there.
- Install the updated translation:

  > perl mis/translator/translate install fr-FR

- Switch to your translated language in the OPAC.
- Confirm that the strings you translated show up correctly on these
  pages:
  - The page title when viewing a bibliographic record detail page for
    a record without a title.
  - On a user summary page, under the hold tab:
    - A hold that is waiting
    - A hold that is in transit
- In Administration -> Identity providers define a new identity provider
  (it doesn't have to be functional).
  - In the OPAC, test that the "Log in with [identity provider]" link is
    correct in each of the three login forms:
    - The modal triggered from the link in the header
    - The form in the right-hand sidebar
    - The form you see if you navigate directly to a user-related page
      e.g. /cgi-bin/koha/opac-user.pl
- The changes to date-format.inc are only visible if JS is turned off
  because Flatpickr hides the format hint when it loads.

Sponsored-by: Athens County Public Libraries
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:19:59 +00:00
Jan Kissig f7941aee28
Bug 42278: (QA follow-up) Fix HIGHHOLDS to JSON serialisation
Using Koha::Template::Plugin::To to serialize HIGHHOLDS to JSON led to the following error:  Template process failed: undef error - encountered object '2026-05-31T23:59:00', but neither allow_blessed, convert_blessed nor allow_tags settings are enabled (or TO_JSON/FREEZE method missing) at /kohadevbox/koha/Koha/Template/Plugin/To.pm line 32.
This patch fixes the handling of HIGHHOLDS.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:19:57 +00:00
Jan Kissig e0aee23fc1
Bug 42278: (QA follow-up) Fix Uncaught TypeError in request-article
This fixes an Uncaught TypeError when searching for a patron and the search only returns a single patron.

To test:
 a) go to /cgi-bin/koha/circ/request-article.pl?biblionumber=262
 b) ienable dev tools console
 c) enter 'acev' and click Search
 d) The following error appears: Uncaught TypeError: can't access property "on", patrons_table is undefined
 e) apply patch and redo a) to c). The error is not thrown.

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:19:56 +00:00
Jan Kissig c379c8301d
Bug 42278: (QA follow-up): Split JS to separate TT and tidy
This puts ArticleRequestsSupportedFormats in a separate script tag. Auto tidy

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:19:55 +00:00
Paul Derscheid 0361fee0e4
Bug 42278: (follow-up) Guard bare-RHS TT interpolations
Several unquoted const assignments rendered to `const X = ;` when
their TT expression was empty (patron.borrowernumber without a
patron, CAN_user_circulate_manage_bookings absent, or the
AlwaysLoadCheckoutsTable syspref unset). The parser aborted the
whole script block, so has_patron, AlwaysLoadCheckoutsTable, etc.
were never defined and later scripts failed with ReferenceError.

Add TT fallbacks so the RHS is always a valid JS literal.

To test:
- /cgi-bin/koha/circ/circulation.pl with no patron → no console errors
- Search a patron, check out an item → still works

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:19:54 +00:00
Paul Derscheid 72443454b2
Bug 42278: (follow-up) Restore findborrower autofocus when no patron loaded
The JS port inverted the original UNLESS condition, so the patron
search field was focused only after a patron was already selected.
Flip back to !borrowernumber.

To test:
- /cgi-bin/koha/circ/circulation.pl with no patron → cursor in findborrower
- Select patron, reload → no focus jump

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:19:53 +00:00
Jonathan Druart 7cca8e81a2
Bug 42278: Tidy all script tags - circ (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:19:52 +00:00
Jonathan Druart 650a8d8a64
Bug 42278: Tidy all script tags - circ
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the circulation module.

The 4 main changes are in the following files:
* circulation.tt
As expected this one is messy to test, we need to look at the diff and
make sure the different features linked with the variables moved at
still working correctly (yes, it's vague!)
* circulation_batch_checkouts.tt
On the batch checkout table the due date hidden input should have the
value of the return date high demand items.
* overdue.tt
On the overdue report view, the "Return claims" column must be hidden if
ClaimReturnedLostValue is not set.
* transfers_to_send.tt
The transfers to send view should show all libraries

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 16:19:51 +00:00
Marcel de Rooy 1c9e5ed219
Bug 42321: Improve handling of empty Z3950/SRU search results
Skips the empty results; only reports the 'real failures'.
Includes adding a grand total of hits to the form.
Some preliminary work to remove the hardcoded 20 results per target
in the code.
This is not yet a complete solution, but an improvement. The code in
C4/Breeding needs a larger overhaul. (And there might be an issue on
the Folio server side at LOC.)

Test plan:
Without this patch:
Use the LOC SRU server (since if frequently generates errcode 61).
Try the same search several times in a row (with Go). You probably will
come across the "LOC SRU record x: 0" messages. (Random behavior.)
Apply this patch.
Repeat the above. Notice that you will sometimes see the error 61 (and the
tip to refresh) but not the code 0 messages.
Run t/db../Breeding.t

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:39:10 +00:00
Olivia Reynolds cbbfa8c8d2
Bug 38621: Use GetPreparedLetter for report templates
Previously, report templates were rendered using process_tt directly.
This made the available variables inconsistent with other notices and
slips. This patch switches to rendering report templates through the
same function as other notices. To match the arguments to this system,
this patch also makes the report system reference templates by their
code rather than ID.

Test plan:
1.  Under Tools > Notices and Slips, create a new notice in the Reports
    module. Choose a code and a name, and under Email assign a subject
    and the following body:

[% today %]
[% FOREACH d IN data %]
[% d.title %]
[% END %]

2.  Under Reports, create a new report from SQL with a name and the
    following query:

SELECT * FROM biblio LIMIT 1

3.  Create another report from SQL with a different name and the
    following query, specifying a runtime parameter:

SELECT * FROM biblio WHERE 'a'=<<Param>> LIMIT 1

4.  On the first report, select "Run with template" and choose the
    template created earlier.
5.  Verify that the report runs successfully, and the output does not
    include the current date.
6.  On the second report, select "Run with template" and choose the
    template created earlier. Choose "a" as the runtime parameter value
    when asked.
7.  Verify that the report runs successfully, and the output does not
    include the current date.
8.  Apply patch.
9.  On the first report, select "Run with template" and choose the
    template created earlier.
10. Verify that the report runs successfully, and the output now
    includes the current date along with the fetched data.
11. Under the Download dropdown, select "Rendered template (...)".
12. Verify the downloaded file matches the report output.
13. On the second report, select "Run with template" and choose the
    template created earlier. Choose "a" as the runtime parameter value
    when asked.
14. Verify that the report runs successfully, and the output now
    includes the current date along with the fetched data.
15. Under the Download dropdown, select "Rendered template (...)".
16. Verify the downloaded file matches the report output.

Sponsored-by: Open Fifth
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:39:08 +00:00
Jonathan Druart a1f8f35b70
Bug 42453: Prevent 500 on the about page if elastic is not runing
If the elastic countainer is stopped, the about page crashes with a 500
"No nodes are available"

Test plan:
Startup ktd with `--search-engine es8`
Go to the about page
Notice that the "Elasticsearch" line contains the version and "running"
Stop the es container: `docker start koha-es-1`
Refresh the about page
=> Without this patch you get the 500
=> With this patch applied the page is rendered with:
"Version: Unkown" and "Status: not running"

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:39:06 +00:00
Lucas Gass c0477bc9f1
Bug 42909: Use createdRow to add back suspend class
To test:
0/ APPLY PATCH
1/ View a record with some holds on it
2/ Look at the holds table ( reserve/request.pl?biblionumber=32 )
3/ Suspend at least one hold and notice the 'suspend' class on the <tr>
4/ Unsuspend the hold and notice the class is removed

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:39:03 +00:00
Jonathan Druart 761db4772a
Bug 42654: Split on several lines for readability
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:38:58 +00:00
Martin Renvoize ead19931db
Bug 42654: Restore section in OPAC course reserve detail title, breadcrumb and heading
When a course reserve has a section defined, the OPAC course detail page
should display it alongside the course name in the page title, breadcrumb,
and main heading. A previous change inadvertently removed this, leaving only
the course name in all three places.

This patch restores the conditional logic so that:
- If a section is set, the format "Course reserves for 'Course name' - Section"
  is used in the title, breadcrumb and <h1>.
- If no section is set, the existing "Course reserves for 'Course name'"
  format is preserved.

Test plan:
1. Enable the CourseReserves system preference.
2. In the staff interface, go to Course Reserves and create (or edit) a course
   that has a 'Section' value filled in (e.g. "Section A").
3. Add at least one item to that course reserve.
4. In the OPAC, browse to Course Reserves and click through to the detail
   page for that course.
5. Confirm that the browser tab title, the breadcrumb trail, and the page
   heading all show "Course reserves for '<course name>' - <section>".
6. Edit the course and clear the Section field.
7. Revisit the detail page and confirm that all three locations now show
   only "Course reserves for '<course name>'" with no trailing dash or
   section fragment.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Jonathan Druart <jonathan.druart@gmail.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:38:57 +00:00
David Nind eb8b13f429
Bug 42721: Update OPACAuthorIdentifiersAndInformation description and identifier labels
The patch updates the OPACAuthorIdentifiersAndInformation system preference
description so that identifiers are listed in alphabetical order.

It also updates the identifier labels in the system preference
description and what is shown in the OPAC:
- ScopusID --> Scopus ID
- WIKIDATA ID --> Wikidata ID

Test plan:
1. For the OPACAuthorIdentifiersAndInformation system preference, select
   "Identifiers (024$2$a)".
2. Note that in the system preference description the identifiers shown
   in the note are not in alphabetical order.
3. Add identifiers to an authority record in the 024$2 (the code for the
   identifier) and 024$a (the value for the identifier) subfields:
   - Example authority record for authority #483, Wall, Larry:
     . ISNI: isni, 0000000110763894
     . Scopus ID: scopus, 57221714177 (note: not his real Scopus ID)
     . VIAF ID: viaf, 91402770
     . Wikidata ID: wikidata, Q92597
4. View the OPAC authority record details page for an authority record
   with 024$2 and $024a information:
   - Example authority record for authority #483, Wall, Larry
     /cgi-bin/koha/opac-authoritiesdetail.pl?authid=483
5. In another tab view the author information tab for an OPAC
   bibliographic record details page where the author is linked to an
   authority record with 024$2 and $024a information:
   - Example bibliographic record details page for Programming Perl:
     /cgi-bin/koha/opac-detail.pl?biblionumber=262
6. Note for both steps 4 and 5 that:
   - Scopus ID is shown as ScopusID
   - Wikidata ID is shown as WIKIDATA ID
7. Apply the patch.
8. Refresh the OPAC authority record and bibliographic record pages.
9. Note that the identifier labels are now shown as Scopus ID and
   Wikdiata ID.
10. View the OPACAuthorIdentifiersAndInformation system preference
    description and note that the identifiers in the note are now
    listed in alphabetical order.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Olivia Reynolds <olivia.reynolds@openfifth.co.uk>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:38:56 +00:00
David Nind fff08df007
Bug 40603: (follow-up) Update system preference description - add uri
Adds uri (URI) to the note for the OPACAuthorIdentifiersAndInformation
system preference note.

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:38:55 +00:00
Owen Leonard 91f3fde0de
Bug 40603: Add support for "uri" to OPACAuthorIdentifiersAndInformation
This patch adds support for display of the "uri" identifier in the OPAC
when looking at personal name authority records and associated
bibliographic records.

To test you must have:
1. A personal name authority record
2. A bibliographic record which has 100$a linked to that authority
   record.

- Search for OPACAuthorIdentifiersAndInformation and make sure that
  "Identifiers (024$2$a)" is checked.
- Go to Authorities and locate your author's record.
- Add a 024 tag with "uri" as the source in $2, and a URI in $a.
- In the OPAC, locate the bibliographic record you modified.
- On the detail page, check the "Author information" tab
- Go to the authority detail page in OPAC for the author authority
  record you modified. Check the "Author information" section
  in the right-hand column.
  - In both cases you should see the URI you added, labeled with "URI:"

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: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:38:54 +00:00
Jan Kissig 8ab021665b
Bug 42912: Fix Uncaught TypeError on opac-readingrecord when no Checkout history
This prevents an 'Uncaught TypeError: can't access property "DataTable", table is undefined' when a patron has no items checked out yet and is visiting opac-readingrecord.
The code now checks if table is defined before accessing its properties.

Testplan:
a) log in in opac, open dev console
b) go to /cgi-bin/koha/opac-readingrecord.pl
c) without patch applied the error above occurs
d) apply patch and reload opac-readingrecord.pl, there should not be any error now
e) check out an item in staff to that patron and check that the table on opac-readingrecord.pl is diplayed

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-29 15:38:53 +00:00
Jonathan Druart fa92634932
Bug 42281: Tidy all script tags - authorities (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-26 11:57:04 +00:00
Jonathan Druart f4353bc132
Bug 42281: Tidy all script tags - authorities
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the authority module.

The 3 main changes are in the following files:
* detail.tt
* merge.tt
* searchresultlist-auth.tt
diff is trivial

Note that authorities/authorities.tt is on a separate bug (bug 42284)

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-26 11:57:03 +00:00
Jonathan Druart cc73486ab6
Bug 41254: Add '(all)' for top-level entries
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-26 11:57:02 +00:00
Jonathan Druart ae0683fd72
Bug 41254: Replace '*' with arrow
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-26 11:57:01 +00:00
Jonathan Druart fd935fa7d7
Bug 41254: Allow filtering by all authorised values for multi-valued statuses
Some item statuses can correspond to multiple authorised values: Not
for loan, Withdrawn, Lost and Damaged. Until now, only a single entry
could be selected, and filtering applied to all values at once.

This change introduces finer-grained filtering by exposing each
authorised value individually in the filter.

Test plan:
Assign multiple authorised values to items on a bibliographic record
for the four affected attributes: Not for loan, Withdrawn, Lost and
Damaged. Use the "Status" filter and verify that each value behaves as
expected.

Display note:
The current dropdown presentation is not ideal.
Suggestions for improvement are welcome, although avoiding optgroup
would be preferable to keep the scope small.

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-26 11:57:00 +00:00
David Cook 1c6328b82b
Bug 42080: (follow-up) allow some file types, checked by libmagic, to be viewed inline
This patch uses File::LibMagic to determine the real file type using
libmagic and magic numbers of invoice files, and allows a select group
of file types to be viewed inline for user convenience.

Note that a default Content-Security-Policy is still included to offer
an extra layer of protection against XSS.

Test plan:
0a. Apply the patch
0b. koha-plack --restart kohadev
1. Enable the syspref AcqEnableFiles (ie set to Do)
2. Find or create an active vendor
3. Create a basket if one doesn't already exist
4. Receive a shipment for the vendor
5. Create an invoice
6. Click "Finish receiving"
7. Click "Manage invoice files"
8. Upload a range of files including SVG, PDF, PNG, TXT
9. Click on the "Download" button
10. Note that the file downloads for all types
11. Click on the link in the "Name" column
12. Note that only the PDF and PNG display inline in the browser.
The other file types should be downloaded same as if you clicked the
"Download" button.

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-26 11:56:57 +00:00
Jonathan Druart 711b3fbd83
Bug 42286: Tidy all script tags - ill (auto tidy)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-26 11:56:53 +00:00
Jonathan Druart 71cd1efd7d
Bug 42286: Tidy all script tags - ill
In order to tidy all the script tags of the .tt files we isolate the
interpolation of Template::Toolkit variables in a separate script tag.

This patch focuses on the ILL module.

I don't really know how to test this patch...

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-26 11:56:52 +00:00
Pedro Amorim c355bb8574
Bug 42666: (RM follow-up): Tidy datatables.js
prove xt/js_tidy.t

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-24 08:41:35 +00:00
Jan Kissig 293e00e95c
Bug 42357: Show patron details on holds table
This patch reintroduces patron details in 'Existing holds' table by using $patron_to_html.

test plan:
a) get a nice fresh ktd and navigate to /cgi-bin/koha/reserve/request.pl?biblionumber=262
b) place a hold for a patron f.e. 23529000035676
c) take a look at the Existing holds tables patron column which only shows the patrons card number.
d) apply patch and run 'yarn js:build'
e) refresh /cgi-bin/koha/reserve/request.pl?biblionumber=262
f) the patron column now should show patrons name
g) set system preference  HidePatronName  to 'Don't show'
h) go to /cgi-bin/koha/reserve/request.pl?biblionumber=262
f) the patron column now should only show the patrons card number.

Signed-off-by: Lawrence O'Regan-Lloyd <loreganlloyd@clamsnet.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 16:26:38 +00:00
Adolfo Rodríguez 676e01d346
Bug 42825: ERM Local Title - Start date (started_on) not saved for package resources
The started_on field inside relationshipFields was missing indexRequired: true,
which is required to generate a unique DOM id per row and correctly bind the
flatpickr input to the Vue data model.

The date_to componentProp also needs indexRequired: true so it references the
correct indexed id of the ended_on field.

Additionally, add a null check in calendar.inc before accessing ._flatpickr
on the end date element to prevent a TypeError when the linked element is
not found.

To reproduce:
1. Go to ERM > eHoldings > Local > Titles
2. Create or edit a local title
3. Link it to a package and enter a Start date, End date and Proxy
4. Save
5. Reopen the title and click on the linked package row
=> Start date is empty; End date and Proxy are saved correctly

Apply patch, then:
1. Go to ERM > eHoldings > Local > Titles
2. Create or edit a local title
3. Link it to a package and enter a Start date, End date and Proxy
4. Save
5. Reopen the title and click on the linked package row
=> Start date is now saved and displayed correctly
=> No TypeError in the browser console when selecting a start date

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 16:26:37 +00:00
Paul Derscheid 78630a1a82
Bug 42231: (QA follow-up) Show item title in note and suspend-hold modals
The static 'hidden' attribute on #addNoteTitle and #suspendHoldTitle was never
removed, so the item title was populated but stayed invisible.

- Toggle 'hidden' off when a modal is populated with a title
- Toggle 'hidden' on when a modal is closed/cleared

Test plan:
- Enable AllowCheckoutNotes
- OPAC > Summary > Checked out: click 'Add note', confirm the item title shows
- OPAC > Summary > Holds: click 'Suspend', confirm the item title shows
- Reopen each modal on a different item, confirm the title updates
- Run an accessibility checker, confirm no empty-heading errors return

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 16:26:34 +00:00
Laura_Escamilla bfa3956cd3
Bug 42231: Fix accessibility issues in OPAC summary table
The OPAC summary page contains several accessibility issues including an unlabeled renew checkbox, unlabeled textarea in the add note modal, and empty headings rendered before JavaScript population.

Test plan:
1. Have a user with checkouts
2. Log into the OPAC and go to "Summary"
3. Notice the renew checkbox does not have a corresponding label
4. Apply the patch
5. Repeat steps 1-2
6. Confirm the renew checkbox now has a corresponding label

Additional accessibility fixes:
7. Open the "Report a problem" modal
8. Confirm the note textarea has a corresponding label
9. Confirm addNoteTitle and suspendHoldTitle are not exposed as empty headings
10. Run an accessibility checker and confirm the related errors are resolved
11. Sign off and have a great day! :D

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 16:26:31 +00:00
Eric Phetteplace a7646d86d3
Bug 42116: e.preventDefault is a function, needs parentheses
This change is unnoticeable in the UI, so the patch does not need before/after testing, but assurance that everything works. The affected code is used in 3 places for holds (cancelling a hold from reserve/request.pl, circ/circulation.pl, and members/moremember.pl) and 2 for cataloging (two different functions on cataloguing/additem.pl).

For holds:
1. Create three holds on different bibs for a patron
2. On the same page where you create the last hold (reserve/request.pl), delete it
3. Circulation > Check out (circ/circulation.pl) > Check out a different title to patron
4. Switch to patron's Holds tab, delete a hold
5. Go to Patrons account (members/moremember.pl) > Holds tab, delete a hold
6. All holds should delete successfully

For cataloging:
1. Go to any bib > New > New item
2. Select "Add Multiple Copies of this Item", add a note
3. Confirm multiple items are created with the note
4. Enter a new note, then select "Save as template"
5. Confirm the item template exists & create an item using it

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 11:49:25 +00:00
Jan Kissig 070693abd3
Bug 42582: Fix Uncaught TypeError on 'Place request with partner libraries'
This patch fixes an Uncaught TypeError on Place request with partner libraries (op=generic_confirm) when at least one partner library is available (primary email is set) and system preference ILLCheckAvailability is enabled.
Reason for this is an undefined object services.

Test plan:
a) start a ktd instance
 ktd --proxy --name main up -d
b) enable system preference ILLModule and ILLCheckAvailability
 http://main-intra.localhost/cgi-bin/koha/admin/preferences.pl?tab=interlibrary_loans
 ILLModule: 'enable'
 ILLCheckAvailability: 'check'
c) edit an ILL patron and set an Primary email address:
 http://main-intra.localhost/cgi-bin/koha/members/moremember.pl?borrowernumber=16 (Walker)
d) create an ill request (Interlibrary loans -> (Requests) -> New ILL request) and fill out mandatory data
e) open dev tools (F12 on Firefox) and go to 'Place requests with partners'
f) notice console error: Uncaught TypeError: can't access property "enabled", services[0] is undefined
g) apply patch and reload page 'Place requests with partners' -> no error

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 11:49:24 +00:00
Jan Kissig 35c7cd1ae7
Bug 42141: Fix Save and show/list/edit button on Vue SIP2 config
This patch fixes the behavior of the Save (Save and list, Save and continue editing, Save and show) button which is controlled via useBaseResource.navigationOnFormSave on
Accounts, Institutions and System preference overrides in Administration -> Self-service circulation (SIP2)

To test:
a) go to Administration -> Self-service circulation (SIP2)
b) create one of the given resources (institution, account, system preference override) and fill out mandatory fields
c) click either Save or Save and continue editing or Save and show
d) check that you always end up on the list.
e) apply patch and run 'yarn js:build' , reload your browser
f) repeat b) and c)
g) check that the desired view is now shown
  - show the edited/created resource
  - list all created resources
  - continue editing the resource

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 11:49:23 +00:00
Jonathan Druart 398c329c21
Bug 42611: Add missing raw filter
[FAIL] koha-tmpl/intranet-tmpl/prog/en/modules/members/readingrec.tt
   FAIL   filters
                asset_must_be_raw at line 172 (    [% Asset.js("js/members/readingrec.js") %])

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 11:49:22 +00:00
David Cook 5c06532231
Bug 42611: Fix Javascript error when no Circulation history
This patch checks that "table" is defined before trying to access
the DataTable object for it.

This patch also moves the Javascript from the .tt file into a separate .js
file since it doesn't need any Template::Toolkit itself.

Test plan:
0. Apply the patch (and reset_all)
1. Log into the staff interface
2. Go to http://localhost:8081/cgi-bin/koha/members/readingrec.pl?borrowernumber=51
3. Open the console and see there is no longer a Javascript error
4. Check out an item like 39999000001310 to this user
5. Review the "Circulation history" and note that the DataTable appears
and there are no Javascript errors

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 11:49:21 +00:00
Jonathan Druart c14daf3f3c
Bug 42666: OPAC counterpart
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 11:49:20 +00:00
Chris Mathevet 487c9701a4
Bug 42666: Parse kohaTable pageLength setting to int
Test plan :
01 - Clear your browser's local storage
02 - Go to Administration > Item types
03- You need to have more than 10 item types, add some if needed
04 - Observe "Showing 1 to 010 of XX" on top of the table
05 - Click on "next" button at the bottom of the table
06 - Nothing happens
07 - Go to Administration > Patron categories
08 - You need to have more than 20 patron categories, add some if needed
09 - Observe "Showing 1 to 020 of XX" on top of the table
10 - Click on "next" button at the bottom of the table
11 - Nothing happens
12 - Apply patch
13 - Clear your browser's local storage
14 - Repeat 2-5 and 7-10, observe that the leading 0 is gone, and that the
"next" button works

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-23 11:49:15 +00:00
Laura_Escamilla 51bdab13ee
Bug 42078: Allow vendor ID searches on serial subscription vendor search page
The serials vendor search currently only searches vendors by name.
This patch allows the search field to also match vendor IDs so
staff can locate vendors using either name or ID.

Test plan:
1. Go to Serials → New subscription.
2. Click to search for a vendor.
3. Search using part of a vendor name and confirm results appear.
4. Search using an exact vendor ID and confirm the correct vendor is returned.
5. Sign off and have a wonderful day! :D

Signed-off-by: Angela Berrett <angela.berrett@familysearch.org>
Signed-off-by: Angela <angela.berrett@familysearch.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 15:39:13 +00:00
Pedro Amorim c420f23125
Bug 42002: Make 'replace' in screen_msg_regex not required
Default to empty string if null to ensure that leaving it blank produces the required outcome: the replace value is an empty string

Signed-off-by: Marion Durand <marion.durand@biblibre.com>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 15:39:12 +00:00
Lisette Scheer 7d60cc280a
Bug 42734: (QA follow-up) Remove integer class
The integer class appears to only lmit the with of the text box to 5em, making it difficult to see the full preference.
I removed the class for better readability.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 15:39:02 +00:00
Martin Renvoize 914ff32fa2
Bug 42734: Add autoMemberNumValue to patrons sysprefs UI with caution note
This patch adds autoMemberNumValue to the Patrons system preferences
page immediately below autoMemberNum, so superlibrarians can view and
correct a runaway counter without needing vendor support.

The entry carries a caution note explaining:
- the value is managed automatically and should not normally be changed
- Koha generates the next cardnumber from max(counter, live_db_max),
  so lowering the counter only has effect once the patron responsible
  for the inflated number has been deleted or had their cardnumber
  corrected first
- the risk of setting it too low: potential re-issuance of a previously
  used cardnumber, which may grant a new patron access to third-party
  services linked to the original holder

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 15:39:01 +00:00
Owen Leonard 25496bdc4f
Bug 42128: Remove event attribute from admin-icon-selection.inc
This patch removes the "onmousedown" event attribute from
admin-icon-selection.inc, an include used in itemtypes.tt and
authorised_values.tt. I took this opportunity to create separate JS
files for both of those templates and added the event handler to the JS.

To test, apply the patch and go to Administration.

- Go to Item types and add or edit an item type.
  - In the icon selection section, select one of the built-in icons.
  - Switch to the "Remove image" tab.
  - Click the text input. The corresponding radio button should be
    selected.
- Go to Authorized values and perform the same test.

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: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 12:00:22 +00:00
Pedro Amorim 0c353be1c1
Bug 42397: Add 'ILL_BATCHES' action_logs modulename
Update ILL/Batch.pm and ILL/Batch/Status.pm to utilize this new modulename instead

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 12:00:16 +00:00
Jonathan Druart 10e86285a9
Bug 42535: Remove .news_delete JS from the main page
The .news_delete elements have been removed on
  commit c7b576ad7e
  Bug 34478: Remove 'Delete' link for news on the homepage
- | <a class="news_delete" href="/cgi-bin/koha/tools/additional-contents.pl?op=delete_confirmed&amp;ids=[% koha_new.additional_content_id | html %]&amp;csrf_token=[% csrf_token | uri %]">Delete</a>

We can remove this code

Test plan:
Confirm that there is no "Delete" links to delete news on the main page

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 12:00:15 +00:00
Laura_Escamilla f10b232d9e
Bug 42531: Allow repeatable field values to wrap
Test plan
1. Go to Administration → MARC bibliographic frameworks.
2. Edit Books, Booklets, Workbooks (BKS) framework.
3. In tag 508, ensure subfield $a is visible in the editor.
4. Open a bibliographic record (e.g. /cgi-bin/koha/catalogue/detail.pl?biblionumber=90).
5. Edit the record and add a long block of text to 508$a (e.g. extended production credits with many names and separators).
6. Save the record and view it in the staff interface.
    * Before patch: The Production Credits field does not wrap and overflows off the page.
7. Apply the patch and run yarn build.
8. Refresh the record detail page.
    * After patch: The Production Credits field wraps correctly within the page.
9. Confirm that shorter repeatable fields still display inline with separators (|) as expected.
10. Sign off and have a great day!

Signed-off-by: Lawrence O'Regan-Lloyd <loreganlloyd@clamsnet.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 12:00:14 +00:00
Jonathan Druart 2d72d4e17a
Bug 42550: Remove JS error from report list if none exist
If there are no saved SQL reports, the "rtable" variable is empty and
triggers an error when called later.
Uncaught TypeError: can't access property "DataTable", rtable is
undefined

Test plan:
/cgi-bin/koha/reports/guided_reports.pl?op=list
Without reports
=> Without this patch there is a JS error in the console
=> With the patch the error is gone

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 12:00:12 +00:00
Owen Leonard b503cfe22e
Bug 42564: (follow-up) Actually remove calls to old assets
Also incorporate the Font Awesome assets into the installer SCSS.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 12:00:11 +00:00
Owen Leonard 8ffe7d9edb
Bug 42564: Upgrade Font Awesome in the staff interface to 7.2
We are using Font Awesome 6.3 in the staff interface. The current
version is 7.2. Upgrading will eliminate the repeated warnings in the
browser console about "Glyph bbox was incorrect."

The patch updates the staff interface CSS so that it pulls Font
Awesome CSS from node_modules. Font assets have been updated in
lib/fontawesome.

The many changed .inc and .tt files are a result of a missed aspect of
our upgrade to Bootstrap 5. The "sr-only" class was removed in BS5 but
the Font Awesome CSS included its own "sr-only" class. This made up for
the fact that we missed the required upgrade to BS5's "visually-hidden."
As soon as Font Awesome's "sr-only" was gone all these mistakes were
made visible.

To test, apply the patch and run 'yarn install.'
- Rebuild the staff interface SCSS.
- Clear your browser cache.
- Test many pages in the staff interface to confirm that no icons are
  missing.
- Check changes to the templates to confirm that "sr-only" has been
  replaced with "visually-hidden."
  - Places where a broken "sr-only" class would be obvious: The h1
    heading "Koha home" on the staff interface main page, the <legend>
    tag on the new currency form in Administration -> Currencies and
    exchange rates.

Sponsored-by: Athens County Public Libraries
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 12:00:10 +00:00
Owen Leonard 297edd689b
Bug 42641: JavaScript errors on patron attribute types admin page
This patch fixes some JavaScript errors on the patron attributes page.
Vanilla JS doesn't automatically handle null variables like jQuery does.

To test, apply the patch and go to Administration -> Patron attribute
types.

- If necessary, add multiple attribute types.
- The table listing all attributes should be displayed as DataTable and
  there should be no errors in the console.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 12:00:09 +00:00
David Cook 55d236769d
Bug 42202: Unfilter branches for OPAC search, news, and most popular
This change unfilters the branches for OPAC search, news, and most popular.
This is most noticeable when using the IndependentBranches system preference.
This change aligns the UX for both logged in and not logged in users

__SETUP__
- Do not apply the patch yet
- Log into Koha
- Go to Administration > System preferences
- Search for OpacAddMastheadLibraryPulldown system preference
- Change it to "Add" and save the preference
- Search for IndependentBranches system preference
- Set it to "Yes" and save the preference
- Search for OpacTopissue system preference
- Set it to "Allow" and save the preference
- Search for OpacNewsLibrarySelect system preference
- Set it to "Show" and save the preference
- Go to Patrons
- Create or modify a patron with a username/password but no superlibrarian
permission

__TESTS__
- Go to the OPAC (and logout if you're already logged in)
- Note that the library pull down saying "All libraries" is present
in the masthead
- Log in as your unprivileged user
- Note that the library pull down saying "All libraries" is now hidden
- Go to Advanced search and note there's no "Location and availability" option
- Go to "Most popular" and note there's no "From:" library filter
- Go to the home page and note it does not show a library selector for news

- Apply the patch

- Refresh the page
- Note that the library pull down saying "All libraries" is present
in the masthead
- Note that the "From:" library filter now appears
- Go to Advanced search and note "Location and availability" now appears
- Go to the home page and note it now shows a library selector for news

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-19 12:00:03 +00:00
Lucas Gass 4f71f15f0c
Bug 41070: (QA follow-up) Tidy
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-18 16:02:10 +00:00
Baptiste 902ca28a3c
Bug 41070: Fix selector in addorderiso validator
Steps to reproduce, do not apply patch
1 - Go to any record and click save -> marc (Unicode/utf8)
2 - Go to any vendor and add a basket
3 - In your acquisition grid, make sure "barcode" is mandatory
4 - In this basket, create a new order from file, use the generated file and wait for the end of the import. Click on add staged files to basket.
5 - Select the record, make sure no Fund or barcode is filled, neither in first or third tab.
6 - Validate: There will be an error due to the missing barcode. If
there is another error, fill the missing part of the form.
7 - Apply patch, repeat 6, the error will be due to the missing fund
8 - Select a fund in the first panel -> the error will be due to the
missing barcode
9 - Select a fund in the third panel -> the error will be due to the
missing barcode

Note: the point about the barcode are not relevant for the bug, they are
just here to prevent the submission of the form. And avoid repeating
steps 4-5.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-18 16:02:09 +00:00
Owen Leonard 369236bb31
Bug 41803: Improvements to consistency in basket groups template
This patch makes some updates to the basket groups template:
- Buttons in a table's "actions" column should have the class "btn
  btn-default btn-xs"
- Adding icons to action buttons
- Group export options (CSV and PDF) under button dropdown
- Use class instead of ID as hook for closing and deleting basket
  groups. This prevents duplicate element IDs on the page.
- When there is no EDIFACT configuration, disable the "Generate EDIFACT
  order" button and put the error message in a tooltip.
- Style warning message as Bootstrap alert

To test, apply the patch and go to Acquisitions and locate a vendor.

- View the vendor details.
- Click "Basket groups" in the sidebar.
- Create multiple basket groups if necessary.
- Test various operations in the list of open groups:
  - Close and export PDF
  - Edit
  - Delete
- Test the actions for a closed basket group:
  - Reopen
  - Export -> CSV and Export -> PDF
- Enable the EDIFACT system preference but do not add any EDI accounts.
  - Under the "Closed" basket group tab the "Generate EDIFACT order"
    buttons should be disabled, and hovering over each one should
    trigger a popup warning that there is no EDIFACT configuration for
    the vendor.

Sponsored-by: Athens County Public Libraries
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-18 16:02:05 +00:00
Jonathan Druart 38474d7611
Bug 42781: Do not modify window.name
https://developer.mozilla.org/en-US/docs/Web/API/Window/name

Test plan:
0. Do not apply this patch (you can apply the first one)
1. Go to /cgi-bin/koha/members/members-home.pl
2. Open the console
3. type "window.name", it's ""
4. Run a patron search, "d"
5. window.name is now "Duffy, Joann name"
6. Apply this patch, try again
7. window.name is still an empty string

Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-15 15:59:36 +00:00
Magnus Enger 98459bab8c
Bug 42781: Declare 'name' before using it in patron-format.js
The code in koha-tmpl/intranet-tmpl/prog/js/patron-format.js uses
a variable called 'name' without declaring it first. The declaration
was removed in bug 32176. No deterioration of functionality has been
discovered in connection with this, but the declaration should be
restored.

To test:
- Apply the patch.
- HidePatronName = Show
- Look at the staff detail view for a record that has at least one
  item on loan.
- Verify the name of the patron is displayed as expected.

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-15 15:59:34 +00:00
Lari Taskula e0fb33c3a7
Bug 28915: Adjust input maxlength when subfield is used as charpos
To test MARC modification with the new feature:
1. Add a new record and make sure it has the following fields
1.1 Field 008 character position 35-37 contains "|||"
1.2 Field 041$a contains "eng"
2. Navigate to Cataloging > MARC modification templates > + New template (name "Change 008 lang")
3. Click + New action
4. Add "008" after "field(s)"
5. From dropdown "Delete", select "Update existing or add new"
6. To the input field on the right of "starting from character position", enter value 35
7. To the input field on the right of "with value", enter eng
8. From the empty dropdown below, select "if"
9. To the input field on the right of "field", enter 041, and to the right, enter a
10. From the dropdown on the right, select "matches"
11. Check "RegEx"
12. To the empty input field on the right, enter ^eng$
(the line should now say: [if] field [041] [a] [matches] m/[^eng$]/ RegEx [X])
13. Give any description you want (ex. Change 008 35-37 to eng)
14. Navigate to the record details you added in step 1
15. Click Edit > Modify record using template
16. Click "Show MARC"
17. Double check field 008 character position 35-37 is currently |||
18. Click "Close"
19. From dropdown "Select a template", select your new modification template from step 2
20. Click "Show MARC"
21. Observe field 008 character position 35-37 is now eng
22. Click "Modify selected records"
23. After job is completed, observe field 008 character positions 35-37 is now eng

Also test MARC modification templates for non-control fields in case of regression.

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-15 15:24:14 +00:00
Andrew Fuerste Henry c19f99daa1
Bug 28915: (follow-up) Increase field size and maxlength in template
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
2026-06-15 15:24:09 +00:00