Commit Graph

9385 Commits

Author SHA1 Message Date
Pedro Amorim 0bbd97a4b9
Bug 37893: (QA follow-up): Fix pod_coverage.t
To test:
prove -v /kohadevbox/koha/xt/author/pod_coverage.t

The changes to Schema files are fixes that were overlooked originally.

The 'die' line in C4/SIP/Sip/Configuration.pm is to force the script to die if SIP configuration does not exist, which only happens when running pod_coverage.t
The original code (prior to 37893) did not consider the possibiliy of a config_file being invalid or undef, parser->XMLin(config_file) died silently, but because pod_coverage.t skips over files that die, it didn't fail. See bug 41271.
Now, with the changes from bug 37893, if a config_file doesnt exist the code falls back to whats in the cache, so it doesn't try to XMLin load an invalid config_file anymore, and fails verbosely.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-19 10:05:29 -07:00
Martin Renvoize c1a97af67c
Bug 37893: (QA follow-up): Remove plaintext password storage from SIP2
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>
2025-11-18 11:21:06 -07:00
Pedro Amorim f70d7a5405
Bug 37893: (QA follow-up): Address qa script complaints
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>
2025-11-18 11:21:04 -07:00
Pedro Amorim ab7684ca2b
Bug 37893: Reimplement check for fresh SIP config
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>
2025-11-18 11:21:04 -07:00
Pedro Amorim 3866d85555
Bug 37893: (QA follow-up): Nuke server params and listeners from UI
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>
2025-11-18 11:21:03 -07:00
Pedro Amorim b1c964db86
Bug 37893: Handle SIP config updates
The classes that use Koha::SIP2::Object as base update the
config_timestamp server param whenever an object of said classes is
inserted, updated or deleted.

This patch considers that, and performs a check to see if the
config_timestamp is more recent than the one which the SIP server was
started with. If it is, config is fetched from the database for up to
date configurations.

Note: The classes currently using Koha::SIP2::Object as base are as
follows:
Koha::SIP2::Account
Koha::SIP2::Institution
Koha::SIP2::SystemPreferenceOverride

The 2 classes that are left out are:
Koha::SIP2::Listener
Koha::SIP2::ServerParam

A UI message is shown when CRUDing any of the 2 above informing that a
SIP server restart is required for the changes to take effect.
The reason these 2 are left out is because they're loaded and only
utilized when the SIP server is launched.

Co-authored-by: Mark Hofstetter <mark@hofstetter.at>
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>
2025-11-18 11:20:59 -07:00
Pedro Amorim 8e83b27a0f
Bug 37893: SIP Configuration read from database
To test:
perl ./C4/SIP/SIPServer.pm /etc/koha/sites/kohadev/SIPconfig.xml

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>
2025-11-18 11:20:57 -07:00
Alex Carver 7fc86a6eb5
Bug 18584: Remove trailing spaces in Barcodes.pm
In legacy code, some trailing whitespaces have been left for training purposes.
This patch removes the trailing whitespace at line 266 in C4/Barcodes.pm

Test plan:
1. View C4/Barcodes.pm and note trailing whitespace at line 266.
2. Apply patch.
3. View C4/Barcodes.pm and note trailing whitespace has been removed.

Signed-off-by: Alex Carver <alexcarver@gmail.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-18 06:56:42 -07:00
Lari Taskula dbf812869d
Bug 41104: Remove -sameSite from checkauth() response headers
To test:
1. prove t/db_dependent/Auth.t
2. Observe success

Signed-off-by: David Cook <dcook@prosentient.com.au>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-17 15:15:51 -07:00
Janusz Kaczmarek 082de62252
Bug 33296: Linker should search for authority records with an appropriate 008/14,15,16 value
In an authority record, 008/14 = 'a' says it's appropriate for use as a
main or added entry (1xx, 7xx), 008/15 = 'a' says it's appropriate for
use as a subject entry, and 008/16 = 'a' says it's appropriate for use
as a series entry.

Test plan:
==========
1. Have a standard KTD environment. Have the patches from Bug 38494
   applied.
2. Set AutoLinkBiblios system preference to 'Do', and
   ConsiderHeadingUse to 'Do'.
3. Open an existing bibliographic record and add a new field 650. In
   subfield $a enter 'Application software' (without quotes), and in $x
   'Development.' (with final dot).
4. Save the record. In Normal view control that the entered subject
   heading entry has been linked with the existing authority record (note
   the magnifying glass icon).
5. Apply the patch ; restart all.
6. Repeat p. 3. Note that this time the newly entered subject heading
   entry has not been linked with the existing authority record. This is
   because the authority record has 008/15 = '|' while 'a' is required with
   ConsiderHeadingUse.
7. In Authorities, find the record for 'Application
   software--Development.' Modify it by changing 008/15 to 'a' (Heading
   use--subject added entry).
8. Return to the bibliographic record. Open it in the editor and save.
   The subject heading entry for 'Application software--Development.'
   should now be linked with the existing authority record.

Signed-off-by: Roman Dolny <roman.dolny@jezuici.pl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-07 10:54:13 -07:00
Martin Renvoize 316304431a
Bug 35451: (follow-up) Save join in C4::Serials::DelSubscription
We can use the new record_table field to save ourselves a join in here
too.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-07 10:54:07 -07:00
Martin Renvoize 0c7e44022e
Bug 35451: (follow-up) Fix C4::Acquisition::TransferOrder
This patch adds table name to the additional fields clone found insdie
TransferOrder.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-07 10:54:06 -07:00
Jonathan Druart ce474740a2
Bug 39860: Fix selenium/opac_holds.t
#   Failed test 'Correctly in search results page'
        #   at t/db_dependent/selenium/opac_holds.t line 88.
        #                   'Error: Can't use an undefined value as a HASH reference at /kohadevbox/koha/C4/XSLT.pm line 247'
        #     doesn't match '(?^u:Results of search for 'opac holds test place hold button')'

might be a conflict with bug 40943

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-07 07:43:59 -07:00
Lucas Gass 7463cb4fb5
Bug 39860: Update scrubber profile and add Scrubber.t test
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:47 -07:00
Lucas Gass 7ace056e45
Bug 39860: Add record_display srubber profile
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:47 -07:00
Lucas Gass 4189541772
Bug 39860: Add options for opac/staff lists
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:46 -07:00
Lucas Gass c55388dd86
Bug 39860: Move display control from system preference to additional contents
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:45 -07:00
Lucas Gass 9cdb95121e
Bug 39860: Allow for the defining of custom MARC fields on the staff interface record display pages
To test:
0. APPLY PATCH, restart_all
1. Find or create a record that has some MARC fields that don't show up by default in the record display. ( I tested using a 538$a )
2. Go to Tools and you should see a new link for 'Record display customizations'.
3. From Record display customizations click 'New Entry'
4. Choose a display location, the choices should be StaffResultsPage, StaffDetailPage, OPACResultsPage, and OPACDetailPage
5. Add the following to the entry:

[% IF record.subfield('538' , 'a') %]
  <span class="results_summary test1">
      <span class="label">The 538a: </span>
      [% record.subfield('538' , 'a') %]
  </span>
[% END %]

6. Go to the record from step 1, you should see the 538$a labeled as 'The 538a:' with the appropriate data in it.
7. This should display in the appropriate location depending on if you chose StaffResultsPage, StaffDetailPage, OPACResultsPage, or OPACDetailPage. Check each of the locations.
8. Make a new, or edit existing, Record display customization and mark the 'Library:' field for a specific branch. Make sure that the Record display customization only shows up when you are logged in at that branch.
9. Install a new language pack, I tested with es-ES.
10. Make a new, or edit existing, Record display customization and fill out the language specific tab. Make sure the Record display customization shows correctly with the language you chose.

Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Anneli Österman <anneli.osterman@koha-suomi.fi>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-11-03 14:13:45 -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
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 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 0a0ba6fea0
Bug 40517: (QA follow-up): Cleanup obsolete code
The patch 'Move creation of hold group into Patron class' is
moving the creation of the hold group logic to the Patron.pm class file
but it didn't remove all the obsolete code.
This is fixed here.

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>
2025-10-29 11:50:10 -06:00
Jonathan Druart f073262263
Bug 40978: Remove warnings from Budgets.t
If no shipment_budget is set then undef is set as key of the hashref
which generates a warning:
  Use of uninitialized value $row[0] in hash element at /usr/lib/x86_64-linux-gnu/perl5/5.40/DBI.pm line 2122.

Later we only access the hashref by budget_id, so this change seems
safe.

Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-24 07:57:06 -06:00
Jonathan Druart eba0060286
Bug 41042: default_save_state is enabled by default
If 'default_save_state' is not in the yaml file then the feature is
enabled by default.

Caught by the following failure:
t/db_dependent/selenium/patrons_search.t ..
        #   Failed test 'Search works when category of patrons is limited to a library we are not signed in at'
        #   at t/db_dependent/selenium/patrons_search.t line 471.
        #          got: 'Showing 1 to 5 of 26 entries (filtered from 82 total entries)'
        #     expected: 'Showing 1 to 15 of 26 entries (filtered from 82 total entries)'
        # Looks like you failed 1 test of 1.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-23 11:33:32 -06:00
Marcel de Rooy 72336b36c5
Bug 40017: (follow-up) More rigorous checking
Adding a few checks to resolve the errors David found while
testing.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
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-10-22 07:42:53 -06:00
Marcel de Rooy 3e2a9aef93
Bug 40017: Add leader and control field positions to Z3950 search results
Test plan:
Run t/Breeding.t
Set AdditionalFieldsInZ3950ResultSearch to 000p6, 008, 040$b
Do some searches and check the Additional fields column of results.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
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-10-22 07:42:52 -06:00
Jonathan Druart de27044ba2
Bug 41042: Make 'default sort order' available to new installations
If a row exists in DB for a given table, default_sort_order will be NULL
in DB which will replace the flag from the YAML file: the feature won't
be available.

Test plan:
0. checkout main (we don't want bug 30633)
1. Go to http://localhost:8081/cgi-bin/koha/admin/columns_settings.pl#biblio-detail%7Choldingst
=> Notice that "Default sort order" is not available for 'holdingst'
(it's added by bug 30633)
2. Save
3. Verify what you have in DB:
select * from tables_settings where module="opac" and tablename="holdingst";
4. Apply 30633, restart_all
5. Go to http://localhost:8081/cgi-bin/koha/admin/columns_settings.pl#biblio-detail%7Choldingst
=> Notice that "Default sort order" is not available for 'holdingst' (not ok)
6. Save
7. Verify what you have in DB:
select * from tables_settings where module="opac" and tablename="holdingst";
8. Apply this patch set
9. Go to http://localhost:8081/cgi-bin/koha/admin/columns_settings.pl#biblio-detail%7Choldingst
=> Notice that "Default sort order" is available for 'holdingst'!
10. Save, verify what you have in DB.

Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-20 10:12:53 -06:00
Martin Renvoize 1571fd489c
Bug 40983: Complete deprecation of old after_biblio_action hook signature
This patch completes the deprecation cycle started in bug 36343 by
removing the backward compatibility code and deprecation warnings for
the old after_biblio_action hook signature.

Changes made:
1. Removed the duplicate biblio and biblio_id parameters from
   _after_biblio_action_hooks in C4::Biblio that were marked for
   deprecation in 24.11.00
2. Updated the test plugin to use only the new payload-based signature,
   ensuring all parameters are accessed via $params->{payload}

The after_biblio_action hook now consistently uses the modern signature
with a payload parameter, matching the pattern used by other plugin hooks
like before_biblio_action, after_item_action, and after_hold_action.

Test plan:
1. Run: prove t/db_dependent/Koha/Plugins/Biblio_and_Items_plugin_hooks.t
2. Run: prove t/db_dependent/Koha/Plugins/
3. Run: prove t/db_dependent/Biblio.t
4. All tests should pass

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-14 14:51:53 -06:00
Martin Renvoize 1884f68c5b
Bug 40866: Implement Alternative pattern for holds override logging (Part 4)
This patch implements proper override logging for holds following the
Alternative implementation pattern used for checkouts and renewals.

Instead of just removing the orphaned logging code from the original
Bug 9762 implementation, this patch properly implements override logging
by updating AddReserve to accept and log override information, similar
to how AddIssue handles confirmations and forced overrides.

Changes:

C4/Reserves.pm:
- Added JSON qw(to_json) import
- Updated AddReserve to accept confirmations and forced parameters
- Enhanced the existing logaction call to include override information
  in JSON format when overrides are present
- Log format matches the Alternative implementation pattern:
  * hold ID
  * branchcode
  * biblionumber
  * itemnumber
  * confirmations array
  * forced array

Koha/REST/V1/Holds.pm:
- Added confirmations array building in the add() method
- Pass 'HOLD_POLICY_OVERRIDE' confirmation when override_all is true
- Pass confirmations parameter to AddReserve call

reserve/request.pl:
- Removed orphaned original implementation logging code
- Removed unused variables and imports (message, @message, user, etc.)
- Removed C4::Log import

koha-tmpl/intranet-tmpl/prog/en/includes/action-logs.inc:
- Added 'HOLD_POLICY_OVERRIDE' case to translate_log_override block
- Displays as "Hold policy override" in log viewer

koha-tmpl/intranet-tmpl/prog/en/modules/tools/viewlog.tt:
- Added JSON display handling for HOLDS module (similar to CIRCULATION)
- Displays hold ID, biblionumber, and optional itemnumber with links
- Shows forced and confirmation overrides using translate_log_override

This ensures hold overrides are logged consistently with the Alternative
implementation pattern, providing proper audit trails for policy overrides
that are properly displayed in the log viewer.

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-09 14:58:34 -06:00
Martin Renvoize 2fea44ff25
Bug 40866: Remove original Bug 9762 implementation remnants (Part 1)
This patch removes the duplicate logging code from the original
Bug 9762 implementation that was not properly removed when the
Alternative implementation was merged.

The original implementation added separate logaction() calls in
CanBookBeIssued and circulation.pl that created additional log
entries with a different JSON format. This caused double logging
when the Alternative implementation (which logs via AddIssue) was
merged on top.

Changes in this patch:

C4/Circulation.pm:
- Removed @message_log array and all pushes to it
- Removed the separate logaction() call at the end of CanBookBeIssued
- Removed 5th return value (@message_log) from CanBookBeIssued
- Removed all if ($issueconfirmed) blocks that were populating @message_log

circ/circulation.pl:
- Removed the problematic line that added OVERRIDDEN to every confirmed
  checkout: $needsconfirmation->{'OVERRIDDEN'} = $issueconfirmed

This addresses the double logging issue where circulation overrides
were being logged twice with different formats.

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2025-10-09 14:58:32 -06:00
Tomás Cohen Arazi 220fdce180
Bug 40915: Add enhanced debug logging for empty critical fields in SIP message parsing
This patch adds debug logging to C4::SIP::Sip::MsgType::_initialize() to help
identify when critical fields (patron_id, item_id) are parsed as empty values.

Empty critical fields in SIP messages can later cause DBIx::Class constraint
errors when passed to Koha::Objects->find() operations, generating confusing
'Odd number of elements in anonymous hash' errors in SIP server logs.

The enhanced logging helps administrators identify the root cause by logging
when empty patron_id or item_id fields are detected during message parsing.

To test:
1. Apply regression tests patch first
2. Run:
   $ ktd --shell
  k$ prove t/db_dependent/SIP/MsgType.t
=> FAIL: Debug logging tests fail (no enhanced logging present)
3. Apply this patch
4. Run:
   $ ktd --shell
  k$ prove t/db_dependent/SIP/MsgType.t
=> SUCCESS: All tests pass, debug logging works correctly
5. Sign off :-D

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-10-09 14:58:31 -06:00
David Cook e5a302d968
Bug 40622: Add missing interface parameter
This change adds the missing interface parameter which
Bug 38233 initially added.

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-10-06 09:15:27 -06:00
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