Commit Graph

60112 Commits

Author SHA1 Message Date
Martin Renvoize cd47fb5ca7
Bug 40435: (follow-up) Change preference type to YesNo
Change FutureHoldsBlockRenewals from type 'Integer' to 'YesNo'
for consistency with other boolean preferences in Koha (e.g.,
AllowHoldDateInFuture, OPACAllowHoldDateInFuture).

While the preference functionally works as Integer due to the
.pref file defining the choices, YesNo is the established
convention for binary system preferences.

Test plan:
1. Apply this patch
2. Run the database update
3. Verify the preference appears correctly in system preferences
4. Verify the preference still functions properly with tests:
   prove t/db_dependent/Circulation.t :: "CanBookBeRenewed | future holds"

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:24 -07:00
Martin Renvoize 70ced21a4d
Bug 40435: (follow-up) Fix DateTime mutation in test
The test had a bug where $future_date was being mutated by the
add() method on line 1975, causing line 1982 to use 4 days
instead of 2 days. This meant the test wasn't properly verifying
that FutureHoldsBlockRenewals=0 prevents blocking for holds
within the ConfirmFutureHolds window.

Test plan:
1. Run: prove t/db_dependent/Circulation.t :: "CanBookBeRenewed | future holds"
2. Verify all tests pass
3. Confirm the test now properly validates the intended behavior

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:23 -07:00
Marcel de Rooy 1c7aab82c5
Bug 40435: Add tests
Test plan:
Run t/db_dependent/Circulation.t

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:23 -07:00
Marcel de Rooy 71b439d855
Bug 40435: Module changes
CanBookBeRenewed will by default pass the skip_future_holds flag
to item->current_holds so that renewals are not blocked by future
holds.
The new pref FutureHoldsBlockRenewals allows you to change that
historical behavior.

Test plan:
[1] Set pref ConfirmFutureHolds=3, FutureHoldsBlockRenewals=Allow,
    OPACAllowHoldDateInFuture=Allow
[2] Checkout some item to patron A.
[3] Place hold on same item for patron B, reserve date tomorrow.
[4] Try to renew item with patron A on account page. Should be
    marked as Not renewable.
[5] Set pref FutureHoldsBlockRenewals=Dont
[6] Repeat step 4. Renew should be allowed.
[7] prove t/db_dependent/Holds.t t/db_dependent/Reserves.t

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:22 -07:00
Marcel de Rooy 87c143b4c2
Bug 40435: Add to HEA
Grouping all future hold prefs here too.

Test plan:
prove t/db_dependent/UsageStats.t

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:22 -07:00
Marcel de Rooy 5b5ffc57c7
Bug 40435: New preference FutureHoldsBlockRenewals
Test plan:
Change this pref value under Administration.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:21 -07:00
Marcel de Rooy f3978e5b1c
Bug 40435: Database revision
Test plan:
[1] Run install or upgrade (updatedatabase.pl). Verify that pref was added to database.
* perl -MC4::Context -e'print C4::Context->preference('FutureHoldsBlockRenewals'),"\n"'
* You should see a zero printed.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:21 -07:00
Lucas Gass 9f9fe699f3
Bug 38061: DBRev 25.12.00.010
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:20 -07:00
Victor Grousset/tuxayo 00988f4d94
Bug 38061: (QA follow-up): dbrev: print if column already exists
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:20 -07:00
Matt Blenkinsop 0a669a7e97
Bug 38061: (QA follow-up) Add default falsy value for subscription creation/editing
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:19 -07:00
Matt Blenkinsop f5ede57411
Bug 38061: Add a checkbox to determine whether collection table issues should be pre-selected
Test plan:
Apply the patches and update the database
1) Create a new subscription with items, there should be a checkbox at the bottom of the form to pre-select collection table issues - make sure this is checked
2) Receive some items against the subscription
3) Navigate to the collections table
4) The checkboxes should be pre-selected as per previous behaviour in Koha
5) Edit the subscription and uncheck the checkbox
6) Return to the collections table and the checkboxes should all be unchecked

Signed-off-by: Nathalie <nathalie.savarit@univ-amu.fr>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:19 -07:00
Matt Blenkinsop 2894e34c1e
Bug 38061: Add item column to serial collections table
This patch adds a column to the table to link to the item

Test plan:
1) Add a new subscription to a serial record (with the option 'create an item record' selected)
2) Receive several issues and create the linked items
3) Navigate to the serials collection table
4) There should be a column for the linked item
5) Click on one of the links, it should display the item

Signed-off-by: Nathalie <nathalie.savarit@univ-amu.fr>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:11 -07:00
Owen Leonard d5de3ee6cd
Bug 38643: (QA follow-up) Replace _() with __() in global.js
The double-underscore function is required for translations to be picked
up in JS files.

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:11 -07:00
Laura_Escamilla 7c5c8e74bc
Bug 38643: Added JS for the dynamic placeholders
To test:

1. Visit http://localhost:8080/cgi-bin/koha/opac-main.pl — notice that
   the main search bar has a placeholder.
2. Visit the advanced search page. Notice that the search bars in the
   advanced search do not have placeholders.
3. Apply this patch. restart_all
4. Refresh the page on the advanced search. Notice that the search bars
   now have placeholders. Try switching out the dropdown options and
   notice that the placeholder text changes depending on what you
   select.
5. Test searches and make sure everything works as expected.
6. Sign off — have an amazing day! :D

Signed-off-by: Ludovic <ludovic.julien@inlibro.com>
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:11 -07:00
Laura_Escamilla 2ad6b96983
Bug 38643: Added dynamic placeholders to the advanced search inputs
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:10 -07:00
Laura_Escamilla b28daeb973
Bug 40794: Add id='account-tabs' wrapper to payment and account tab templates
This patch adds a new id="account-tabs" to that div.

To test:

Apply the patch and restart_all. Clear browser cache if necessary.

1. Go to a patron’s accounting tab → Transactions / Make payment / Manual invoice / Manual credit.
2. Inspect the HTML for the tabs menu. The surrounding div should have both class="toptabs" and id="account-tabs".
3. Verify styling and tab functionality remain unchanged.
4. Sign off and have a great day! :D

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:10 -07:00
Jonathan Druart 9f947a2517
Bug 41047: Sort libraries by description instead of code
On the holdings tables the libraries are sorted by code, we should sort
them by description.

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:09 -07:00
Pedro Amorim 32ea6abb1e
Bug 41054: Sort metadata keys alphabetically case insensitive
This coincidentally+nicely puts eISSN before ISSN on the 'manage request page' while keeping the rest of the order as before

Test plan:
1) Enable ILLModule
2) Create a new ILL request, visit:
<staff_url>/cgi-bin/koha/ill/ill-requests.pl?method=create&backend=Standard
3) Pick type one of 'journal article', 'conference', 'journal', 'generic resource'
4) Enter cardnumber, library, eISSN and other data if you want
5) Notice 'eISSN' shows on the 'Manage request' page.
6) Test again by creating an OPAC request, visit:
<opac_url>/cgi-bin/koha/opac-illrequests.pl?op=add_form&backend=Standard

Signed-off-by: Richard Bridgen <Richard.Bridgen@nhs.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:09 -07:00
Pedro Amorim d8989fe57f
Bug 41054: Add eISSN to Standard forms
Signed-off-by: Richard Bridgen <Richard.Bridgen@nhs.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:08 -07:00
Pedro Amorim e6788ab699
Bug 41054: Add test
prove t/db_dependent/Koha/ILL/Backend/Standard.t

Signed-off-by: Richard Bridgen <Richard.Bridgen@nhs.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:08 -07:00
David Cook 58f0439bcf
Bug 41646: Fix HTML display for self-checkin
This change moves the wrapper so that the web page display correctly

Test plan:
0. Apply the patch
1. Enable the SelfCheckInModule system preference
2. Go to http://localhost:8080/cgi-bin/koha/sci/sci-main.pl
3. Note that there isn't a lot of whitespace between
the word "koha" and "Self check-in"
4. Celebrate

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:07 -07:00
Tomás Cohen Arazi 8f7a1b861f
Bug 41603: Move after_hold_action plugin hook outside transaction
The after_hold_action plugin hook is currently called from within the
hold cancellation transaction in Koha::Hold->cancel(). This creates
a fragile architecture where any plugin performing database queries
can cause lock timeouts and transaction failures.

The issue manifests when plugins query tables with foreign key
relationships to biblio records. Even lightweight queries on seemingly
unrelated tables (like illrequests) can trigger lock conflicts due to
foreign key constraints that require shared locks on referenced rows.

Since the plugin hook executes while the transaction holds locks on
reserves/biblio tables, any plugin database access creates potential
for circular lock dependencies and timeouts.

This patch moves the plugin hook call outside the transaction boundary,
ensuring that:
- Core hold operations complete without plugin interference
- Plugins receive the same data but execute after transaction commit
- Database lock conflicts are eliminated
- Plugin failures cannot corrupt core hold cancellation logic

The hook receives identical data through a stored reference to the
cancelled hold, maintaining full backward compatibility while
eliminating the transaction fragility.

Test plan:
1. Install any plugin that implements after_hold_action hook with
   database queries (e.g., ILL plugins checking hold relationships)
2. Create a hold and attempt to cancel it
3. Without patch: Operation may timeout with "Lock wait timeout exceeded"
4. With patch: Operation completes immediately
5. Verify plugin hook still receives correct hold data

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:07 -07:00
Lucas Gass b3cea14d28
Bug 38207: DBIC
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:06 -07:00
Lucas Gass e8d42b7abc
Bug 38207: DBRev 25.12.00.009
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:06 -07:00
Andrew Fuerste Henry dcf1a2b959
Bug 38207: Add exec flag to atomicupdate
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:05 -07:00
Matt Blenkinsop d221187a41
Bug 38207: Update cypress tests
(cherry picked from commit 61bcde708a970d1bca07e4a803ae5dfe78c16c89)
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:05 -07:00
Matt Blenkinsop 23af641f5a
Bug 38207: Update UI to use new field
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:04 -07:00
Matt Blenkinsop 2234969a83
Bug 38207: Add a new payment_method column to aqbooksellers
(cherry picked from commit 881f96172a8c1b35d3e74f7f0f6aa44629578021)
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:04 -07:00
Lucas Gass 12b73f4719
Bug 20638: DBRev 25.12.00.008
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:03 -07:00
Tomás Cohen Arazi 95ce864450
Bug 20638: (follow-up) Silence viewlog.pl warning
This patch fixes useless warnings being printed by `viewlog.pl` I
noticed while testing this new feature.

To test:
1. Test the feature introduced by this patchset
2. Make sure you are running:
   $ ktd --shell
  k$ tail -f /var/log/koha/kohadev/*.log
=> FAIL: You see things like:

```
[2025/09/26 18:37:39] [WARN] Use of uninitialized value in substr at /kohadevbox/koha/tools/viewlog.pl line 156.
[2025/09/26 18:37:39] [WARN] Use of uninitialized value in substr at /kohadevbox/koha/tools/viewlog.pl line 156.
[2025/09/26 18:37:39] [WARN] Use of uninitialized value in substr at /kohadevbox/koha/tools/viewlog.pl line 156.
[2025/09/26 18:37:39] [WARN] Use of uninitialized value in substr at /kohadevbox/koha/tools/viewlog.pl line 156.
[2025/09/26 18:37:39] [WARN] Use of uninitialized value in substr at /kohadevbox/koha/tools/viewlog.pl line 156.
[2025/09/26 18:43:44] [WARN] Use of uninitialized value in substr at /kohadevbox/koha/tools/viewlog.pl line 156.
[2025/09/26 18:43:44] [WARN] Use of uninitialized value in substr at /kohadevbox/koha/tools/viewlog.pl line 156.
```
3. Refresh the viewlog page
=> FAIL: They are consistent
4. Apply this patch
5. Repeat 3
=> SUCCESS: No more warnings!
6. Sign off :-D

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:03 -07:00
Tomás Cohen Arazi 130ee49ba4
Bug 20638: Improve ApiKey logging to use structured data
This patch enhances the ApiKey logging mechanism to pass structured
object data instead of formatted strings to logaction(), following
the ACTN1 coding guideline for action logs.

Changes:
- Pass the ApiKey object directly to logaction() for CREATE/REVOKE/ACTIVATE
- Pass undef for info and the object in diff field for DELETE operations
- Refactor store/revoke/activate methods to improve logging consistency
- Update tests to handle the new structured logging format

The new approach provides richer, more structured log data that can be
better utilized by log analysis tools and maintains consistency with
other Koha object logging patterns.

Test plan:
1. Enable ApiKeyLog system preference
2. Create, revoke, activate, and delete API keys
3. Verify action_logs table contains structured object data
4. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Koha/ApiKey.t
=> SUCCESS: Tests pass!
5. Sign off :-D

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:02 -07:00
Tomás Cohen Arazi 6720260774
Bug 20638: Include APIKEYS in 'Modification log'
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:02 -07:00
Tomás Cohen Arazi ddb282013f
Bug 20638: Add APIKEYS support to log viewer
Add comprehensive support for viewing API key logs in the log viewer:

tools/viewlog.pl:
- Add APIKEYS to patron lookup logic alongside MEMBERS, CIRCULATION, FINES
- Enable patron name display for API key log entries

koha-tmpl/.../viewlog.tt:
- Add APIKEYS to the modules list for filtering
- Add ACTIVATE and REVOKE to the actions list for filtering
- Include APIKEYS in patron display logic for object column

koha-tmpl/.../action-logs.inc:
- Add APIKEYS module translation: 'API keys'
- Include ApiKeyLog system preference check with warning icon
- Add ACTIVATE and REVOKE action translations
- Maintain alphabetical order in translation blocks

This enables librarians to view and filter API key creation, activation,
revocation, and deletion activities in the standard log viewer interface,
with proper patron name resolution and preference-based logging status
indicators.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:01 -07:00
Tomás Cohen Arazi bc6110ae10
Bug 20638: Update apikeys.pl and template with proper exception handling
This patch comprehensively updates the API keys management interface
to use the new revoke() and activate() methods with proper exception
handling.

Controller changes (members/apikeys.pl):
- Add Try::Tiny and Scalar::Util imports for exception handling
- Replace direct field manipulation (active(0)/active(1)) with proper
  method calls (revoke()/activate()) to ensure logging
- Wrap method calls in try/catch blocks to handle specific exceptions:
  * Koha::Exceptions::ApiKey::AlreadyRevoked
  * Koha::Exceptions::ApiKey::AlreadyActive
- Implement standard Koha messages pattern with @messages array
- Improve code structure with elsif chain instead of multiple if statements
- Add proper error handling for key_not_found cases
- Include error_string for unhandled exceptions to aid debugging

Template changes (koha-tmpl/.../apikeys.tt):
- Add comprehensive error message handling for all exception types:
  * already_revoked: Clear message for revoked keys
  * already_active: Clear message for active keys
  * key_not_found: Message for missing keys
  * unhandled_exception: Generic message with detailed error string

Key benefits:
- All API key state changes are now properly logged when ApiKeyLog is enabled
- Better user experience with specific, actionable error messages
- Robust exception handling prevents crashes and provides debugging info
- Improved code maintainability and extensibility

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:01 -07:00
Tomás Cohen Arazi be1c64aa46
Bug 20638: Add revoke() and activate() methods to Koha::ApiKey
This patch adds two new methods to Koha::ApiKey:
- revoke(): Sets active to 0, throws exception if already revoked
- activate(): Sets active to 1, throws exception if already active

Both methods include proper exception handling and comprehensive tests.

Test plan:
1. prove t/db_dependent/Koha/ApiKey.t
2. Verify new subtests pass for revoke() and activate() methods
3. Confirm exceptions are thrown for invalid state transitions

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:00 -07:00
Tomás Cohen Arazi ad7f5c1d80
Bug 20638: Add ApiKeyLog system preference
This patch adds the ApiKeyLog system preference to control logging
of API key actions (creation, deletion, revocation, activation).

The preference follows the same pattern as BorrowersLog and other
logging preferences.

Test plan:
1. Apply patch and run database update
2. Go to Administration > System preferences > Logs
3. Verify ApiKeyLog preference appears with Yes/No options
4. Verify default value is 'Don't log' (0)

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:26:00 -07:00
Martin Renvoize 2025731e52
Bug 38728: (follow-up) Fix cashup modal triggering after POST/REDIRECT/GET implementation
The upstream implementation of POST/REDIRECT/GET pattern for cashup operations
introduced a regression where the cashup modal would no longer auto-trigger
after successful cashup submission. The original approach passed cashup_id as
a query parameter in the redirect, but the template variable was not being
populated from the URL parameter, causing the JavaScript to receive an empty
value.

This follow-up implements a more modern and reliable solution using URL hash
fragments instead of query parameters:

1. Changed redirect URLs to use hash fragments (e.g., #cashup-123)
2. Updated JavaScript to detect and parse hash fragments on page load
3. Auto-triggers the cashup modal when hash is present
4. Cleans up the URL using history.replaceState() after modal opens

Benefits:
- Maintains proper POST/REDIRECT/GET pattern
- Hash fragments don't trigger server requests or require server-side handling
- More reliable than template variable approach
- Follows modern web development patterns
- Works consistently across both register.pl and registers.pl pages

Test plan:
1. Navigate to POS register page (pos/register.pl)
2. Perform a cashup operation
3. Verify the cashup summary modal automatically appears after redirect
4. Verify the URL is clean (no hash fragment visible)
5. Repeat for registers summary page (pos/registers.pl)
6. Perform individual register cashup
7. Verify modal auto-triggers correctly

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:59 -07:00
Martin Renvoize f57279b52c
Bug 38728: Add automatic modal popup for cashups in registers summary
This patch automatically triggers the cashup display modal after a
cashup is performed from the Cash registers summary page when performing
a cashup on an individual register.

Test plan:
1. Enable the point of sale system preference
2. Ensure you have permission for cash_management > cashup
3. Create at least one cash register for your current branch
4. Navigate to More > Point of Sale > Cash registers
5. Perform some transactions to create outstanding amounts
6. Click 'Record cashup' button on an individual register
7. Confirm the cashup in the modal dialog
8. Verify that after page reload, the cashup summary modal
   automatically opens showing the details of the cashup just performed

Signed-off-by: Sally <sally.healey@cheshiresharedservices.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:59 -07:00
Martin Renvoize c122b45af8
Bug 38728: Add automatic modal popup for cashups on register details page
This patch automatically triggers the cashup display modal after a
cashup is performed from the individual Register details display page.

Test plan:
1. Enable the point of sale system preference
2. Ensure you have permission for cash_management > cashup
3. Create at least one cash register for your current branch
4. Navigate to More > Point of Sale > Cash registers
5. Click on a register name to access the individual register page
6. Perform some transactions to create outstanding amounts
7. Click 'Record cashup' button on the register details page
8. Confirm the cashup in the modal dialog
9. Verify that after page reload, the cashup summary modal
   automatically opens showing the details of the cashup just performed

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Sally Healey <sally.healey@cheshiresharedservices.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:58 -07:00
Jonathan Druart 0a3ed65e70
Bug 40192: (bug 38446 follow-up) Add title to /erm/extended_attribute_types
Sponsored-by: Karlsruhe Institute of Technology (KIT)
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:58 -07:00
Matt Blenkinsop 806ac743f0
Bug 40192: Add additional fields support to ERM titles
This patch extends the additional fields framework to ERM e-holdings
titles, allowing libraries to configure custom metadata fields for
managing electronic resources.

Implementation details:
- Extended Koha::ERM::EHoldings::Title and ::Titles with
  AdditionalFields mixin for object-level support
- Added 'erm_titles' table mapping to AdditionalField.pm for API
  serialization
- Updated OpenAPI schema definitions to include extended_attributes
  in erm_eholdings_title.yaml and expose extended_attribute_types
  endpoint
- Enhanced REST API controller to handle additional fields in title
  creation/updates
- Updated admin interface to allow configuring additional fields for
  the 'title' table name
- Modified Vue.js EHoldingsLocalTitleResource component to display
  and manage custom fields

This enables institutions to track custom metadata (e.g., license
details, administrative notes, local identifiers) alongside standard
ERM title information.

Test plan:
1. Configure additional fields:
   - Go to Administration > Additional fields
   - Click "New field" and select table name "title"
   - Create a text field: Name="License notes", Searchable=Yes
   - Create an authorized value field: Name="Access level",
     AV category=LOC (or any available category)
   - Save both fields

2. Test with local ERM titles:
   - Navigate to E-resource management > Local titles
   - Create a new local title or edit an existing one
   - Verify the "Additional fields" section appears with your
     configured fields
   - Fill in "License notes" with test text
   - Select a value for "Access level"
   - Save the title

3. Verify persistence:
   - Reopen the title you just edited
   - Confirm both additional field values are displayed correctly
   - Edit one field value and save
   - Confirm the update persists

Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:57 -07:00
Matt Blenkinsop c04ac1c541
Bug 40191: Tidy files without the DO NOT PUSH patch
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:56 -07:00
Matt Blenkinsop ce6367fede
Bug 40191: Handle resources without detail view in navigation options
Fixes an edge case where resources without a dedicated show/detail component
(like Record Sources) would show invalid navigation options.

- ResourceFormSave: Filter out "show" option when no_show is true
- RecordSourcesResource: Set no_show flag to hide inappropriate options

Ensures the split button menu only shows valid navigation targets.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:56 -07:00
Matt Blenkinsop 671ecb0731
Bug 40191: Add Cypress test coverage for split button navigation
Adds E2E test in VueFramework_spec.ts verifying:
- Split button renders with correct options
- Primary action executes default navigation
- Dropdown options execute alternative navigation behaviors
- Behavior adapts correctly based on resource configuration

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:55 -07:00
Matt Blenkinsop 8a1dd87c70
Bug 40191: Update Cypress tests for split button navigation changes
Updates existing test selectors and assertions to work with the new split
button UI pattern:

- Admin/RecordSources_spec.ts: Update button selectors
- ERM tests (Agreements, Licenses, Packages, Titles, Dialog): Update form save expectations
- InfiniteScrollSelect_spec.ts: Update interaction patterns
- Preservation/Trains.ts: Update save button selectors

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:55 -07:00
Matt Blenkinsop 00f3c8dd99
Bug 40191: Extend split button navigation to sticky toolbar
Adds the same split button navigation options to the sticky toolbar that
appears when scrolling resource forms, ensuring consistent functionality
regardless of scroll position.

Components modified:
- Toolbar.vue: Support for dropdown button actions
- ResourceFormSave.vue: Emit navigation events for toolbar
- VendorResource.vue: Wire up toolbar navigation handlers

Maintains UX consistency between main form buttons and sticky toolbar.

Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:55 -07:00
Matt Blenkinsop 23afa83ecc
Bug 40191: Change button text from 'Submit' to 'Save' for clarity
Updates ResourceFormSave component button labels:
- "Submit" → "Save" (more intuitive for editing forms)
- "Submit and [action]" → "Save and [action]"

Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:54 -07:00
Matt Blenkinsop a61e410e11
Bug 40191: Add split button UI for alternative post-save navigation
Introduces a split button pattern allowing users to override the default
post-save behavior:
- Primary button executes default action
- Dropdown menu provides alternative navigation options
- Adapts menu options based on resource configuration

Components modified:
- New DropdownButtons component for split button UI
- Updated ButtonSubmit to support dropdown actions
- Extended ResourceFormSave with action handlers
- Applied to VendorResource and ToolbarButton

The UI adapts based on resource configuration:
- "show" default: offers "continue editing" and "return to list"
- "edit" default: offers "show" and "return to list"
- "list" default: offers "show" and "continue editing"

Test plan:
1) Enable ERM and navigate to the agreements form
2) At the bottom, there should now be a button for "Submit" and a dropdown with two options
 - Submit and continue editing
 - Submit and return to list
3) Fill out the form three times, testing a different button each time
4) Click to edit one of your agreements
5) The buttons should operate the same but now they will start with 'Submit' instead of 'Save'
6) Navigate to licenses - for the purposes of testing the DO NOT PUSH commit has set this to have the behaviour where it returns to the list on save
7) On the form, the list option should be gone from the dropdowns and replaced by "Submit and show"
8) The buttons should all operate as described
9) Navigate to packages - for the purposes of testing they have been set to default to staying on the form when saving
10) The option to continue editing should be gone, replaced with the option to return to the list
11) The buttons should work as described

Sponsored-by: Karlsruhe Institute of Technology (KIT)
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:54 -07:00
Matt Blenkinsop 317c548a07
Bug 40191: Apply configurable post-save navigation to all resource forms
Extends the navigation behavior system to all Vue resource components:
- EHoldings packages and titles (ERM)
- Licenses (ERM)
- Record sources (Admin)
- Preservation trains
- Vendors
- SkeletonResource template

Each resource can now define its preferred post-save behavior via the
on_save_navigation prop.

Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:53 -07:00
Matt Blenkinsop 1fc9fd20a6
Bug 40191: Add configurable post-save navigation for Vue resource forms
This patch introduces a new navigation behavior system for resource forms,
allowing each resource type to define its default post-save action (stay on
form, show detail, or return to list).

Changes:
- Add `on_save_navigation` prop to ResourceFormSave component
- Extend base-resource composable with navigation configuration
- Implement navigation logic in ButtonSubmit component
- Apply to AgreementResource as initial implementation

This provides a more flexible UX by letting different resource types have
appropriate default behaviors while maintaining consistent patterns.

Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 09:25:46 -07:00