Commit Graph

59586 Commits

Author SHA1 Message Date
Lisette Scheer 96bb1ec97d
Bug 40827: Add context to plugin wrapper for report plugins
This patch updates the plugin wrapper to include the reports menu and have the breadcrumbs list reports instead of admin or tools when method="report"

To Test:
1. Install the Kitchen Sink Plugin
2. Navigate to Reports->Report plugins->Run Report.
3. Observe the admin menu shows
4. Apply the patch
5. Repeat step 2
6. Observe the report menu shows and the breadcrumbs are for the report module.
7. Check that the tools and configuration show the appropriate tool/admin context.

Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:42 -07:00
David Nind 88ffb14749
Bug 41015: (QA follow-up) Update labels
Updates to the search forms and labels:
- Use sentence case for the Z39.50/SRU search form label
- Update title text for the advanced search link
- Update the title for the advanced search pop-up window to
  "Advanced Z39.50/SRU search"

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:42 -07:00
Andrew Fuerste Henry f98c74b987
Bug 41015: Label Z39.50/SRU search in advanced cataloging
The advanced cataloging editor has a Z39.50/SRU search form
included on the page, but it's just labeled "Search," so it's
not at all clear what it's for.

Test plan:
1. Enable and go to advanced cataloging editor.
2. Note that the Z39.50/SRU search form is just labeled
   "Search".
3. Apply patch, reload page.
4. Note that it's now labeled "Z39.50/SRU search".
5. Note that the advanced search pop-up window is now
   labelled "Advanced Z39.50/SRU search".

Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:41 -07:00
Lucas Gass 06e04d3a02
Bug 20253: DBIC
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:41 -07:00
Lucas Gass 60803c8840
Bug 20253: DBRev 25.06.00.031
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:40 -07:00
Martin Renvoize ebfca0edb4
Bug 20253: (follow-up) Fix undefined variable $b and test plan count
In bug 40587 we renamed a variable from $b to $basketno. After rebasing,
the auto-orders blocking code had a bug where it referenced an undefined
variable $b instead of $basketno when checking for PO number conflicts.
This caused warnings: "Use of uninitialized value $Koha::EDI::b in exists"

This patch:
- Renames $b to $basketno throughout the conflict checking code
- Updates test plan from 7 to 8 to match actual subtest count

Test plan:
1. Run prove t/db_dependent/Koha/EDI.t
2. Verify all tests pass without warnings
3. Confirm auto-orders blocking works correctly for duplicate PO numbers

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:40 -07:00
Martin Renvoize e5add0fd96
Bug 20253: (follow-up) Update tests for Bug 38489 rebase
With the move to Koha::File::Transports we need to update the tests
introduced in this patchset to match the others by generating a 'local'
transport and using that.

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:39 -07:00
Martin Renvoize 943bfe097e
Bug 20253: (follow-up) Block auto_orders and UI ordering for duplicate PO numbers
When po_is_basketname is enabled for a vendor, duplicate purchase order
numbers should prevent both automatic ordering (auto_orders) and manual
UI-triggered ordering to avoid conflicts with existing baskets.

This patch implements blocking functionality that:

1. Auto-orders blocking:
   - Tracks baskets with PO number conflicts during quote processing
   - Skips auto-ordering for baskets with duplicate PO numbers
   - Logs clear warnings about blocked baskets

2. UI basket ordering blocking:
   - Adds duplicate checking in create_edi_order function
   - Returns detailed error information when conflicts detected
   - Prevents EDI order creation for conflicting baskets

3. User-friendly error handling:
   - Updates basket.pl to handle duplicate PO number errors
   - Stays on basket page to display error messages
   - Provides clear messaging about conflicts and resolution steps

4. Template messaging:
   - Adds clear error message explaining duplicate PO conflicts
   - Shows which existing basket uses the same PO number
   - Guides users on next steps to resolve the issue

This ensures data integrity and prevents order processing conflicts
while providing clear feedback to users about duplicate PO number
issues.

Test plan:
1. Set up a vendor with EDI account and enable "po_is_basketname"
2. Create a basket with a specific name (e.g., "PO12345")
3. Process an EDIFACT quote that contains the same PO number:
   - If auto_orders is enabled: verify the new basket is created but NOT automatically ordered
   - Check the logs show "Auto-order blocked" message
4. For UI testing, create another basket manually with the same name
5. Try to generate EDI order via "Generate EDI order" button
6. Verify: Error message appears stating duplicate PO number conflict
7. Verify: Basket remains open (not closed)
8. Verify: Error message shows which existing basket uses the PO number
9. Test with po_is_basketname disabled: verify normal operation continues
10. Test with unique PO numbers: verify orders process normally

Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Sponsored-by: Royal Borough of Kensington and Chelsea <https://www.rbkc.gov.uk/>
Sponsored-by: OpenFifth <https://openfifth.co.uk/>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:39 -07:00
Martin Renvoize 81087d7584
Bug 20253: (follow-up) Use purchase order number in BGM segment for outgoing ORDER messages
When vendors are configured to use purchase order numbers for basket naming,
the purchase order number should be included in outgoing ORDER messages as
the document message number in the BGM segment for proper EDI workflow continuity.

According to EDIFACT specifications, the purchase order number from incoming
quote messages (RFF+ON segments) should be used as the document message number
in the BGM segment of outgoing ORDER messages, rather than as a separate RFF+ON
segment.

This follow-up ensures that:
1. Purchase order numbers from incoming QUOTE messages are preserved
2. The same purchase order numbers are sent back in ORDER messages via BGM segment
3. Vendors receive the reference numbers they expect for order processing in the
   correct format.

Implementation:
- Added get_purchase_order_number() method to extract PO number from basket name
  when vendor is configured with 'po_is_basketname'
- Modified beginning_of_message() to accept purchase order number parameter
- Uses purchase order number in BGM segment when available, falls back to basketno
- Added comprehensive tests for purchase order number handling in ORDER messages

Test Plan:
1. Apply patches
2. Configure a vendor EDI account with "Basket name source" = "Purchase order number"
3. Process a QUOTE message containing RFF+ON segment
4. Verify basket is created with purchase order number as name
5. Generate ORDER message from the basket
6. Verify ORDER message contains purchase order number in BGM segment
7. Run tests: prove t/db_dependent/Koha/Edifact/Order.t

This completes the round-trip EDI workflow for purchase order number handling
according to EDIFACT standards: Quote RFF+ON → Basket Name → Order BGM

Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Sponsored-by: Royal Borough of Kensington and Chelsea <https://www.rbkc.gov.uk/>
Sponsored-by: OpenFifth <https://openfifth.co.uk/>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:38 -07:00
Martin Renvoize 1e2e89e43f
Bug 20253: (follow-up) Make basket name read-only when derived from EDI purchase order number
When a basket is created from an EDI quote with the vendor EDI account configured
to use purchase order numbers, the basket name should be protected from changes
to maintain the integrity of the purchase order number reference.

This patch:
- Makes the basket name field read-only in the UI when the basket was created
  from EDI with purchase order number setting
- Adds explanatory text when the field is protected
- Implements server-side protection to prevent basket name changes even if
  the UI is bypassed
- Preserves the original purchase order number derived name

Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Sponsored-by: Royal Borough of Kensington and Chelsea <https://www.rbkc.gov.uk/>
Sponsored-by: OpenFifth <https://openfifth.co.uk/>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:38 -07:00
Martin Renvoize 458608b9c4
Bug 20253: (follow-up) Add duplicate purchase order number validation
When processing EDI quotes with purchase order numbers, validate that the
purchase order number is unique for the vendor to prevent operational
confusion. The validation:

- Checks for existing baskets with the same purchase order number and vendor
- Includes both open and closed baskets in the uniqueness check
- Logs an error with the raw RFF+ON segment and details to the edifact_errors table
- Continues processing (non-blocking) to prevent data loss
- Provides system log warnings for monitoring

The error logging includes:
- Section: Raw RFF+ON segment (e.g., "RFF+ON:orders 23/1")
- Details: Clear description of the duplicate purchase order number issue

This ensures administrators can identify and resolve duplicate purchase order
numbers while maintaining system functionality and audit trails.

Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Sponsored-by: Royal Borough of Kensington and Chelsea <https://www.rbkc.gov.uk/>
Sponsored-by: OpenFifth <https://openfifth.co.uk/>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:37 -07:00
Martin Renvoize 4179211ce8
Bug 20253: Optionally use buyer's purchase order number from EDIFACT quote as basket name
This enhancement allows libraries to configure vendors to use the buyer's
purchase order number (from RFF+ON segments) as the basket name instead of
the EDIFACT filename, improving searchability and reference tracking.

Backend Changes:
- Added purchase_order_number() method to Koha::Edifact::Message to extract
  RFF+ON segments from message-level data (before first LIN segment)
- Modified process_quote() in Koha::EDI to use purchase order number for
  basket naming when configured, with fallback to filename

Frontend Changes:
- Updated admin/edi_accounts.pl to handle po_is_basketname parameter
- Added "Use purhase order numbers" option to EDI accounts template

Test Plan:
1. Apply patches and run database update
2. Go to Administration > Acquisitions > EDI accounts
3. Create or edit a vendor EDI account
4. Verify "Use purchase order numbers" option appears
5. Enable "Use purchase order numbers" and save
6. Process an EDIFACT quote file that contains RFF+ON segments
7. Verify the created basket name uses the purchase order number instead of filename
8. Process a quote file without RFF+ON segments
9. Verify the basket name falls back to the filename
10. Test with "Use purchase order numbers" disabled
11. Verify basket names use filenames regardless of RFF+ON presence
12. Run tests: prove t/Edifact.t t/db_dependent/Koha/EDI.t

The feature is optional and backward compatible - existing behavior is
unchanged unless explicitly configured.

Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Sponsored-by: Royal Borough of Kensington and Chelsea <https://www.rbkc.gov.uk/>
Sponsored-by: OpenFifth <https://openfifth.co.uk/>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:37 -07:00
Martin Renvoize 168a5a9107
Bug 20253: Add po_is_basketname field to vendor_edi_accounts table
This patch adds a new boolean field 'po_is_basketname' to the vendor_edi_accounts
table to allow configuration of how basket names are used in EDIFACT.

Changes:
- Added atomicupdate for existing installations
- Updated kohastructure.sql for new installations

Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Sponsored-by: Royal Borough of Kensington and Chelsea <https://www.rbkc.gov.uk/>
Sponsored-by: OpenFifth <https://openfifth.co.uk/>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:36 -07:00
Martin Renvoize f6964f2ffa
Bug 20253: Add tests for RFF+ON segment handling and basket naming
This patch adds tests for:
1. RFF+ON (Purchase Order Number) segment parsing in EDIFACT messages
2. Vendor configuration for basket naming preferences
3. Basket naming logic in QUOTE processing

Test coverage includes:
- Message-level RFF+ON segment extraction
- Validation that RFF+ON processing stops at LIN segments
- Multiple RFF segment handling
- Database field storage and constraints
- Basket naming configuration logic
- Fallback behavior when purchase order number unavailable

Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Sponsored-by: Westminster City Council <https://www.westminster.gov.uk/>
Sponsored-by: Royal Borough of Kensington and Chelsea <https://www.rbkc.gov.uk/>
Sponsored-by: OpenFifth <https://openfifth.co.uk/>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:36 -07:00
Martin Renvoize 78aa42e969
Bug 40334: (follow-up) Terminology
The envelope level of EDIFACT is called an 'Interchange'. This patch
updates our UI terminology to match the official protocol terminology as
what we're actually displaying here is the Interchange file that
contains the related messages for the Basket.  The interchange file will
often contain other messages of the same type that came through at the
same time of the this basket generation.

Sponsored-by: Open Fifth <https://openfith.co.uk>
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:35 -07:00
Martin Renvoize 4f120d8666
Bug 40334: Add EDIFACT message display to basket page
This patch extends the EDIFACT message display functionality from the invoice page
to the basket page, providing comprehensive access to EDIFACT messages and error
reporting.

Features added:
- Toolbar buttons for viewing EDIFACT messages (quote/order)
- Smart button display: single button for one message type, dropdown for multiple
- EDIFACT parsing errors section with inline error display
- Errors grouped by message type with detailed information
- Conditional display: only shows when relevant data exists

Changes:
- acqui/basket.pl: Added EDIFACT message and error collection logic
- basket.tt: Added toolbar buttons and parsing errors section
- Uses existing modal system for raw message display

Sponsored-by: Open Fifth <https://openfith.co.uk>
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:35 -07:00
Matt Blenkinsop 17cea3929c
Bug 38208: Provide a link from vendors to ERM
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>
2025-11-03 14:13:34 -07:00
Marcel de Rooy e5575d6c0c
Bug 40943: (QA follow-up) Add a few POD lines for new sub
This clears qa warnings.

Test plan:
Read the POD.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:34 -07:00
Jonathan Druart 01514e3aa4
Bug 40943: Use session_id from userenv instead of cookie for value_builder
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
[EDIT] Inline tidy. Moved set_userenv_from_session before POD of next sub.
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:33 -07:00
Jonathan Druart b34d5194f5
Bug 40943: Store session_id in userenv
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
[EDIT] Inline tidy.
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:33 -07:00
Martin Renvoize 7e576e58f8
Bug 38115: (follow-up) Use File::Basename to extract filename for remote upload
When --filename contains a path (e.g., /tmp/records.mrc), the script
was uploading to the remote server with the full path, creating
unwanted directory structures (e.g., uploads/tmp/records.mrc).

This patch uses File::Basename::fileparse() to extract just the
filename portion for the remote upload, while still using the full
path for local file operations.

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:32 -07:00
Martin Renvoize e7307ddc05
Bug 38115: (follow-up) Improve error handling and connection management
Enhance the export_records.pl script with better error handling
and connection lifecycle management:

1. Connection Management:
   - Always call disconnect() after file transport operations
   - Ensure connections are cleaned up even on errors

2. Error Handling:
   - Replace unusual die+pod2usage with clear error messages
   - Add file existence validation before upload attempts
   - Provide detailed error messages with context
   - Consistent error message formatting

3. User Experience:
   - Add validation for --delete_local_after_run without --destination_server_id
   - Provide informative success messages to STDERR
   - Better error messages with specific failure reasons

4. Robustness:
   - Check if output file was created before upload
   - Check if file exists before attempting deletion
   - Graceful handling of missing upload directories

These improvements make the script more reliable and user-friendly
while maintaining all existing functionality.

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:32 -07:00
Tomás Cohen Arazi 631a14ec2e
Bug 38115: (follow-up) Update terminology from SFTP/FTP to file transport
This follow-up patch updates the terminology in export_records.pl to use
generic 'file transport' language instead of specific 'FTP/SFTP' references,
aligning with the recent renaming of the underlying classes to File::Transports.

Changes:
- Replace $sftp_server variable with $file_transport for clarity
- Update error messages to use 'file transport server' terminology
- Fix incorrect error message for report_id validation
- Update POD documentation to reference 'file transport servers'
- Maintain consistency with the renamed admin interface and API

This ensures the script terminology matches the current class structure
and admin interface naming conventions.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:31 -07:00
Jake Deery 1ee76c6a9f
Bug 38115: Add destination_server_id to export_records
This patch adds two new flags to the export_records.pl script.
* --destination_server_id=ID
    This flag will, when passed, upload the file generated by this script to
    the destination server, as configured in the FTP/SFTP Servers settings.
* --delete_local_after_run
    This flag will, when passed, cause the script to unlink (delete) the
    generated marc or CSV file found on the local disk. This is useful for folk
    who want to upload the file, but not necessarily keep a local copy, filling
    up the server's storage medium

TO TEST:

a)  APPLY PATCH, reset_all
b)  Create valid FTP/SFTP Server in Koha settings, ensuring that the server
    you create is valid and passes testing
c)  Run ./misc/export_records.pl with no agruments
    1)  Notice how koha.mrc file is generated
d)  Run ./misc/export_records.pl --destination_server_id=1
    1)  Notice how koha.mrc file is generated
    2)  On your FTP/SFTP Server, notice how koha.mrc is now present in the
        upload directory
e)  Run ./misc/export_records.pl --delete_local_after_run
    1)  Notice how koha.mrc file is NOT generated locally
f)  Run ./misc/export_records.pl --destination_server_id=1 --delete_local_after_run
    1)  Notice how koha.mrc file is NOT generated locally
    2)  On your FTP/SFTP Server, notice how koha.mrc is still present in the
        upload directory AND the file age is fresh

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:31 -07:00
Pedro Amorim b6233aeb84
Bug 40551: Make patron page holds table use API endpoint for cancellation
Test plan, k-t-d, patches applied:
1) Search for 'music':
http://localhost:8081/cgi-bin/koha/catalogue/search.pl?q=music
2) Click the 'Select all' link on the left of the search toolbar
3) Click the 'Place hold' button on the same toolbar
4) On the patron input, add 'koha'
5) You need to pick the 'Pickup location' specifically for each hold. Click 'Place holds'
6) On this screen (reserve/request.pl) ensure the table(s) work. Selecting all works. Canceling selected works (it doesn't refresh immediatelly, it's a background job). Suspend works as before, sorting, etc.
7) Now visit the patron details page:
http://localhost:8081/cgi-bin/koha/members/moremember.pl?borrowernumber=51
8) Click the 'Holds' tab.
9) Test that selecting multiple holds and canceling selected works.
10) Test that canceling a specific hold works.
11) Repeat steps 8-10 but for the circulation page from patron details at:
http://localhost:8081/cgi-bin/koha/circ/circulation.pl?borrowernumber=51

Signed-off-by: Phillip Berg <phillip.berg@mainlib.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:30 -07:00
Lucas Gass ec1869faa2
Bug 40550: (RM follow-up) Adjust number of API tests
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:29 -07:00
Pedro Amorim 09673df356
Bug 40550: Add cancellation_bulk API endpoint
Signed-off-by: Phillip Berg <phillip.berg@mainlib.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:29 -07:00
Pedro Amorim 353e3b6da8
Bug 40550: Add API tests
prove t/db_dependent/api/v1/holds.t

Signed-off-by: Phillip Berg <phillip.berg@mainlib.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:28 -07:00
Lucas Gass d7d4566810
Bug 40552: (RM follow-up) Fix forbidden pattern complaint
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:28 -07:00
Pedro Amorim 53841886f5
Bug 40552: Allow selecting all holds from a group
Test plan, k-t-d, patches applied:
1) Search for 'test':
http://localhost:8081/cgi-bin/koha/catalogue/search.pl?q=test
2) Click the 'Select all' link on the left of the search toolbar
3) Click the 'Place hold' button on the same toolbar
4) On the patron input, add 'koha'
5) You need to pick the 'Pickup location' specifically for each hold. Click 'Place holds'
6) Now visit the patron details page:
http://localhost:8081/cgi-bin/koha/members/moremember.pl?borrowernumber=51
7) Click the 'Holds' tab.
8) Click the top most checkbox to select all holds. Click the 'group selected' button. Notice the holds are grouped and the 'group hold' column shows the hold group number accordingly.
9) Test that selecting the hold group number opens the hold group modal and a new 'select group holds' buttons exist.
10) Click that button, ensure it selects the group holds. Test with more holds, more groups, unselecting all beforehand, selecting all beforehand, etc.

Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:27 -07:00
Pedro Amorim 8c4d956247
Bug 40552: Preparation: Move patron page logic for reusability
Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:27 -07:00
Lucas Gass ad23ace00e
Bug 40529: DBIC
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:26 -07:00
Lucas Gass 954910e2b3
Bug 40529: DBRev 25.06.00.030
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:26 -07:00
Pedro Amorim 877390de6a
Bug 40529: (QA follow-up): Fix DB changes
Add UNIQUE KEY entries to table definition
The UNIQUE KEY are required as a hold group 'might have' a target hold, not 'has many' target holds.
This update and the other things this patch updates in atomicupdate + kohastructure should  fix the error thrown by command:
perl /kohadevbox/misc4dev/run_tests.pl --instance=kohadev --db-password=password --run-db-compare-only --compare-with=HEAD

This command no longer produces any errors.

Also in this patch:
Renamed table from 'hold_group_target_holds' to 'hold_groups_target_holds' and move it alphabetically to be after 'hold_groups' in kohastructure.sql
This is cleaner, as it matches the 'hold_groups' related table, and allows for alphabetical sorting on kohastructure.sql that makes sense i.e. hold_groups is created first, then hold_group_target_holds is created second with an FK to the former.

All of this passes:
prove ./t/db_dependent/Koha/Hold.t
prove ./t/db_dependent/Reserves/HoldGroup.t
prove ./t/db_dependent/Circulation*
prove ./t/db_dependent/Hold*
prove ./t/db_dependent/Reserves*

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:25 -07:00
Pedro Amorim 028826c560
Bug 40529: (QA follow-up) Rebase and fix tests
This further rebases on top of 40058 which removed RevertWaitingStatus.
It also fixes a warning where 'eq was being utilized on initialized' coming from sub remove_as_hold_group_target

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:25 -07:00
Pedro Amorim 9a03ec6a28
Bug 40529: (QA follow-up): Add skip logic to GetPendingHoldRequestsForBib
This fixes the issue reported by Andrew on comment 23.
Following the scenario he describes, the hold should now still appear, but attached to the correct patron (Patron B).
This was an oversight as I wasn't aware of GetPendingHoldRequestsForBib and had only added the skip logic to GetBibsWithPendingHoldRequests.

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:24 -07:00
Pedro Amorim 8426becada
Bug 40529: (QA follow-up): Remove hold as hold group target when reverted
If a hold that is a hold group target, i.e. it's 'waiting' or 'in transit', is reverted it needs to remove itself as its own hold group target

Tests added here as well:
prove t/db_dependent/Koha/Hold.t

Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:24 -07:00
Pedro Amorim fc52ac9a45
Bug 40529: (QA follow-up): Include target holds
The skipping of non target holds was skipping all holds that are part of a hold group which has a target, including the target hold itself. This was wrong. Target holds need to be included as they are considered to be a regular 'found' hold.

Tests that prove the bug and its fix added to:
prove ./t/db_dependent/Koha/Hold.t

Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:23 -07:00
Pedro Amorim c9c8ce74b5
Bug 40529: Add unit tests
Test plan, k-t-d, patches applied:
1) Apply patches, enable DisplayAddHoldGroups system preference
2) Do a search for 'test':
<staff_url>/cgi-bin/koha/catalogue/search.pl?q=test
3) Click the 'Select all' link at the top of the search results, click the 'Place hold' button.
4) Enter the 'koha' user
5) Pick a pickup location for each of the holds and click 'Place holds'.
6) Visit the 'koha' patron:
<staff_url>/cgi-bin/koha/members/moremember.pl?borrowernumber=51
7) Notice there are 3 holds all part of hold group '1'
8) Check-in one of the items in this hold group: 39999000005578. Confirm hold.
9) Repeat 6). Notice 'Continuous delivery' is now the hold group 'target'.
10) Place a new hold for one of the other 2 'non-target' holds for a different patron. Visit:
<staff_url>/cgi-bin/koha/reserve/request.pl?biblionumber=29
11) Enter 'henry' on the patron input. Pick 'Henry Acevedo (23529000035676)'. Click 'Place hold'. Notice Henry's hold is priority 2. Let's check-in the item for this record: 39999000001310
12) Notice the eligible hold is Henry's, not the koha user's hold. This is because the hold that relates to koha's user is part of a hold group that already has a target so it was skipped. You may confirm the hold.
13) Now let's cancel 'target' hold, visit:
<staff_url>/cgi-bin/koha/members/moremember.pl?borrowernumber=51
14) Click the 'Holds' tab and the red trash icon next to 'Continuous delivery'. Confirm cancellation.
15) Check the holds again, now there's only 2 holds in the existing group.
16) Let's repeat the exercise as before and place a hold for 'Henry' for 'Clean code', visit:
<staff_url>/cgi-bin/koha/reserve/request.pl?biblionumber=114
17) Enter 'henry' and place a hold as before.
18) The 'Clean code' record now has 2 holds: first for 'koha' user and the second for 'Henry'.
19) Now check-in the item for that record. Notice it's the 'koha' user's hold that comes up. This is because it's first in priority and the hold is part of a hold group that does not yet have a target. Confirm hold.
20) Go back to 'Henry' and cancel his holds. Visit:
<staff_url>/cgi-bin/koha/members/moremember.pl?borrowernumber=19
21) Select 'both', click 'Cancel selected'. Confirm cancellation.
22) Visit 'holds to pull':
<staff_url>/cgi-bin/koha/circ/pendingreserves.pl
23) Notice no holds show, even though 'koha' user has a hold that does not yet have an item assigned to it. This hold was skipped because it's part of a hold group that already has a target. To confirm this, disable DisplayAddHoldGroups and refresh 'Holds to pull'. Confirm it shows.
24) The same happens for the 'holds queue' i.e. 'non-target' holds are skipped. To test, with the sys pref still disabled, run the build_holds_queue.pl script:
$ perl misc/cronjobs/holds/build_holds_queue.pl
25) Notice the 'non-target' hold shows, and that is expected if DisplayAddHoldGroups is disabled. Enable DisplayAddHoldGroups and repeat 24. Confirm the hold is gone.

The behavior above works as described for holds that become 'In transit' or 'Waiting'.

Run the updated test files:
prove ./t/db_dependent/Koha/Hold.t
prove ./t/db_dependent/Reserves/HoldGroup.t

Relevant tests worth running to ensure no regressions are added to existing covered functionality:
prove ./t/db_dependent/Circulation*
prove ./t/db_dependent/Hold*
prove ./t/db_dependent/Reserves*

Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:23 -07:00
Pedro Amorim b6a45dd3d4
Bug 40529: Behavior change: Add target info on hold group modal
Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:22 -07:00
Pedro Amorim 3569da3996
Bug 40529: Behavior change: Main patch
When a hold that belongs to a hold group becomes 'In transit' or 'Waiting',
it now becomes that hold group's target hold.
Subsequent check-ins that would satisfy other holds in the same hold
group are skipped, as they are part of a group that already has a
target.

The behavior change introduced here that differs from the groundwork
from bug 15516 are:
1) Before, only 'Waiting' holds would consider an action based on hold
   groups i.e. cancel the other holds in the group. Now 'In transit'
   also does this.
2) This hold groups related action used to be to cancel other holds in
   the group. This is no longer the case. Now, the respective hold is
   set as the hold group's target. This causes the holds in the same group that
   are not the target to be skipped when a check-in that would otherwise
   satisfy one of those holds happens. This behavior change allows the following
   scenario which wasn't possible before:

   A hold is marked 'Waiting'. It becomes its group target. For any reason,
   that hold is then cancelled. Any subsequent check-in of an item of a
   hold in this group may now becomes that group's new target.
   Similarly, the same use case above is also true for 'In transit' holds.

----

   The 'skip non-target holds' behavior has been added to check-in logic
(Reserves::_Findgroupreserve), 'holds to pull' logic
(pendingreserves.pl) and holds queue (HoldsQueue.pm).

Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:22 -07:00
Pedro Amorim bf4e2d01aa
Bug 40529: Add hold group targets logic
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>
2025-11-03 14:13:14 -07:00
David Cook 5864b7c7a3
Bug 40818: Add missing html filter on html_helpers.inc
Signed-off-by: David Cook <dcook@prosentient.com.au>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 09:44:42 -07:00
Jonathan Druart 31d8491fcf
Bug 40818: Replace raw with html filter for marc_lib
Signed-off-by: David Cook <dcook@prosentient.com.au>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 09:44:41 -07:00
Jonathan Druart 3284d2c174
Bug 40818: Remove HTML from marc_lib
Signed-off-by: David Cook <dcook@prosentient.com.au>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 09:44:41 -07:00
David Cook bd81a7a299
Bug 40525: Update spreadsheet format to escape formulas
This change updates the spreadsheet format to escape formulas
using the built-in function if using Buttons 3.2.0+ or using
a workaround if not.

Test plan:
0. Apply the patch
1. Go to http://localhost:8081/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=29
2. Click on tab 1
3. For 100$a type in the following and save:
=SUM(1+1)
4. Go to http://localhost:8081/cgi-bin/koha/circ/circulation.pl?findborrower=42
5. Checkout barcode 39999000001310 to the patron
6. Go to http://localhost:8080/cgi-bin/koha/opac-user.pl and login as that patron
7. Download the CSV for the summary table and open in Excel
8. Note that the "Author" is "'=SUM(1+1)" and not "=SUM(1+1)" or "2"

Signed-off-by: Brendan Lawlor <blawlor@clamsnet.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 09:44:33 -07:00
Pedro Amorim 11ea8d533d
Bug 40517: (QA follow-up): Fix tests
Enforce no hold group when creating hold object

When a hold is created by build_object, it's auto-assigned a hold_group_id (as expected).
When a hold is ->fill, it's hold_group_id is cleared by cleanup_hold_group (as expected).

The problem is then this causes the  object before ->fill to be out of sync with the up to date object returned by the API (i.e. the latter has an empty hold_group_id, as expected, but the former has the auto-assigned hold_group_id).

Using ->discard_changes or ->get_from_storage doesnt work because the  became a  after ->fill.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 07:19:54 -07:00
Lari Taskula d77c826c8c
Bug 41044: Fix warning
To test:
1. prove t/db_dependent/Koha/Item.t
2. Observe success

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-31 15:26:29 -06:00
Lari Taskula 120ef099fc
Bug 41044: Add a failing test
To test:
1. prove t/db_dependent/Koha/Item.t
2. Observe failing test

Subtest: test empty string warning
        1..1
        not ok 1 - No warnings were produced
           Failed test 'No warnings were produced'
           at t/db_dependent/Koha/Item.t line 3656.
         found warning: Argument "" isn't numeric in addition (+) at /usr/local/lib/x86_64-linux-gnu/perl/5.34.0/DateTime/Duration.pm line 70.
         didn't expect to find a warning
         Looks like you failed 1 test of 1.
    not ok 9 - test empty string warning
       Failed test 'test empty string warning'
       at t/db_dependent/Koha/Item.t line 3657.
     Looks like you failed 1 test of 9.
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-31 15:26:29 -06:00
CJ Lynce b0ec433062
Bug 40995: (follow-up) pass invert_name in patron autocomplete
Passes invert_name flag to patron_to_html to restore previous
format in patron autocomplete.

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-31 15:26:28 -06:00