Commit Graph

9351 Commits

Author SHA1 Message Date
Nick Clemens 168f52f99b
Bug 34596: Unit tests
Writing these I found that transferbook was generating two queue rebuilds - fixed that

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-06 09:15:18 -06:00
Nick Clemens 18fba45afd
Bug 34596: Add rebuild queue where needed for existing calls to AddReturn
Existing calls to AddReturn:

C4/Circulation.pm
 - transferbook - calls ModDateLastSeen, queue is rebuilt
 - AddIssue - rebuild not needed, book is going out again immediately

C4/SIP/ILS/Transaction/Checkin.pm
 - do_checkin - added

Koha/Checkouts.pm
 - automatic_checkin - added

circ/circulation.pl
 - called in stats checkout, not needed

circ/returns.pl
 - added

opac/sci/sci-main.pl
- added

svc/checkin
 - added

svc/recall
 - wasn't actually called, removed the use statement

tools/inventory.pl
 - added

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-06 09:15:17 -06:00
Nick Clemens f9d096df27
Bug 34596: Do not build holds queue when checkin reserve found but do if hold ignored
This patch does two things:
1:
It prevents rebulding the real time holds queue during a checkin if a reserve was found.
The reserve will either:
a - be set to waiting if at correct location and no confirmation - this is fine because we will rebuild the queue when
    filling the hold
b - trigger a popup whihc will rebuild the queue when confirming the transfer, or be ignored

2:
It adds a form to ignoring a hold so that we can rebuild the holds queue if we decided not to use the current item
to fill the found hold

To test:
0 - Enable RealTimeHoldsQueue
1 - Place several holds for different libraries on a title
2 - Checkout a copy to a patron at current library (ignore current holds)
3 - Clean up DB so we can see outcomes from next steps:
   delete from branchtransfers; delete from background_jobs; update reserves SET found=NULL where found='T';
4 - Check in item, confirm hold
5 - Check background jobs, note two rebuilds of the holds queue
6 - Check item out to previous patron, repeat 3
7 - Check in item, ignore the hold
8 - Check background jobs, note only one rebuild
9 - Apply patch, restart all
10 - Checkout item, repeat 3
11 - Checkin item, confirm hold
12 - Check background jobs, onlt one rebuild of holds queue
13 - Checkout item, repeat 3
14 - Checkin item, ignore hold
15 - Check background jobs, only one rebuild of holds queue

Signed-off-by: Brendan Lawlor <blawlor@clamsnet.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-06 09:15:09 -06:00
Lucas Gass b7cb04b925
Revert "Bug 40286: Make C4::Auth::checkpw_internal use Koha::Patrons->find_by_identifier"
This reverts commit 4d748a390c.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-02 06:02:02 -06:00
Lucas Gass c144c733cd
Bug 38330: (RM follow-up) Add missing comma
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-30 06:17:26 -06:00
Tomas Cohen Arazi 4d748a390c
Bug 40286: Make C4::Auth::checkpw_internal use Koha::Patrons->find_by_identifier
This patch does what the title says. The code change is clear to
understand.

The check for userid vs. cardnumber is done in the `find_by_identifier`
method so no need to do it here.

Note: When `find_by_identifier` was written, I picked some other place's
logic (API password validation) so `userid` is used first for finding
the patron. Because of this, tests in t/db_dependent/Auth.t need to be
adjusted. I believe this is not an issue, as those tests should be
removed once we move forward with bug 33905, entirely.

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

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
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>
2025-09-29 14:02:30 -06:00
Nick Clemens 6f135d4392
Bug 28702: Reduce DB lookups in buildKohaItemsNamespace
This patch moves the prefetch to current_branchtransfers and uses the prefetched reserves
and transfers to reduce the number of lookups from the DB

We also don't fetch the specific current transfer, knowing we have current transfers is enough

To test:
1 - Perform a search on the OPAC
2 - Add the results to a list
3 - Load the list several times and use developer tools (F12) to view the time to load in the network tab
4 - Repeat a search several times and use developer tools (F12) to view the time to load in the network tab
5 - Record the times noted above
6 - Find or create a record with many items, biblionumber 3 in my example
7 - on the command line:
    export DBIC_TRACE=1
    perl -e 'use C4::XSLT; my $i = C4::XSLT::buildKohaItemsNamespace( 3 );'
    note the lookups in reserves and transfers
8 - Apply patch
9 - Repeat 7 and note less lookups
10 - Repeat the search and list view and compare times to before the patch
11 - prove -v t/db_dependent/XSLT.t

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-29 14:02:24 -06:00
Tomas Cohen Arazi 7dc6af40f6
Bug 38936: Introduce C4::Output::redirect_if_opac_suppressed
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
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>
2025-09-29 14:02:22 -06:00
Tomas Cohen Arazi 2fdf0d12d0
Bug 38330: Make sure biblio.opac_suppressed is populated/updated on save
This patchset adds a new column to biblio/deletedbiblio for storing the
information about OPAC suppression for the record.

It works as any other framework-mapped attribute. It defaults to 0 (not
suppressed) and some sanitization is done on storing, because the DB
should only contain 0 or 1.

To test:
0. Have a couple records with 942$n set to suppress them.
1. Apply this patches
2. Run:
   $ ktd --shell
  k$ updatedatabase
=> SUCCESS: All good
3. Check the `opac_suppressed` column was added to both tables
4. Notice it tells you need to run `touch_all_biblios.pl`
5. Run:
  k$ koha-mysql kohadev
   > SELECT opac_suppressed,COUNT(opac_suppressed) FROM biblio GROUP BY opac_suppressed;
=> FAIL: There are no records with the opac_suppressed flag set to 1
6. Run:
  k$ perl misc/maintenance/touch_all_biblios.pl -v
=> SUCCESS: No failures
7. Repeat 5
=> SUCCESS: Your couple records have the flag set. This means ModBiblio
is doing the right thing
8. Play with adding new records (suppressed and not)
=> SUCCESS: Suppression status is set correctly
9. Change the status to select records
=> SUCCESS: The DB column and the MARC are in sync!
10. Sign off :-D

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-29 14:02:15 -06:00
Tomas Cohen Arazi c798f642bf
Bug 38330: Map to biblio.opac_suppressed on saving record
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-29 14:02:14 -06:00
David Cook 9da5f23f96
Bug 40473: Use better algorithm for calculating Code39 barcode length
This patch uses the PDF::Reuse::Barcode algorithm for calculating barcode
background box length relative to barcode length in order to determine
the actual barcode width and thus the X scale factor required to re-size
that barcode so that it fits on the label width (or rather the
"Barcode width" which is a percentage applied to the label width
to create a narrower usable surface for the barcode and barcode background
box).

To test:
0. Apply the patch
1. Go to http://localhost:8081/cgi-bin/koha/cataloguing/additem.pl?biblionumber=29
2. Add an item with barcode 123456, add an item with barcode 39999000001310399991,
    and ensure an item with barcode 39999000001310 already exists
3. Go to http://localhost:8081/cgi-bin/koha/labels/label-manage.pl?label_element=batch
4. Create a patch that uses 3 items using 39999000001310, 2 items with 123456,
    and 2 items with 39999000001310399991
4. Go to http://localhost:8081/cgi-bin/koha/labels/label-manage.pl?label_element=layout
5. Edit the layout "Label Test"
6. Change the "Barcode width" to 1, and enable "Draw guide boxes", and click "Save"
7. Export the batch using the template "Avery 5160 | 1 x 2-5/8" and the layout "Label Test" and open as PDF
8. Note that the whole barcode fits inside the red guidebox (there should be some
overlap of white on top of the red guidebox but that is normal since we're using 100% of the
barcode label width).
9. Edit the "Label Test" layout to try "Code39 + Modulo43" and "Code39 + Modulo10" and retry batch export
10. Edit the "Label Test" and try different "Barcode width" like the usual default .8
11. Celebrate that your barcodes fit on the label!

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-26 10:36:41 -06:00
Tomas Cohen Arazi 1873d97c07
Bug 40163: Fix several http addresses in the code docs
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Brendan Lawlor <blawlor@clamsnet.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-23 16:21:29 -06:00
Bernard Scaife affa3e62fd
Bug 40675: Fix SIP message corruption from embedded line endings
Patron messages containing carriage returns, line feeds, or CRLF
combinations can break SIP protocol communication since CR is used
as the SIP message terminator. This causes message parsing failures
and protocol errors in self-check systems.

The previous regex only handled single carriage returns (\r),
missing Windows CRLF (\r\n) and Unix LF (\n) sequences.

This patch normalizes all line ending variations to spaces to
prevent SIP message corruption while preserving message content.

Test plan:
1. Go to a patron record and click "Add message"
2. Select "Add message for OPAC..." from dropdown
3. In a text editor (e.g., Word), create a message with line breaks:
   "This is line one[Enter]This is line two[Enter]This is line three"
4. Copy and paste this multi-line text into the message box and save
5. Run the SIP emulator: misc/sip_cli_emulator.pl
6. Execute a patron information request for this patron
7. Before patch: Observe message breaks at line endings, corrupting
   the SIP response
8. Apply patch and restart SIP server
9. Repeat steps 5-6
10. After patch: Verify the message appears as single line with
    spaces replacing line breaks: "This is line one This is line two
    This is line three"
11. Test with different line ending types (Windows, Mac, Unix) to
    ensure all variations are handled correctly

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

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
[EDIT] Adjusted the comment in Sip.pm
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-19 08:42:47 -06:00
Nick Clemens 3f61f6088f
Bug 40708: Return the specific error to the checkin page
When implemented, the message here was believed to either be about Duplicate IDs, or guarantor issues.
We are now seeing a wider variety of issues possible from SQL errors, lock timeout or missings rows as examples

This patch adds an 'ErrorMessage' message to the return from AddReturn and displays it to the user.

To test:
1 - Issue an item to a patron, note the itemnumber
2 - On the command line, lock the row:
    sudo koha-mysql kohadev
    START TRANSACTION;
    SELECT * FROM issues WHERE itemnumber=975 FOR UPDATE;
    leave mysql open at this point
3 - On the interface, check in the item, wait a bit
4 - After a bit you get the error to check the config page, but nothing is there
5 - close mysql, apply patch, restart all
6 - Repeat 2
7 - Check in the item, wait a bit
8 - Note you now get the error from the DB:
    Error: (DBIx::Class::Storage::DBI::_dbh_execute(): DBI Exception: DBD::mysql::st execute failed: Lock wait timeout exceeded; try restarting transaction at /kohadevbox/koha/Koha/Object.pm line 174 )
9 - Sign off!

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

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-19 08:42:43 -06:00
Paul Derscheid c0f191b79c
Bug 40665: Link checkouts to bookings
This patch adds a booking_id field to the issues and old_issues tables
to create a linkage between checkouts and the bookings that generated
them. When a patron with a booking checks out the reserved item, the
checkout is linked to their booking and the booking status is updated
to 'completed'.

The booking_id is preserved during renewals and when checkouts are
moved to old_issues upon return.

Database changes:
- Add booking_id column to issues and old_issues tables
- Add foreign key constraints to maintain referential integrity

Test plan:
1. Apply the database update
2. Restart services
3. Create a booking for a patron
4. When the patron checks out the booked item:
 a. Verify the checkout links to the booking (booking_id is set)
 b. Verify the booking status changes to 'completed'
5. Renew the checkout
 a. Verify the booking_id is preserved after renewal
 b. Check the database: SELECT booking_id FROM issues WHERE issue_id = X
6. Return the item
 a. Verify the checkout moves to old_issues
 b. Verify the booking_id is preserved in old_issues
7. Test the new Koha::Booking methods:
 a. For a booking with a checkout, verify $booking->checkout returns
    the correct Koha::Checkout object
 b. For a booking with an old checkout, verify $booking->old_checkout
    returns the correct Koha::Old::Checkout object
8. Test the API:
 a. Verify checkout endpoints include booking_id in responses
 b. Verify the booking relationship can be embedded using
    x-koha-embed: booking
9. Run the test suite:
 prove t/db_dependent/Circulation.t
 prove t/db_dependent/Koha/Booking.t
 prove t/db_dependent/Koha/Checkout.t

NOTE: I also thought about the inverse: linking to a checkout from the
booking, but as Koha is a circulation centric system, this approach makes
more sense in my opinion. I also thought about bidirectional linking via
FKs but that is too much maintenance overhead (and potential error source)
that we don't need. The inverse lookups should still be performant through
the FKs.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-05 15:10:36 -06:00
Tomas Cohen Arazi 47f0aab19f
Bug 40636: (follow-up) Cache the calendar object
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-05 08:02:32 -06:00
Tomas Cohen Arazi 31dced9c8b
Bug 40636: Fix holiday logic in CancelExpiredReserves with comprehensive edge case handling
CancelExpiredReserves had incorrect holiday logic that checked if **today** is a holiday instead of checking if the **hold's expiration date** was a holiday.

This caused:
* Holds that expired on non-holidays to remain active if cleanup script ran on holidays
* Holds that expired on holidays to be cancelled if cleanup script ran on non-holidays

The simple fix exposed additional edge cases around server downtime that could leave holds active indefinitely.

Changes:
* Implements comprehensive holiday logic when `ExpireReservesOnHolidays = 0`
* Same-day protection: Don't cancel holds that expire TODAY if today is a holiday
* Historical cleanup: Cancel holds that expired in the past when running on business days
* Retrospective cancellation: Handle server downtime by checking for missed business days
* Comprehensive test suite covering all scenarios including long-term expired holds

To test:
1. Apply the tests patch
2. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Reserves/CancelExpiredReserves.t
=> FAIL: Tests fail! The logic in the method is wrong!
3. Apply this patch
4. Repeat 2
=> SUCCESS: All tests pass, demonstrating correct behavior in all scenarios
5. Sign off :-D

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-05 08:02:31 -06:00
Lucas Gass f2adf0ad82
Bug 39820: Add cancellation reason and clean up cancellation request
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-05 08:02:29 -06:00
Lucas Gass 2246bfbb4a
Bug 39820: Cancel holds with cancellation requests via SIP
To test:
1. In circ rules set a Default waiting hold cancellation policy to allow hold cancellation requests.
2. Add a hold for a patron and create a hold cancellation request.
3. Check the item in via SIP, I used the SIP emulator:

kohadevbox/koha/misc/sip_cli_emulator.pl -a localhost -p 6001 -l MPL -su term1 -sp term1 -m checkin --patron 23529000035676 --item 39999000001310

4. The hold remains.
5. APPLY PATCH, restart_all
6. Try 2 - 4 again, the hold should be cancelled

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-05 08:02:27 -06:00
Tomas Cohen Arazi cd4e1da3ec
Bug 40275: Use Koha::Patrons->find_by_identifier in the codebase
Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 14:00:46 -06:00
Martin Renvoize b31f8c566d
Bug 9762: (follow-up) Add integration tests and improve AddRenewal logging consistency
This commit adds two key improvements to the Bug 9762 circulation override logging:

1. **Consistent JSON Logging**: Updated AddRenewal to always log in JSON format,
   matching AddIssue behavior. Previously AddRenewal only logged JSON when
   confirmations/forced were present, otherwise logged just the item number.

2. **Integration Tests**: Added comprehensive tests for both AddIssue and AddRenewal
   JSON logging functionality:
   - Test normal operations (empty confirmations/forced arrays)
   - Test override operations (populated confirmations/forced arrays)
   - Verify JSON structure and content accuracy

The AddRenewal function now consistently logs:
```json
{
  "issue": 123,
  "itemnumber": 456,
  "confirmations": [...],
  "forced": [...]
}
```

This ensures uniform action log format across all circulation operations and
provides better integration test coverage for the override logging functionality.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:13 -06:00
Hammat Wele 489780f3f9
Bug 9762: (follow-up) Add branchcode to Log circulation and add some override confirmations in action logs, fix typos
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:11 -06:00
Martin Renvoize 255c0897f2
Bug 9762: (Alternative) Handle renewals
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:11 -06:00
Martin Renvoize 5350a9276e
Bug 9762: (Alternative) Log circulation overrides
An alternative approach to the original submission for bug 9762. Instead
of recording a distinct action log line for a set of override messages
in addition to the standard issue record, this patch updates the
existing issue log to include any confirmation or impossible responses
from the preceeding CanBookBeIssued call.

We continue to record these as a JSON structure as the prior patch did,
but instead of human messages we use the predefined codes as returned
from the existing CanBookBeIssued response.

To test:

After each step, a single action log message should be displayed under
`Tools > Log viewer`. The message itself will now consist of a JSON
string with an array of 'confirmations' and 'forced' strings
representing the overriden feedback from CanBookBeIssued.

Circulation -- Checking out

1) Check out an item that is age-restricted (AgeRestrictionOverride syspref)
2) Check out an item that has a “not for loan” status (AllowNotForLoanOverride
   syspref)
3) Check out an item that has a “lost” status (IssueLostItem syspref)
4) Check out an item to a patron who has reached the checkout limit
   (AllowTooManyOverride syspref)
5) Check out an item to a patron who is not allowed to borrow this item type
6) Check out an item to a patron who has unpaid fines (AllFinesNeedOverride
   and/or AllowFineOverride + noissuescharge sysprefs)
7) Check out an item on hold for someone else
8) Check out an item on hold ready for pickup by someone else
9) Check out an item already checked out to someone else
   (AutoReturnCheckedOutItems syspref)
10) Check out to a patron who has restrictions

Circulation -- Checking in

11) Ignore a hold upon check in
12) Ignore a hold and transfer upon check in

Circulation – Renewing

13) Renew an item on hold for someone else
    (AllowRenewalOnHoldOverride syspref)
14) Renew an item that has reached the maximum number of renewals
    (AllowRenewalLimitOverride syspref)

Holds

15) Place a hold for a patron who is not allowed to place this item
    type on hold (AllowHoldPolicyOverride syspref)
16) Place a hold for a patron who has reached the maximum number of
    holds
17) Place an item-level hold when rules dictate that this is not
    allowed

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:10 -06:00
Martin Renvoize 86f4eb93aa
Bug 9762: (QA follow-up) Remove superflous string construction
We never actually pass `$message` back to anywhere so there's no reason
to create it in the first place.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:10 -06:00
Martin Renvoize b4e26e9c48
Bug 9762: (QA follow-up) Fix failing test
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:09 -06:00
Martin Renvoize ee74749058
Bug 9762: (QA follow-up) Add missing issueconfirmed check
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:09 -06:00
Matthias Le Gac 9183fca07d
Bug 9762: Change how to pass the param
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:07 -06:00
emilyrose 89811768b6
Bug 9762: Log circulation overrides
This patch allows you to save commands that have been overridden by someone.

The patch has been updated but is not yet completed. Tests 10, 13, 14, and 17 are still not functional. Tests 15 and 16 need to be fixed as they do not display the barcode. All other tests should be functional.

To test:

--After each step, a message will be displayed in the action_logs table and in Tools > Log viewer --

Circulation -- Checking out

1) Check out an item that is age-restricted (AgeRestrictionOverride syspref)
2) Check out an item that has a “not for loan” status (AllowNotForLoanOverride syspref)
3) Check out an item that has a “lost” status (IssueLostItem syspref)
4) Check out an item to a patron who has reached the checkout limit (AllowTooManyOverride syspref)
5) Check out an item to a patron who is not allowed to borrow this item type
6) Check out an item to a patron who has unpaid fines (AllFinesNeedOverride and/or AllowFineOverride + noissuescharge sysprefs)
7) Check out an item on hold for someone else
8) Check out an item on hold ready for pickup by someone else
9) Check out an item already checked out to someone else (AutoReturnCheckedOutItems syspref)
10) Check out to a patron who has restrictions

Circulation -- Checking in

11) Ignore a hold upon check in
12) Ignore a hold and transfer upon check in

Circulation – Renewing

13) Renew an item on hold for someone else (AllowRenewalOnHoldOverride syspref)
14) Renew an item that has reached the maximum number of renewals (AllowRenewalLimitOverride syspref)

Holds

15) Place a hold for a patron who is not allowed to place this item type on hold (AllowHoldPolicyOverride syspref)
16) Place a hold for a patron who has reached the maximum number of holds
17) Place an item-level hold when rules dictate that this is not allowed (In circulation rules put "On shelf holds allowed" to "If any unavailable")

Sponsored-by: Solutions inLibro inc. <https://inlibro.com/>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:07 -06:00
David Cook c0ea7bd469
Bug 15516: (follow-up) fix count_holds() for CanBookBeReserved()
This patch adds search_attrs to count_holds() since these get
used with CanBookBeReserved.

Test plan:
0. Apply the patch
1. prove t/db_dependent/Koha/Holds.t t/db_dependent/Reserves/HoldGroup.t t/db_dependent/Reserves.t

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-09-03 11:42:04 -06:00
David Cook 4864cd79cc
Bug 15516: (follow-up) Fix some merge bugs
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>
2025-09-03 11:42:02 -06:00
Aleisha Amohia 8bfe38b3ba
Bug 15516: Relevant controller changes and tests
Signed-off-by: Michal Denar <black23@gmail.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>

Signed-off-by: Michal Denar <black23@gmail.com>
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>
2025-09-03 11:42:00 -06:00
Marcel de Rooy c11dce94c1
Bug 37651: (follow-up) Still skip future holds for renewals
We need a skip_future_holds flag in item->current_holds to make renewals
act as they did before. There is no need to add it to biblio->current_holds.

Test plan:
Run t/db_dependent/Holds.t
Interface test: Issue a book, place hold on tomorrow, set ConfirmFutureHolds
to 2 days. Verify that renew is not blocked by this hold.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-08-29 10:43:33 -06:00
Tomas Cohen Arazi 4ad2c94690
Bug 40671: Update method calls from revert_waiting to revert_found
This patch updates all existing calls to the renamed method throughout
the codebase to maintain compatibility.

Changes:
* Updated C4::Circulation calls to use revert_found()
* Updated C4::Reserves calls to use revert_found()
* Updated test files to use revert_found()
* Maintained all existing functionality and behavior

All existing functionality is preserved - this is purely a method
name change to reflect the expanded capability.

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Emily Lamancusa <emily.lamancusa@montgomerycountymd.gov>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-08-29 10:43:26 -06:00
Lisette Scheer 5832521086
Bug 40620: Holds Queue will assign to the lowest item number if multiple branches have the same transport cost
To Test:
Before applying:
1. Turn on the UseTransportCostMatrix system preference
2. Create holds on a record with multiple items. (I used Lanark in KTD)
3. Set the item location to all be the same (I used MID)
4. Set the holds to pickup at Centerville, Fairfield, and Pleasant Valley
5. Set the transport cost matrix to
Centerville\fairfield 1
Centerville\Midway 1
Fairfield\Centerville 1
Fairfield\Midway 1
Midway\Centerville 1
Midway\Fairfield 1
Midway\Pleasant Valley 4

6. Build the holds queue (either turn on realtime hold queue and then edit the bib to update or run the cron on the command line)
7. Run a report: select * from hold_fill_targets where biblionumber=9 order by borrowernumber;
8. Rebuild the hold queue
9. Run the report again, the results should be the same.

10. Apply the patch
11. Run the hold queue again
12. Observe the results should now be different.
13. Try a few more times and ensure the numbers are changing, create some more items at midway and try again to see more variety in numbers.

Signed-off-by: David Flater <flaterdavid@gmail.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-08-22 07:45:01 -06:00
Hammat Wele 99322896b9
Bug 20644: Add checkprevcheckout on item types
I have added the "Check for previous checkouts" option to item types. This option is visible only when the system preference "CheckPrevCheckout" is set to either :
- "Unless overridden by patron category or by item type, do"
or
- "Unless overridden by patron category or by item type, do not."

This option takes precedence over patron and patron category preferences.

TEST PLAN
1) Apply the patch.
2) Perform an atomic update (installer/data/mysql/updatedatabase.pl)
3) Set the "CheckPrevCheckout" system preference to "Unless overridden by patron category or by item type, do".
4) Go to "Koha administration > Item types > + New item type".
5) Fill in the necessary fields; the "Check for previous checkouts" field should be set to "Inherit from system preferences".
6) Click the "Save changes" button.
7) Create an item with the type you have created.
8) Check out this item for a patron, then check it in.
9) Check out the same item for the same patron again.
10) The message "Patron has previously checked out this title: <Title>. Check out anyway?" should appear.
11) Go to "Koha administration > Item types".
12) Edit the created item type.
13) Change the value of the "Check for previous checkouts" field to "No and try to override system preferences".
14) Click the "Save changes" button.
15) Check out the same item for the same patron.
16) The message should not appear.
17) Run the tests "Borrower_PrevCheckout.t" (prove t/db_dependent/Patron/Borrower_PrevCheckout.t) and "ItemTypes.t" (prove t/db_dependent/Koha/ItemTypes.t).
18) Verify that all tests pass successfully.

Signed-off-by: Laurence <laurence.rault@biblibre.com>
Signed-off-by: Emmi Takkinen <emmi.takkinen@koha-suomi.fi>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-08-20 13:42:58 -06:00
Tomas Cohen Arazi a137c7a183
Bug 40058: Remove RevertWaitingStatus()
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>
2025-08-14 16:05:59 -06:00
Martin Renvoize 2f849fd79c
Bug 40296: (follow-up) Fix booking patron ownership and cancellation logic
This follow-up addresses critical issues in the initial implementation:

1. **Patron Ownership Check**: Only mark bookings as 'completed' when
   the patron checking out the item is the same patron who made the booking

2. **Smart Cancellation**: When another patron checks out an item that
   conflicts with an existing booking:
   - Cancel the booking only if checkout overlaps with actual booking period
   - Respect lead/trail periods - don't cancel if conflict is only during
     preparation periods (allows librarian override scenarios)

3. **Date Logic**: Proper overlap detection using start_date and end_date
   rather than periods extended by lead time

This prevents incorrect booking completion and handles librarian override
scenarios appropriately.

Test plan:
1. Apply previous patch and this follow-up
2. Enable bookings and create a bookable item

Test A - Patron's own booking completion:
3. Create booking for Patron A: start = today, end = +7 days
4. Check out item to Patron A (due date = +5 days)
5. Verify booking status = 'completed'

Test B - Lead period override scenario:
11. Return item, set bookings_lead_period circulation rule = 3 days
12. Create booking for Patron A: start = +5 days, end = +8 days
13. Check out item to Patron B (due date = +4 days) - conflicts with lead period
14. Override the booking conflict warning
15. Verify Patron A's booking status remains 'new' (not cancelled)
16. This respects librarian's decision that item will return in time

Test C - No booking scenario:
17. Return item, ensure no active bookings exist
18. Check out item to any patron
19. Verify checkout works normally without errors

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-08-14 16:05:50 -06:00
Lucas Gass a8fd9734c6
Bug 40296: Mark booking as completed when issuing to booking patron
This patch adds logic to automatically mark a patron's booking as
'completed' when they check out the item they have booked.

When AddIssue is called, the system now:
- Checks if there's a conflicting booking for the checkout period
- Marks the booking status as 'completed' if found

This ensures booking status accurately reflects when items are
actually checked out to fulfill bookings.

Test plan:
1. Enable bookings system preference
2. Create a bookable item (set bookable = 1 in items table or via item editor)
3. Create a booking for a patron for that item with start date = today,
   end date = 7 days from now
4. Go to circulation and check out the item to the same patron who made
   the booking
5. Check the booking status in the database or via the bookings interface
6. Verify the booking status has changed from 'new' to 'completed'
7. Confirm the checkout was successful and shows normally in patron's
   checkouts list

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-08-14 16:05:50 -06:00
David Cook a6713d8849
Bug 38997: Remove outdated developer doc
This change removes a line in the developer doc which is no
longer relevant.

There's not really much to test here.

Signed-off-by: Lin Wei Li <lin-wei.li@inLibro.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-08-14 16:05:47 -06:00
Baptiste Wojtkowski 1cb2f97e8c
Bug 38619: UNIMARC prices should also be extracted from 071d
When adding a document that does not use 010d as price document, but 071d, the price is not imported from koha since it only checks 010d and 345d.

To reproduce:
1 - Create a Koha item, make sure there is neither 010d or 345d
2 - Add a 071d and fill a price
3 - Export the item as marcxml
4 - If you do not have one: in acquisition, create a vendor, a basket associated to this vendor, and a line associated to this vendor
5 - Add a line to any open basket, select: import "from a new file" and
  select the exported marcxml -> The price in 071 is not imported
6 - Apply patch
7 - Repeat 5 -> the price is properly imported

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>
2025-08-14 16:05:46 -06:00
Laura_Escamilla 9d5d88b0eb
Bug 39427: Searching lists table by owner can only enter firstname or surname
To test:
1. Ensure that the virtual shelves system preference is enabled
2. Create one or two lists using a patron that has both a first and last name. You don’t have to add items to the list, the list itself is enough.
3. Under the Owner column in the Lists table, search using the patron’s first name. Note that the name is properly filtered.
4. Next, try to search by the last name. It is also properly filtered.
5. Now search using both the first name and the last name together. Note that the results come up empty.
6. Apply the patch.
7. Repeat steps 3–5. Note that the patron shows in the results with just the first name, the last name, and the full name.
7.1. Additionally, try searching with extra spaces (e.g., ' Firstname Surname ' or 'Firstname Surname'). Confirm that results are still correctly shown.
8. Run t/db_dependent/Virtualshelves.t
9. Sign off and have a great day! :D

Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-08-01 13:22:38 -06:00
Tomas Cohen Arazi 9cad25967d
Bug 40270: Fix uninitialized value warnings in SIP logging
The SIP server generates warnings when logging account information
for failed logins:

Use of uninitialized value $args[0] in sprintf at /kohadevbox/koha/C4/SIP/Sip.pm line 314
Use of uninitialized value $args[1] in sprintf at /kohadevbox/koha/C4/SIP/Sip.pm line 314

This occurs when $self->{account}->{id} or $self->{account}->{institution}
are undefined during failed authentication attempts.

This patch fixes the issue by:
1. Adding a safer sprintf implementation in siplog that handles undefined values
2. Providing default values for undefined account information in logging calls

To test:
1. Start SIP server
2. Attempt to connect with invalid credentials using sip_cli_emulator.pl:
   ./misc/sip_cli_emulator.pl -a 127.0.0.1 -p 6001 -su invaliduser -sp wrongpass -l kohalibrary2 --patron koha -m patron_information
3. Check /var/log/koha/kohadev/sip-output.log
=> FAIL: 'Use of uninitialized value...' warns
4. Apply this patch
5. Repeat 2
=> SUCCESS: No "Use of uninitialized value" warnings appear
=> SUCCESS: Logging shows 'undef/undef' for failed logins instead of empty strings
6. Try a valid login
=> SUCCESS: Still works correctly for valid logins
7. Sign off :-D

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-08-01 13:22:36 -06:00
Tomas Cohen Arazi 36df107fc9
Bug 40037: (follow-up) Remove redundancy in `before_send_messages`
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-07-28 16:26:41 -06:00
Tomas Cohen Arazi 17d02662c4
Bug 40037: Remove redundant check in `notices_content` hook handling
I reused an implemented hook in C4::Letters and overlooked the
redundancy in it. This patch clears that.

To test:
1. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Koha/Plugins/Notices_content_hook.t
=> SUCCESS: Tests pass
2. Apply this patch
3. Repeat 1
=> SUCCESS: Tests pass! No behavior change!
4. Sign off :-D

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-07-28 16:26:41 -06:00
Baptiste Wojtkowski 007d66e314
Bug 39180: (QA follow-up) Tidy
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-07-25 14:27:20 -06:00
Nick Clemens bd32425271
Bug 39180: Catch exception when updating patron lastseen date
This patch adds a catch during circulatoin actions and passes a message back to the caller

For checkouts and renewals we don't have a method for passing messages so we simply catch the exception
and warn - this seems reasonable, as we have now added a warning on the patron display that they are missing
a guarantor

To test:
 1 - Create a Child type  patron with no guarantor
 2 - Create a patron in a non-child category that can_be_guarantee with no guarantor
 3 - Check out an item to each patron above
 4 - Enable system preference 'ChildNeedsGuarantor' and TrackLastPatronActivityTriggers - select all
 5 - In mysql
    UPDATE borrowers SET datelastseen = '2025-01-01';
 6 - Restart all to clear cache (so update last seen will update)
 7 - Attempt to checkout a book to either patron - 500 error
 8 - Attempt to returnt he books the patrons have checked out - 500 error
 9 - Attempt to renew their items - 500 error
10 - Apply patches, restart all
11 - Repeat checkout, renewal, checkin
12 - On checkout and renewal there should be a warning on the patron page, but actions succeed with no additional problems
13 - On return you get a warning letting you know the action succeeded but there is still a problem to resolve

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-07-25 14:27:18 -06:00
Lucas Gass d6883d9e3c
Bug 37883: (follow-up) Increment counts correctly
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-07-23 16:36:45 -06:00
Lucas Gass 0a22703807
Bug 37883: Add logged in branch available, other, and onloan counts
Signed-off-by: Brendan Lawlor <blawlor@clamsnet.org>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-07-23 16:36:42 -06:00
Jonathan Druart ca6cbc3cf9
Bug 40405: Set decreaseLoanHighHolds\* to 0
When reviewing the different sysprefs that had "NULL" as default, I
only found those 2 occurrences that could be problematic. I think we
should default to 0 here.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-07-23 16:36:31 -06:00