Commit Graph

6356 Commits

Author SHA1 Message Date
Andrew Fuerste Henry cc68988bce
Bug 41752: label concactfirstname and contactname as Guarantor first name and Guarantor surname
This change impacts the display of patron fields listed in system preferences:
BorrowerMandatoryField
BorrowerUnwantedField
PatronSelfModificationBorrowerUnwantedField
PatronSelfRegistrationBorrowerMandatoryField
PatronSelfRegistrationBorrowerUnwantedField

To test:
1 - confirm that the sysprefs listed above include "Alternate contact: First name (contactfirstname)" and "Alternate contact: Surname (contactname)"
2 - confirm that toggling the display of these fields hides/shows the Guarantor first name and Guarantor surname fields in a patron record
3 - apply patch, restart_all
4 - confirm that sysprefs now show "Guarantor first name (contactfirstname)" and "Guarnator surname (contactname)"
5 - confirm toggling the display of these fields still hides/shows the correct fields in a patron record in the staff client, in self-ref, and in OPAC self-modification

Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-02-06 15:17:27 -07:00
Tomás Cohen Arazi 402a251392
Bug 40966: Make sure 'whole_record' and 'weighted_fields' are passed around
The ES query builder correctly handles this parameters (passed from
search.pl and opac-search.pl) when it builds the ES query. But the
returned 'query_cgi' that is used later for keeping the search results
query context for building things like facets, just doesn't pass this
values around, leading to a loss of them on the generated links.

This patch makes sure they are passed around.

To test:

1. Apply the regression tests
2. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Koha/SearchEngine/Elasticsearch/QueryBuilder.t
=> FAIL: Tests fail! These params are not passed around!
3. Set ElasticsearchMARCFormat="Searchable array"
4. Reindex all the things:
  k$ koha-elasticsearch --rebuild -d -v kohadev
5. Go to advanced search, using the 'More options' option.
6. Check 'Search entire MARC record' and 'Apply weights to search'
7. Perform a search on 'FULL TEXT'
=> SUCCESS: The URL contains `whole_record=on` and `weighted_fields=on`
8. Hover on any facet and look at the link
=> FAIL: It doesn't contain them!
9. Apply this patch
10. Restart all
  k$ restart_all
11. Refresh the search results
12. Repeat 6
=> SUCCESS: Links have the needed parameters!
13. Repeat 2
=> SUCCESS: Tests pass! the parameters are passed around!
14. Sign off :-D

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-02-06 15:17:17 -07:00
Jonathan Druart d4ee7bd5f0
Bug 40946: Remove warning "Aborted connection" from Koha/Z3950Responder/ZebraSession.t
start_server from Net::Z3950::SimpleServer is going to fork and the DB
server is aborting the connection

db-1         | 2025-10-03 12:02:12 272 [Warning] Aborted connection 272 to db: 'koha_kohadev' user: 'koha_kohadev' host: '172.19.0.6' (Got an error reading communication packets)

Test plan:
  prove t/db_dependent/Koha/Z3950Responder/ZebraSession.t
=> Without this patch you will see a warning in the db container log
=> With this patch apply the warning no longer appears

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

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-02-06 15:17:13 -07:00
Pedro Amorim 7277f04342
Bug 36360: Add Illrequest to list of stuff to consider merging
Signed-off-by: Richard Bridgen <richard.bridgen@nhs.net>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-02-06 15:17:10 -07:00
Baptiste Wojtkowski 5262ff688b
Bug 41695: Fix rejecter in suggestion.pm
TEST PLAN:
1 - Apply tests patch
2 - Run 'prove t/db_dependent/Koha/Suggestions.t' -> it fails on
rejecter
3 - Apply this patch
4 - Run 'prove t/db_dependent/Koha/Suggestions.t' -> it works

Note: this patch also provide tests for remaining accessors in the
subtest

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-02-06 15:17:08 -07:00
Baptiste Wojtkowski ba0b968a5a
Bug 39721: Changes suggestion_ref in order to remove it
suggestion_ref is quite messy, it needs to be reworked in order to use
objects in suggestion.pl.

As far as I studied, it is used as
- the whole input from forms,
- the default content to input in a form
- the content that will be amended in order to propose another hash to
  modSuggestion. However, ModSuggestion will be removed so we don't need
  such a hash
- every suggestion that need to be updated using the "change selected
  suggestion" tool
- create the object suggestion_only, whose purpose is still unclear to
  me.

As a result it is created by :
> 25 my $suggestion_ref = { $input->Vars };
And by removing a number of keys depending on the use of suggestion_ref
in the script.

In this patch, we remove every code made to use suggestion_ref as the
source object for form and use another variable, $stored_suggestion which is an object.

In next patch we aim at fully removing $suggestion_ref, which is still
used by ModSuggestion

Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-02-06 15:17:06 -07:00
Tomás Cohen Arazi 8895b74bee
Bug 41619: Add Koha::CSV
This patch introduces Koha::CSV, a wrapper around Text::CSV_XS that
provides consistent defaults and methods for CSV generation across Koha.

The class:
- Inherits CSV delimiter from CSVDelimiter system preference
- Enforces security defaults (binary=1, formula='empty')
- Provides convenient methods for common CSV operations
- Allows per-instance configuration overrides

This establishes a foundation for standardizing CSV exports throughout
Koha, eliminating inconsistencies in CSV generation and providing a
testable, maintainable approach to CSV handling.

Test plan:
1. Apply patch
2. Run:
   $ ktd --shell
  k$ prove t/Koha/CSV.t
=> SUCCESS: Tests pass!
3. Tests cover:
   - Default initialization with CSVDelimiter preference
   - Preference value inheritance (comma, semicolon, tabulation)
   - Constructor parameter overrides
   - add_row() method with various data types
   - combine() and string() methods
   - print() to filehandle
   - Proper quote escaping and empty field handling
4. Sign off :-D

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

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-02-06 15:17:02 -07:00
Jonathan Druart 849f67988f
Bug 41076: Adjust our perl tidiness for v20250105
Generated using
  `perl misc/devel/tidy.pl --perl`

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-02-05 09:03:51 -07:00
Pedro Amorim 9a4e6a87df
Bug 39971: Add query param
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-30 10:54:25 -07:00
Pedro Amorim 20e00d408f
Bug 39971: Add POD
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-30 10:54:24 -07:00
Pedro Amorim e0824a79bf
Bug 39971: Move patron_attributes_form method to a class
This makes it reusable, documentable, and testable.

This is changing code without adding a new feature or fixing a bug.
The first test plan should be to just make sure that the existing functionality is kept intact, i.e. rendering and saving the patron attribute types in the form.

As to why we need this, we're maintaining the ILL Actions plugin where we have a feature to quickly add a patron. This is designed to be as minimal as possible, but if there are any mandatory patron attribute types, those need to be considered.
To test this:
1) Apply patches and enable ILLModule syspref.
2) Install the plugin:
https://github.com/openfifth/koha-plugin-ill-actions/releases/tag/v2.4.0
3) Add a mandatory patron attribute type, you can edit the existing one in k-t-d, visit:
   <staff_url>/cgi-bin/koha/admin/patron-attr-types.pl?op=edit_attribute_type&code=SHOW_BCODE
5) Tick the 'Staff interface mandatory' checkbox
6) Create a new ILL request, visit:
   <staff_url>/cgi-bin/koha/ill/ill-requests.pl?method=create&backend=Standard
7) Notice there's a '+Add new user' link next to the cardnumber input at the bottom of the form. Click that.
8) Notice there's a 'Additional attributes and identifiers' section. This is only possible (without writing it again) because of the patches here.

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-30 10:54:24 -07:00
Jonathan Druart e7325583f3
Bug 39438: (bug 38446 follow-up) Add agreement_period to /erm/extended_attribute_types
Sponsored-by: Karlsruhe Institute of Technology (KIT)
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-30 10:54:11 -07:00
Martin Renvoize b44f85e1b2
Bug 39438: Add DBIC schema relationships for agreement period additional fields
This patch adds the required DBIx::Class relationship definitions to
Koha::Schema::Result::ErmAgreementPeriod to support additional fields
and extended attributes on agreement periods.

Two has_many relationships are added:
- additional_field_values: links to all additional field values
- extended_attributes: alias for additional_field_values

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-30 10:54:11 -07:00
Matt Blenkinsop 080fccc0c5
Bug 39438: Add additional fields support to ERM agreement periods
This patch enables additional fields functionality for agreement periods
in the ERM (Electronic Resource Management) module, allowing libraries
to define custom metadata fields for agreement period records.

Changes include:
- Update Koha::AdditionalField to support erm_agreement_periods table
- Modify API definitions to include extended_attributes in responses
- Add erm_agreement_periods option to additional fields admin interface
- Enhance Vue components to display and manage additional field values
- Update ShowElement component to handle period-specific attributes

Test plan:
1. Navigate to Administration > Additional fields
2. Create new fields for "Agreement periods"
3. Edit an ERM agreement and add/edit period information
4. Verify additional fields appear and can be populated
5. Confirm values are saved and displayed correctly

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-30 10:54:10 -07:00
Pedro Amorim 6473a06916
Bug 41478: Refactor: Readability + Never nester
1) Install the following dummy backend plugin:
https://github.com/openfifth/koha-ill-backend-plugin/releases/tag/v2.0.9
2) Sys prefs preparation: Enable ILLModule, ILLOpacUnauthenticatedRequest and check PluginBackend on AutoILLBackendPriority
3) Logout, create a new Unauthenticated ILL request on the OPAC, visit:
<opac_url>/cgi-bin/koha/opac-illrequests.pl?op=create&backend=Standard
4) Fill in the mandatory top fields (first name, last name, email address and library)
5) Pick 'Book' for type and enter 'green' in title. This will cause the dummy plugin to be available in the AutoILL logic.
6) At the bottom of the form, on the "Verification" captcha, purposely input a wrong captcha e.g. '123'
7) Click 'Create'. Notice an odd looking form is presented, this is the dummy backend form, but it should present the 'Standard' form when using AutoILLBackendPriority as that was also the form we were presented with originally.
This happens because currently it's the backend that delegates back to Koha what template to render. When using AutoILLBackendPriority, however, Koha should handle this template delegation instead and present the Standard form.
8) Apply patches. Repeat test plan. Notice that now on step 7 you get the correct form, and error message (coming from Standard, as expected when using AutoILLBackendPriority).
9) Input the correct captcha this time
10) Confirm the created request landed in the PluginBackend backend.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-30 10:54:06 -07:00
Pedro Amorim 53a78c501d
Bug 41478: Render Standard form on OPAC if failed_captcha and AutoILLBackendPriority
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-30 10:54:05 -07:00
Lucas Gass 34bb9ad633
Bug 26993: DBIC changes
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 14:16:06 -07:00
Lucas Gass edc7b29b17
Bug 26993: Use last_returned_by->delete_all
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 14:16:04 -07:00
Lucas Gass 9d4b4efffd
Bug 26993: (follow-up) Rename last_returned_by_all as last_borrowers
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 14:16:04 -07:00
Lucas Gass cf018a0bf4
Bug 26993: (follow-up) Return Koha::Patron resultset from last_returned_by_all
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 14:16:03 -07:00
Jonathan Druart c05bc3ad7e
Bug 26993: Use a txn
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 14:16:03 -07:00
Lucas Gass e25ecf6757
Bug 26993: last_returned_by_all should return an array ref
Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 14:16:02 -07:00
Lucas Gass 4b04138ed1
Bug 26993: Implement changes
Test plan:

1. APPLY patch, restart_all, updatedatabase
2. Search for the StoreLastBorrower system preference, it should now allow you to enter a number of borrowers to store
3. Set the pref to 3.
4. Check an item out to any patron. Then immediately check it back in.
5. On catalogue/moredetail.pl?biblionumber=X ( where X is you biblionumber ) you should see a "Last returned by:" entry with the correct cardnumber for the borrower.
7. Confirm this is right in the database with: SELECT * FROM items_last_borrower where itemnumber = X; ( Where X is your itemnumber )
8. Repeat step 4 to a different borrower.
9. Repeat steps 5 and 6. You should see 2 cardnumbers of each of the borrowers on catalogue/moredetail.pl?biblionumber=X
10. Repeat step 4 with another new borrower.
11. Repeat steps 5 and 6. You should see 3 cardnumbers of each of the borrowers on catalogue/moredetail.pl?biblionumber=X
12. Choose a different item and repeat steps 4 - 11 for this item.
13. Now set the StoreLastBorrower preference to 0.
14. Using the original item from step 4, check something out to a patron and immediately check it back in.
15. catalogue/moredetail.pl?biblionumber=X should NOT have an entry for "Last returned by:"
16. Check the database, all entries for the itemnumber from step 14 should be deleted.

Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 14:16:01 -07:00
Lucas Gass 19ef8940f9
Bug 26993: Schema changes
Signed-off-by: Trevor Diamond <trevor.diamond@mainlib.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 14:16:00 -07:00
David Cook b86095ffe7
Bug 40719: Explicitly turn off RELATIVE for TemplateUtils
This change explicitly turns off RELATIVE in Koha/TemplateUtils.pm

Test plan (Koha/TemplateUtils.pm):
0. Apply the patch and koha-plack --restart kohadev
1. Go to http://localhost:8081/cgi-bin/koha/tools/letter.pl
2. Click "New notice" and choose "reports"
3. Add the following to the report:
[% IF ( x == 1 ) %]
One
[% ELSE %]
Two
[% END %]
4. Go to http://localhost:8081/cgi-bin/koha/reports/guided_reports.pl?phase=Use%20saved
5. Create a report like the following:
SELECT biblionumber FROM biblio;
6. Click "Run with template" and choose the Reports template you made
7. Note that the output shows "Two"
8. Edit your Reports notice and include the following:
[% INSERT ../etc/passwd %]
9. Re-run the report using "Run with template"
10. Note that the output shows the regular SQL results (ie template transform not successful)

Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:30 -07:00
Kyle M Hall 356903a96a
Bug 32370: (QA follow-up) Add https to license url, use Test::NoWarnings
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:26 -07:00
Tomas Cohen Arazi 71fce974e3
Bug 32370: Adapt Koha::Auth::Identity::Provider
This patch adapts the Koha::Auth::Identity::Provider class to
make use of this, and also to prove the behavior is correct (expected
results, exceptions, encoding, etc).

To test:
1. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Koha/Auth/Identity/Provider.t \
           t/db_dependent/api/v1/idp.t
=> SUCCESS: Identity provider related tests pass!
2. Apply this patches
3. Repeat 1
=> SUCCESS: Tests still pass!
4. Sign off :-D

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:26 -07:00
Tomas Cohen Arazi 6d4965f2d3
Bug 32370: Provide a generic set of tools for JSON fields
This patch introduces a new class for extending Koha::Object-based
classes so they have reusable ways to deal with JSON encoded fields.

As documented in the POD, classes can now

```perl
use base qw(Koha::Object Koha::Object::JSONFields);
```

and will have the following methods available:

* decode_json_field
* set_encoded_json_field

For convenience, the Koha::Auth::Identity::Provider class is tweaked to
make use of this, and also to prove the behavior is correct (expected
results, exceptions, encoding, etc).

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

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-22 10:02:25 -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
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
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
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
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 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
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
Martin Renvoize ac64e18ce6
Bug 40811: (follow-up) Fix list context bug and add comprehensive tests
This patch fixes a critical bug where plain_text_password() was called
in list context during hash construction. When a transport has no
password, the method's bare 'return' statement returns an empty list ()
in list context rather than undef, causing all subsequent key-value
pairs to shift positions. This resulted in malformed connection
parameters being passed to Net::SFTP::Foreign and Net::FTP.

Example of the bug:
  my %hash = (
    user => 'john',
    password => $self->plain_text_password,  # Returns () when no password
    timeout => 10
  );
  # Results in: (user => 'john', timeout => 10) instead of
  # (user => 'john', password => undef, timeout => 10)

Changes to code:
- Wrap plain_text_password calls with scalar() to force scalar context
  in both FTP.pm and SFTP.pm
- Make SFTP key and password authentication mutually exclusive using
  ternary operator
- Prefer key-based auth over password when both are available (SFTP)

Test plan:
1. Run t/db_dependent/Koha/File/Transport/FTP.t - should pass
2. Run t/db_dependent/Koha/File/Transport/SFTP.t - should pass
3. Verify tests cover:
   - Scalar context behavior with no password
   - FTP authentication with proper parameter passing
   - SFTP password-only authentication
   - SFTP key-only authentication
   - SFTP key preference when both key and password exist

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 15:28:17 -07:00
Martin Renvoize b75d07acd5
Bug 40811: Implement dual API for file transports with simplified auto-management
This patch implements a dual API design for Koha::File::Transport, providing
both a simplified auto-managing API and a traditional explicit API for maximum
flexibility and ease of use.

DUAL API DESIGN
===============

Simplified API (Recommended):
  - Automatic connection management (no connect/disconnect needed)
  - Flexible per-operation directory control via options hashref
  - Stateless operations safe for concurrent usage

  Example:
    $transport->upload_file($local, $remote, { path => '/custom/' });
    $transport->download_file($remote, $local);  # Uses download_directory
    $transport->list_files({ path => '/incoming/' });

Traditional API (Explicit Control):
  - Manual connection/directory management when needed
  - Stateful directory operations via change_directory()
  - Ideal for multiple operations in the same directory

  Example:
    $transport->change_directory('/work/');
    $transport->upload_file($local, 'file1.txt');
    $transport->upload_file($local, 'file2.txt');
    my $files = $transport->list_files();

The APIs can be mixed - calling change_directory() explicitly switches to
manual mode and disables auto-management for subsequent operations.

STANDARDIZED TEMPLATE METHOD PATTERN
=====================================

All transport methods now follow a consistent pattern with clear separation
between public API (parent class) and protocol implementation (subclasses).

Public methods in Koha::File::Transport:
  - connect()          → Resets directory state, calls _connect()
  - disconnect()       → Resets directory state, calls _disconnect()
  - change_directory() → Sets manual mode flag, calls _change_directory()
  - upload_file()      → Manages connection/directory, calls _upload_file()
  - download_file()    → Manages connection/directory, calls _download_file()
  - list_files()       → Manages connection/directory, calls _list_files()
  - rename_file()      → Ensures connection, calls _rename_file()

Subclass responsibilities (SFTP/FTP/Local):
  - Implement _connect() - Protocol-specific connection logic
  - Implement _disconnect() - Protocol-specific disconnection logic
  - Implement _change_directory() - Protocol-specific directory change
  - Implement _upload_file() - Protocol-specific upload logic
  - Implement _download_file() - Protocol-specific download logic
  - Implement _list_files() - Protocol-specific listing logic
  - Implement _rename_file() - Protocol-specific rename logic
  - Implement _is_connected() - Protocol-specific connection check

Test plan:
  prove t/db_dependent/Koha/File/Transports.t

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 15:28:17 -07:00
Tomás Cohen Arazi ac9944f7b0
Bug 29668: Adapt to current guidelines
The added patches make some changes:

* $c->req->json is used to access the request body, as explained by the
  Mojolicious OpenAPI plugin author it should be done.
* Instead of calling `$basket->to_api` we use the `$c->objects->to_api`
  helper which deals with calling context (embeds, etc). Otherwise it
  would require doing it manually if embeds are added.
* Tests are grouped together the same way the rest of them are.

To test:
1. Apply this patches
2. Run:
   $ ktd --shell
  k$ prove t/db_dependent/api/v1/acquisitions_baskets.t
=> SUCCESS: Tests pass!

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 15:28:16 -07:00
Julian Maurice 5e0a72f8a8
Bug 29668: Add API route to add a basket
Example usage:

POST /api/v1/acquisitions/baskets

{
    "vendor_id": 1,
    "name": "Basket #1",
}

Test plan:
1. Try requesting this endpoint with your favorite API tool
   (I recommend https://github.com/frigus02/RESTer)
2. Run `prove t/db_dependent/api/v1/acquisitions_baskets/post.t`

Edit (tcohen): Re-did the commit with some fixes in the spec

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 15:28:09 -07:00
Pedro Amorim 63d1023317
Bug 41237: (QA follow-up): Utilize available logged in user object
Instead of re-fetching the patron object.

This also adjusts tests:
prove t/db_dependent/Koha/ILL/Requests.t

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 07:44:21 -07:00
Pedro Amorim ee348649a2
Bug 41237: Update fetch of patron's branchcode to search additional_contents by
Signed-off-by: Stephen Graham <s.graham4@herts.ac.uk>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 07:44:20 -07:00
Nick Clemens aef17e613d
Bug 40846: Improve handling of ignored records
Currently, a job is marked failed if there are no records added or updated.
We should take ignored records into account.

Additionally, I mark the job failed when the number of records processed
doesn't equal the number of records in the batch.

To test:
1) Export some records from your Koha, include some with items
2) Stage and import those records into Koha, matching on biblionumber,
   ignoring matcheds, updating items
3) View the import job, it is marked failed
4) View the batch, all records imported
5) Apply patch, restart all
6) Stage/import as before
7) Job is now marked finished
8) Records imported as before

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 07:44:20 -07:00
Jonathan Druart e549d21441
Bug 40777: Add POD
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 07:44:19 -07:00
Jonathan Druart 85b8096284
Bug 40777: Add tests for errors_in_marc
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 07:44:16 -07:00
Jonathan Druart 4551a2d1ba
Bug 40777: Add tests for invalid_item_type
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 07:44:16 -07:00
Jonathan Druart 368e8124c5
Bug 40777: Add tests for invalid_item_library and no_item_type
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 07:44:15 -07:00
Jonathan Druart a4c0746370
Bug 40777: Move all biblio tests to the new package
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 07:44:15 -07:00
Jonathan Druart b88dd24139
Bug 40777: Introduce Koha::Database::DataInconsistency
test plan:
1. Export a record with an item from the staff interface as MARCXML (Save > MARCXML).
2. Edit the file and remove the 952$a (home library) and 952$b (current library).
3. Delete the item and record in the staff interface.
4. Import the exported record and item from the MARCXML file:
   - Cataloging > Import > Stage for import
     . Settings > Format: MARCXML
   - Stage for import
   - View batch link on the job details page (assuming successfully staged)
     . New record framework: change to Books, Booklets, Workbooks
5. Turn on the browser developer tools and view the console.
6. Access the details page for the new record.
7. Note that you get:
   - A "Processing" dialog box on screen
   - A browser pop-up window/dialog box with:
       Something went wrong when loading the table.
       500: Internal server error
   - Click OK
   - The console shows:
      . Failed to load resource: the server responded with a status of 500 (Internal Server Error)
      . Got 500 (Internal Server Error)
      . DataTables warning: table id=holdings_table - Ajax error. For more information about this error, please see https://datatables.net/tn/7
8. Run misc/maintenance/search_for_data_inconsistencies.pl, you get these result (the itemnumber may be different):
    == Not defined items.homebranch and/or items.holdingbranch ==
    	* Item with itemnumber=973 does not have home and holding library defined
    => Edit these items and set valid homebranch and/or holdingbranch
    (↑↑ don't do it, it's part of the message content)
9. Apply the patch.
10. Restart everything.
11. Refresh the details screen for the imported record.
12. You now get the same as step 7, but with added "Have a look at the "Audit" button in the toolbar" text in the browser pop-up dialog box:
    - A "Processing" dialog box on screen
    - A browser pop-up window/dialog box with:
        Something went wrong when loading the table.
        500: Internal server error
        Have a look at the "Audit" button in the toolbar
    - Click OK
    - The console shows:
      . GET http[URL for the record....] 500 (Internal Server Error)
      . Got 500 (Internal Server Error)
      . DataTables warning: table id=holdings_table - Ajax error. For more information about this error, please see https://datatables.net/tn/7
13. Click on the Audit button.
14. You get a yellow box at the top of the record with:
      Errors found
      Item with itemnumber=973 does not have home and holding library defined
    (Note that there is still the "Processing" dialog box, you can edit the item by select the "Items" option in the sidebar menu and then edit the item details - the home and current library files will be auto-populated with the current library, Centerville with KTD)
15. Repeat step 8, you get the same results.
16. The tests pass: prove t/db_dependent/Koha/Database/DataInconsistency.t
17. Check the details page for another record that doesn't have any data issues - note the 'Audit' toolbar item, and if clicked should show a blue box at the top of the record with "No data inconsistency found."

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-01-21 07:44:13 -07:00