This patch implements an algorithm for selecting the item that would
leave the largest gap after the proposed booking to maximize the
opportunity for future bookings.
Key Changes:
Koha::Booking:
- Added set_itemtype_filter() method for transient itemtype parameter
- Added _select_optimal_item() method using single aggregated query
* Groups bookings by item_id with MIN(start_date)
* Selects items with no future bookings (optimal)
* Among items with bookings, selects one with latest next booking
* O(1) complexity - single database query with GROUP BY
- Updated _assign_item_for_booking() to use optimal selection
* Filters by itemtype when itemtype_id is provided
* Replaces previous random selection (RAND())
API Changes:
- Added itemtype_id parameter support to add() endpoint
- Added itemtype_id parameter support to update() endpoint
- Validates exactly one of item_id or itemtype_id is provided
- itemtype_id is transient - not persisted to database
- Extracted and applied via set_itemtype_filter() before store()
Architecture:
- itemtype_id is NOT a database column (transient only)
- Used as selection criterion, then discarded
Test plan:
1. Apply patch and restart services
2. Create "any item" booking via staff interface
3. Verify item with longest future availability is selected
4. Test via API with itemtype_id parameter
5. Verify itemtype_id is not persisted to database
6. Run t/db_dependent/Koha/Booking.t
7. Run t/db_dependent/api/v1/bookings.t
Signed-off-by: Kristi Krueger <kkrueger@cuyahogalibrary.org>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
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>
This patch updates the swaager definition to have the correct format
To test:
1 - Enable issue notes: AllowCheckoutNotes preference
2 - Issue an item to a patron
3 - Sign in to opac as that patron, add a note
4 - Have staff client open and a second tab try:
http://localhost:8081/api/v1/checkouts/
5 - Error "message":"Does not match date format.","path":"\/body\/0\/note_date"
6 - Apply patch, yarn build, restart all
7 - Refresh the page
8 - Success!
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
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>
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>
This patch adds the primary_contact_method field to the api response for patrons
To test:
1 - GET http://localhost:8081/api/v1/patrons/51
2 - Look for primary_contact_method, it's not there
3 - Apply patch
4 - GET http://localhost:8081/api/v1/patrons/51
5 - Look for primary_contact_method, it's not there
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Required for the follow-up ERMCounts widget
Sponsored-by: UKHSA (UK Health Security Agency)
Signed-off-by: Jeremy Evans <Jeremy.Evans@ukhsa.gov.uk>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Updates the OpenAPI definitions to support additional fields on vendor
records.
This adds:
- extended_attributes array field to vendor schema definition
- _strings field for localized/computed string representations
- extended_attributes and +strings to available embed options
These changes allow the API to expose and accept additional field data
when retrieving or modifying vendor records via the REST API.
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Use should use coded_values for the library and item type column so that
we can search using the code and the description.
With this patch we now have a dropdown list with the libraries and item
types in the table's headers.
Test plan:
0. Turn on AllowHoldItemTypeSelection
1. Create a hold and select an item type
Note: I think there is a bug if you select it from "Hold next available
item", use "Hold details". Please confirm?
2. Go to the holds history view
3. Filter and search by item type description and code. Same for
library.
Use the dropdown list in the headers.
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>
This follow-up removes the security vulnerability of storing plaintext
passwords in the sip_accounts table. The SIP2 system now relies entirely
on Koha's secure password authentication.
Changes:
- Remove plaintext password comparison from login_core() and telnet_transport()
- Remove login_password column from sip_accounts table
- Update database schema files and atomic update
- Remove password field from API definitions and Vue form
- Update all tests to remove login_password references
Authentication now works in two stages:
1. Access control: Check if userid exists in sip_accounts (allowlist)
2. Authentication: Validate password against hash in borrowers table
This maintains SIP access control while eliminating plaintext password
storage. Staff users authenticate with their Koha password (securely hashed).
Test plan:
1. Run updated tests to verify they pass
2. Verify SIP2 authentication works with staff user credentials
3. Confirm no plaintext passwords are stored
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
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>
This patch makes the API representation of the identity providers
domains match the new metadata.
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch provides a link in the left hand menu so that from a vendor record you can access ERM agreements and licenses relevant to that vendor
Test plan:
1) Apply patch and reset_all
2) Navigate to ERM and create some agreements and licenses that link to a vendor and some that don't
3) Navigate to a vendor record
4) There should be links in the left hand menu for agreements and licenses
5) Click on these and you should be taken to ERM and see a filtered table based on that vendor
Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Hold group target hold:
The hold that is set as the hold group's target. If a hold group has a
hold target, subsequent check-ins that would 'trap' items to the
remaining holds in the group are instead skipped.
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Anneli <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
list and add actions:
/patrons/{patron_id}/hold_groups
New test file:
prove t/db_dependent/api/v1/patrons_hold_groups.t
Signed-off-by: Anneli <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch adds the option to embed the return value of the
`late_since_days` method in basket objects in the REST API.
It does so by just adding it to the list of embeds in the spec. It is
added in every place baskets can be returned.
Signed-off-by: Emmi Takkinen <emmi.takkinen@koha-suomi.fi>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch adds the required mapping in
`Koha::Acquisition::Order::Claim` and adds it's definition to the API
spec.
To test:
1. Apply the patches
2. Verify the mapping makes sense and conforms to the current style and
API coding guidelines.
3. Run:
$ ktd --shell
k$ prove xt/api.t
=> SUCCESS: Tests pass
4. Sign off :-D
Signed-off-by: Emmi Takkinen <emmi.takkinen@koha-suomi.fi>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Test plan:
Apply the "tests" patch first
prove xt/api.t
=> fail
Apply this patch
=> pass
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch renames the entire API structure from SFTP-specific to generic
file transport terminology to reflect the polymorphic nature of the system.
API Changes:
- Endpoints: /config/sftp_servers -> /config/file_transports
- Parameters: sftp_server_id -> file_transport_id
- Definitions: sftp_server -> file_transport
- Controller: Config::SFTP::Servers -> Config::File::Transports
File Changes:
- api/v1/swagger/definitions/sftp_server.yaml -> file_transport.yaml
- api/v1/swagger/paths/config_sftp_servers.yaml -> config_file_transports.yaml
- Koha/REST/V1/Config/SFTP/Servers.pm -> Koha/REST/V1/Config/File/Transports.pm
- t/db_dependent/api/v1/sftp_servers.t -> file_transports.t
Updated References:
- swagger.yaml: paths, definitions, parameters, tags
- Template JavaScript: API URLs and variable names
- Controller: package name, variable names, error messages
- Tests: endpoints, parameters, descriptions
- API mapping: to_api_mapping field name correction
To test:
1. Apply this patch
2. Run: yarn api:bundle (to regenerate swagger bundle)
3. Run: prove t/db_dependent/api/v1/file_transports.t
4. All API tests should pass
5. Verify admin interface uses new API endpoints
6. Test CRUD operations work correctly
The API now consistently uses 'file_transports' terminology matching
the polymorphic file transport system that supports FTP, SFTP, and
future transport types.
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
We now use background jobs triggered by Transport->store to update the
connection status.
Status is now a json blob with more details, so we update the api
definition to reflect that.
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch adds a central FTP/SFTP management UI, with an associated
database object and class, plus the beginnings of an API. We can use
this code as a building block for adding FTP/SFTP connections to
other parts of the system, as well as to improve the usability of the
EDI transports. It is also now possible to test these connections
from within the Koha UI.
To test:-
You will need access to an FTP or SFTP server
Contact me if you need a disposable FTP/SFTP server
a) Go to Koha Administration
b) Notice no FTP/SFTP referenced on this page
c) APPLY PATCH, reset_all
d) Create new user, let's say sftpuser
e) Set permissions for new user to include:
1) catalogue
2) parameters -> manage_sftp_servers
f) Log in with this new user, go back to Koha Administration
1) Notice the FTP/SFTP servers option
g) Undo step e2) for the sftpuser via the koha admin user
1) Refresh the Koha Administration page as the sftpuser
2) Notice how FTP/SFTP servers has disappeared
h) Back to koha admin, go to Koha Administration -> FTP/SFTP Servers -> New
i) Complete form depending on the FTP or SFTP server you have access to, Submit
1) Notice you are prompted to confirm before saving
j) Select Edit, observe your details are the same, and Submit again
k) Repeat step J one additional time
l) Select Test, observe all tests passing
m) Select Delete, confirm deletion, and observe server disappear
n) Optionally, run prove on new tests
1) t/Koha/Auth/Permissions.t
2) t/db_dependent/Koha/SFTP/Server.t
3) t/db_dependent/api/v1/sftp_servers.t
o) SIGN-OFF
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
TO TEST:
0. APPLY PATCHES, updatedatabase, restart_all
1. Create a user with limited permissions, making sure you give them the "batch_modify_holds" permission
2. Login as chosen patron.
3. Navigate to Tools page.
4. Note there's a link "Batch modify holds".
5. Remove permission from user.
6. Link to new tool is not displayed.
7. Navigate to new tool Tools->Batch modify holds.
8. Fill in some criteria to search holds with.
9. Confirm that holds found match your search criteria.
10. Set e.g. new expiration date for all or just selected holds.
11. Confirm that holds were modified as they should have.
12. Confirm this also from database.
13. Find holds with a found/waiting status.
14. Attempt to modify their suspend status.
15. Alert box with text "One or more holds have found status and can't be suspended." should be displayed.
16. Play around, test different modifications.
17. Create SQL report which contains column for reserve_id.
18. e.g "SELECT reserve_id FROM reserves limit 10".
19.. Run report.
20. Over report select "Batch operations" should be displayed and under that there should be option "Batch modify holds".
21. Click "Batch modify holds" option.
22. Confirm that holds displayed in "Batch mofidy holds" tool are same as found with your report.
23. Do a holds search that will bring up multiple pages of results
24. Try selecting some holds from different pages to modify
25. Ensure all selected holds are being modified
26. Play around, test different modifications.
Sponsored-by: Koha-Suomi Oy
Signed-off-by: Jason Robb <jrobb@sekls.org>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Brought to light by accessing the following page with the feature enabled:
http://localhost:8081/cgi-bin/koha/members/holdshistory.pl?borrowernumber=51
Also by running the following tests file before this patch:
t/db_dependent/api/v1/holds.t
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
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>
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>
This patch makes holds endpoints be allowed to embed strings.
To test:
1. Use your favourite REST tool to hit /api/v1/holds
2. Add the `x-koha-embed: +strings` header.
=> FAIL: The API rejects because it is not equiped with the feature.
3. Apply this patches
4. Run:
$ ktd --shell
k$ yarn api:bundle
k$ koha-plack --restart kohadev
5. Repeat 2
=> SUCCESS: It works!
6. Sign off :-D
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
We have insert_final_newline = true to ensure files will contain a new
line at the end. However we have seen commits with "No new line" added
in the git log.
We should have a xt test to prevent more occurrences.
We should also have a test at the QA script level:
https://gitlab.com/koha-community/qa-test-tools/-/issues/96
Test plan:
prove xt/find-missing-new-lines-at-the-end-of-file.t
should return green.
Remove the new line at the end of a file, eg.
vim -b mainpage.pl
:set noeol
:wq
Now
prove xt/find-missing-new-lines-at-the-end-of-file.t
is failing on mainpage.pl.
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
The test added in xt/api.t was not fully accurate, we skipped the
columns that have the same name as the api attribute (ie. the ones not
part of to_api_mapping)
Test plan:
prove xt/api.t should pass
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>