commit 421a7580e7adc3a2555ddfac3ffb0f52c2d84a3c Author: Jonathan Druart Date: Mon Aug 24 16:02:51 2020 +0200 Bug 26288: Update Select2 to 4.1.0 commit 167622c08d84d794fe7cd3b2103b77dda604f860 Author: Martin Renvoize Date: Thu Sep 17 12:38:07 2026 +0100 Bug 40934: (follow-up) Fix false positive on --code/--exclude-code mutual exclusivity The mutual-exclusivity check ran before the empty-element cleanup added for bug 37075, so a bare -c (no value) left an empty string in @letter_code, which the check saw as truthy and rejected even though -c had effectively not been used. Move the cleanup above the check. Also add the same mutual-exclusivity guard directly in C4::Letters::SendQueuedMessages, since letter_code and exclude_letter_code build the same search key and passing both would otherwise let one silently clobber the other in the hashref passed to ->search - only the CLI script enforced this until now, so any other caller could hit the silent-clobber bug. Adds regression coverage: unit tests for the new exception in SendQueuedMessages, and a script-level test reproducing the RM's reported false positive. Sponsored-by: OpenFifth Signed-off-by: Pedro Amorim commit 2a652a8d124659d2af58a6dfa7fb86ee8dc72f0d Author: Nick Clemens Date: Fri Aug 21 14:22:02 2026 +0000 Bug 40934: (QA follow-up) Don't delete the queue We already delete the queue at the start of all tests and the tests here are checking using ID, there is no reason to delete the queue again Signed-off-by: Nick Clemens Signed-off-by: Pedro Amorim commit e6908ef0a72b0e9075963aacaaccd5ce1caf50b1 Author: Martin Renvoize Date: Tue Jan 20 13:00:28 2026 +0000 Bug 40934: (follow-up) --code and --exclude-code should be mutually exclusive Both options were being accepted but only the last one in the command line was being applied. Now they are mutually exclusive like --category and --skip-category in longoverdue.pl. Signed-off-by: Nick Clemens Signed-off-by: Pedro Amorim commit 3430793f078ff008d0b0918fe3c077923f014fdf Author: Martin Renvoize Date: Wed Jan 7 15:49:32 2026 +0000 Bug 40934: Add --exclude-code option to process_message_queue.pl Some libraries want to send digest messages once per day (e.g., at 20:05) but send all other messages every hour. Currently, this requires listing almost all letter codes (~85) in the hourly cron job, which is error-prone and makes it easy to forget notifications at upgrades. This patch adds a new --exclude-code (-x) option to process_message_queue.pl that allows excluding specific letter codes from processing, making it much easier to configure digest scheduling. Changes: - Added --exclude-code option to process_message_queue.pl (repeatable) - Modified C4::Letters::SendQueuedMessages to handle exclude_letter_code parameter - Supports both scalar and array reference formats Example usage: # Send all messages except digests every hour 00 */1 * * * process_message_queue.pl --exclude-code DUEDGST \ --exclude-code PREDUEDGST --exclude-code HOLDDGST \ --exclude-code AUTO_RENEWALS_DGST # Send all messages including digests once per day 05 20 * * * process_message_queue.pl Test plan: 1. Apply both patches 2. Run: ktd --shell --run 'prove t/db_dependent/Letters.t' 3. Verify all tests pass (should show 105 tests passing) 4. Create test messages in message_queue with different letter codes: - Insert messages with codes: DUEDGST, PREDUEDGST, ACQ_NOTIF, HOLD 5. Test single exclusion: misc/cronjobs/process_message_queue.pl --exclude-code DUEDGST - Verify DUEDGST messages remain pending - Verify other messages are processed 6. Test multiple exclusions: misc/cronjobs/process_message_queue.pl --exclude-code DUEDGST \ --exclude-code PREDUEDGST - Verify both digest messages remain pending - Verify non-digest messages are processed 7. Test combined with --code option (should work together): misc/cronjobs/process_message_queue.pl --code ACQ_NOTIF \ --exclude-code DUEDGST - Verify only ACQ_NOTIF messages processed (DUEDGST excluded anyway) 8. Test help output: misc/cronjobs/process_message_queue.pl --help - Verify --exclude-code option is documented Sponsored-by: OpenFifth Signed-off-by: Marion Durand Signed-off-by: Nick Clemens Signed-off-by: Pedro Amorim commit 2bf60ebf2139cf409de8ade280831173ec91b8c9 Author: Martin Renvoize Date: Wed Jan 7 15:48:56 2026 +0000 Bug 40934: Add tests for exclude_letter_code in process_message_queue.pl This patch adds unit tests for the new exclude_letter_code functionality in SendQueuedMessages, which will allow excluding specific letter codes when processing the message queue. Test coverage includes: - Excluding a single letter code (array format) - Excluding multiple letter codes - Excluding with scalar parameter format Sponsored-by: OpenFifth Signed-off-by: Marion Durand Signed-off-by: Nick Clemens Signed-off-by: Pedro Amorim commit 0dfcddf383d8239f7ae877f2f0935c0653276f61 Author: Slava Shishkin Date: Wed Sep 16 20:41:11 2026 +0300 Bug 43296: (follow-up) Fix perltidy This follow-up fixes the formatting issue reported by xt/perltidy.t. Test plan: 1. Run prove xt/perltidy.t 2. Confirm it passes. Signed-off-by: Pedro Amorim commit 18469d46c4b09d86c8e666f19ef276407eac8e64 Author: Pedro Amorim Date: Mon Sep 21 11:55:40 2026 +0000 Bug 42667: DBRev 26.06.00.027 Signed-off-by: Pedro Amorim commit 5694e63a8cb1c6342e66226120e060ed93b6c751 Author: Lucas Gass Date: Wed Sep 16 15:07:55 2026 +0000 Bug 42667: (follow-up) Fix edit button inside of preview SQL modal Signed-off-by: Pedro Amorim commit 3d7b5c5a953559dd7ce2d1fc8ef4459f8ca4c857 Author: Lucas Gass Date: Wed Sep 16 14:52:53 2026 +0000 Bug 42667: (follow-up) Update dropdown so users can only choose to edit own report Signed-off-by: Pedro Amorim commit 51d1fe94983ae9dfc7d66338b4ab2280c55d769e Author: Martin Renvoize Date: Thu Jun 11 16:13:14 2026 +0100 Bug 42667: (QA follow-up) Test edit permission on ownerless reports Add two test cases covering reports with no borrowernumber (NULL owner): a patron without edit_all_reports should be denied, one with the permission should succeed. The POD documents this case but it was not previously exercised. Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 5da8ba1ce9509d21b9644fa27422fd3dc90e2fb9 Author: Martin Renvoize Date: Thu Jun 11 16:12:52 2026 +0100 Bug 42667: (QA follow-up) Fix null guard and exception description - Add null check around Koha::Patrons->find() in guided_reports.pl before calling ->has_permission, matching the defensive pattern already used in Koha::Report::check_edit_permission - Add missing description to Koha::Exceptions::Report base class for consistency with its sub-exceptions Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 5b5c875df9e79479e83cf6813e57c8fc0632d7c7 Author: Kyle M Hall Date: Thu May 21 13:31:52 2026 -0400 Bug 42667: Enforce permission in Koha::Report Prevents possible template bugs from allowing editing of reports by others without the proper permissions. Signed-off-by: Kyle M Hall Signed-off-by: Brendan Lawlor Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 1da4dcec000ba4cef13d4e66c6ccfeadf41824f0 Author: Kyle M Hall Date: Thu May 21 12:23:06 2026 -0400 Bug 42667: Hide edit controls as needed Test plan: 1) Apply this patch set 2) Run updatedatabase.pl 3) Restart all the things! 4) Create 2 users with create_reports and not edit_all_reports 5) Create reports with each 6) Note that each cannot edit the others reports 7) Create a user with create_reports and edit_all_reports 8) Note the this user can edit reports from the previous two users Edit button placements to look for: * Reports table row * Actions menu * Toolbar Signed-off-by: Kyle M Hall Signed-off-by: Brendan Lawlor Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit df282a5f893f217eb99653578f9ccbcb1cea0949 Author: Kyle M Hall Date: Thu May 21 12:12:55 2026 -0400 Bug 42667: Require edit_all_reports to edit other librarian's reports Signed-off-by: Kyle M Hall Signed-off-by: Brendan Lawlor Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit d2fa6156fdadadf398a2083d625e6649502a06aa Author: Kyle M Hall Date: Thu May 21 11:34:32 2026 -0400 Bug 42667: Add new edit_all_reports permission Signed-off-by: Kyle M Hall Signed-off-by: Brendan Lawlor Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 08a4e352af2b5a0bd53c8cebe8a77bcc99f72b20 Author: Jonathan Druart Date: Fri Sep 18 15:31:22 2026 +0200 Bug 42330: (follow-up) Tidy Something very messy happened during the last rebase before push. Sorry! I've restored the original version: git rebase -i HEAD~258 Edit commit b02ca1270d6eeb3 and remove the next one (Tidy) perl misc/devel/tidy.pl $(git diff --name-only HEAD~1) git commit -a git rebase --continue Luckily there was no conflict! I then picked the version of those files and here is the commit. Use this to confirm: `git show -w ad694a3411e677fcea96f315758793fd1fe0f203` You should see changes that are not related to tidiness Signed-off-by: Owen Leonard Signed-off-by: Pedro Amorim commit dfea14718301faf66f8389e74342a8adcdc59548 Author: Martin Renvoize Date: Thu Jun 18 17:01:00 2026 +0100 Bug 42385: (QA follow-up) Test PickupLibrary fall-through to ItemHomeLibrary The original _GetCircControlBranch tests covered the case where CircControl is PickupLibrary but no userenv branch is available, in which case the resolution falls through to the ItemHomeLibrary behaviour. That coverage was lost when the tests moved to t/db_dependent/Koha/Policy/Circulation.t, since the PickupLibrary subtest always mocks a userenv. This restores coverage for the fall-through path: with CircControl set to PickupLibrary, no userenv, and no pickup_library_id, the controlling library is resolved from the item's home library. Test plan: 1. Apply patch 2. Run: $ ktd --shell k$ prove t/db_dependent/Koha/Policy/Circulation.t => SUCCESS: Tests pass! 3. Sign off :-D Signed-off-by: Martin Renvoize (cherry picked from commit 6a13c6e5066384e59e52f0d48f5a430958671ef2) Signed-off-by: Pedro Amorim commit 275d870be7a961ab60705f6327f74a2b0126132d Author: Tomás Cohen Arazi Date: Tue May 5 10:20:39 2026 -0300 Bug 42385: Remove _GetCircControlBranch Removes the deprecated _GetCircControlBranch function and its export from C4::Circulation. Removes the corresponding tests from Circulation.t (now covered by t/db_dependent/Koha/Policy/Circulation.t). Test plan: 1. Apply patch 2. Run: $ ktd --shell k$ prove t/db_dependent/Circulation.t \ t/db_dependent/Koha/Policy/Circulation.t => SUCCESS: Tests pass! 3. Sign off :-D Signed-off-by: Alex Carver [Acerock7] Signed-off-by: Martin Renvoize (cherry picked from commit 8e784622815a2db2ce6f558987d7c0b0951ceec0) Signed-off-by: Pedro Amorim # Conflicts: # C4/Circulation.pm # t/db_dependent/Circulation.t commit 4f1b98160eb294d91c0d446e30eb4bc177b8e753 Author: Tomás Cohen Arazi Date: Tue May 5 10:16:25 2026 -0300 Bug 42385: Use Koha::Policy::Circulation everywhere Replaces all calls to _GetCircControlBranch with Koha::Policy::Circulation->circ_control_library in: - C4::Circulation (10 call sites) - Koha::Item (1 call site) - Koha::Recall (1 call site) - reserve/request.pl (1 call site) - svc/letters/preview (2 call sites) Test plan: 1. Apply patch 2. Run: $ ktd --shell k$ prove t/db_dependent/Koha/Policy/Circulation.t \ t/db_dependent/Circulation.t \ t/db_dependent/Koha/Items.t \ t/db_dependent/Koha/Recall.t => SUCCESS: Tests pass! 3. Sign off :-D Signed-off-by: Alex Carver [Acerock7] Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 5c833281ed064d1fa70a0c373920d224fc399740 Author: Tomás Cohen Arazi Date: Tue May 5 10:12:51 2026 -0300 Bug 42385: Add Koha::Policy::Circulation Adds Koha::Policy::Circulation->circ_control_library($item, $patron) class method that resolves which library controls circulation rules, based on the CircControl and HomeOrHoldingBranch system preferences. This follows the same pattern as Koha::Policy::Holds->holds_control_library. An optional pickup_library_id parameter allows callers in API/daemon contexts to pass the library explicitly instead of relying on userenv. Test plan: 1. Apply patch 2. Run: $ ktd --shell k$ prove t/db_dependent/Koha/Policy/Circulation.t => SUCCESS: Tests pass! 3. Sign off :-D Signed-off-by: Alex Carver [Acerock7] Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 255eeaf4f615a48f32d4d60e1ff4c882dff38d74 Author: Martin Renvoize Date: Wed Sep 16 08:38:51 2026 +0100 Bug 43375: (QA follow-up) Add test coverage for form-data fallback in userinfo parsing _get_data_and_patron() falls back to Mojo::Parameters form-data parsing whenever $tx->res->json fails to decode the userinfo response body. That branch was untested: all existing userinfo_url subtests mock json() to return a hashref, so the fallback path was never actually exercised. This adds a subtest that mocks a genuine url-encoded response body (json() returning undef) and confirms the fallback still maps data and finds the matching patron correctly. Test plan: 1. Run: $ ktd --shell k$ prove t/db_dependent/Koha/Auth/Client/OAuth.t => SUCCESS: All 6 subtests pass, including the new fallback-path test 2. Sign off Co-Authored-By: Claude Sonnet 5 Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 8b1e8f80baa37cc8892d44ab10e1ea882a773ba8 Author: Tomás Cohen Arazi Date: Mon Aug 24 14:57:28 2026 -0300 Bug 43375: Use Mojo json() with form-data fallback for userinfo parsing This patch simplifies the userinfo response parsing by relying on Mojo::Message::Response->json which decodes JSON regardless of Content-Type header parameters. If JSON decoding fails (returns undef), it falls back to URL-encoded form data parsing. This fixes integration with APIs that return extra Content-Type parameters (e.g. Microsoft Graph returns odata.metadata, odata.streaming, and IEEE754Compatible alongside charset) which previously caused the strict regex to fail and silently misparse the response as form data. Test plan: 1. Apply the regression test (previous patch) 2. Run: $ ktd --shell k$ prove t/db_dependent/Koha/Auth/Client/OAuth.t => FAIL: Subtest fails - Content-Type with extra params not recognized 3. Apply this patch 4. Repeat step 2 => SUCCESS: All tests pass 5. Sign off :-D Signed-off-by: David Nind Signed-off-by: Martin Renvoize Signed-off-by: Pedro Amorim commit 63ffc0b28fc758164f0aea6b4a6ba162a0bd03b7 Author: Tomás Cohen Arazi Date: Mon Aug 24 14:57:08 2026 -0300 Bug 43375: Regression tests This patch adds a regression test demonstrating that the OAuth userinfo_url response parsing fails when the Content-Type header contains extra parameters beyond charset (e.g. Microsoft Graph API returns application/json;odata.metadata=minimal;odata.streaming=true). The strict regex in _get_data_and_patron only matches Content-Type values with an optional ;charset=... suffix, causing valid JSON responses to be silently misinterpreted as URL-encoded form data. Test plan: 1. Apply this patch 2. Run: $ ktd --shell k$ prove t/db_dependent/Koha/Auth/Client/OAuth.t => FAIL: New subtest fails - email is undef, patron not found 3. Sign off :-D Signed-off-by: David Nind Signed-off-by: Pedro Amorim commit 6975b6616b3647cee3d507bd0f396aa6389584d2 Author: Olivia Reynolds Date: Thu Aug 6 14:20:58 2026 +0000 Bug 30319: Remove appropriate hidden fields on self-modification Previously, the system preference PatronSelfRegistrationBorrowerUnwantedField was used to remove hidden fields regardless of whether the operation was self-registration or self-modification. This patch uses the appropriate set of hidden fields depending on the current operation (create/update). Test plan: 1. Set OPACPatronDetails to "Allow". 2. Ensure PatronSelfModificationBorrowerUnwantedField is empty. 3. Set PatronSelfRegistrationBorrowerUnwantedField to exclude Title (towards the bottom right of the modal). 4. Log into the OPAC, and navigate to Your account > Personal details. 5. Change your title and submit the request. 6. Verify you see the notice "No changes were made." at the top of the page. 7. Apply patch. 8. Change your title again and submit the request. 9. Verify the request is submitted successfully. 10. Return to the personal details screen, but don't submit. 11. Set PatronSelfModificationBorrowerUnwantedField to exclude Title. 12. On the preloaded personal details screen, update the title and submit. 13. Verify you see the notice "No changes were made." at the top of the page. Sponsored-by: Open Fifth Signed-off-by: David Nind Signed-off-by: Lucas Gass Signed-off-by: Pedro Amorim commit 0fc43dd5a3fb70b3cd2b7e572acc747e26fe1f8d Author: Baptiste Wojtkowski Date: Wed Sep 16 13:48:03 2026 +0000 Bug 41742: (follow-up) Add pod to AddBudgetPeriod Create a pod coverage for AddBudgetPeriod Signed-off-by: Pedro Amorim commit 0ae6c196ecc59404f8d6ecd10d4bf437689f28a4 Author: Olivia Reynolds Date: Wed Sep 16 09:51:28 2026 +0000 Bug 39337: (follow-up) Mock OpacSuppression in Output tests Before the refactoring in this bug, redirect_if_opac_suppressed was intended to be called after checking OpacSuppression was enabled. Now it performs this check internally, so to adapt these unit tests correspondingly, we mock OpacSuppression to be enabled, as was the implied state before. Test plan: 1. Prove t/db_dependent/Output.t and verify all tests pass. Sponsored-by: Open Fifth Signed-off-by: Pedro Amorim commit bb05ef7ce8bface1d77704d415d83b336164ca5a Author: Pedro Amorim Date: Tue Sep 15 16:06:59 2026 +0000 Bug 42310: DBRev 26.06.00.026 Signed-off-by: Pedro Amorim commit 1b903bc3c58ee05f1a524726e513971423cd2c9b Author: Pedro Amorim Date: Tue Sep 15 15:52:35 2026 +0000 Bug 42310: (RM follow-up) Refresh stale DBIC checksum on Koha::Schema::Result::Branch Signed-off-by: Pedro Amorim commit 76d156d4fcc8672cf6e751de6d2a83be1bcf7453 Author: Tomás Cohen Arazi Date: Tue Sep 15 11:27:36 2026 -0300 Bug 42310: (QA follow-up) Clean up stale references to dropped calendar tables - cleanup_database.pl: rewrite DeleteSpecialHolidays to purge the new library_single_closures and library_closure_exceptions tables via their Koha::Objects classes (was querying the dropped special_holidays table). - kohastructure.sql: fix the comment header above library_repeating_closures that still referred to repeatable_holidays. - C4::Overdues: drop the dead GetSpecialHolidays / GetRepeatableHolidays / GetWdayFromItemnumber routines (unreferenced, exported nowhere) that still queried the dropped special_holidays / repeatable_holidays tables, along with the now-unused Date::Calc and Date::Manip imports. Signed-off-by: Pedro Amorim commit 51fd136eb11befc204f830fcb40ad2e04a7a7eb3 Author: Tomás Cohen Arazi Date: Mon Sep 14 10:58:14 2026 -0300 Bug 42310: (follow-up) Retire t/db_dependent/Holidays.t t/db_dependent/Holidays.t was a legacy file whose coverage is now provided by the two dedicated calendar test files. Its calendar behaviour assertions (is_holiday for weekly/day-month/single holidays) are already exercised by t/db_dependent/Calendar.t and t/db_dependent/Koha/Library/Calendar.t. The remaining unique cases queried the special_holidays / repeatable_holidays tables directly, which this bug drops during the migration to the Koha::Library::Calendar::*Closure schema, so the file could no longer run. This commit folds the unique coverage into t/db_dependent/Koha/Library/Calendar.t, rewritten against the new closure objects/API (no raw legacy-table SQL): - is_holiday DST edge case (America/Santiago days_between) - next_open_days / prev_open_days throwing NoOpenDays when the library is never open, and finding an open day created via an exception - copy_to completeness: repeating-closure copy, exception copy, and exclusion of past-dated single closures and exceptions, plus the no-duplication guarantee for all four closure types and then deletes t/db_dependent/Holidays.t. Test plan: - prove t/db_dependent/Koha/Library/Calendar.t - prove t/db_dependent/Calendar.t Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 755521ba0f6f362b5390127c9876346c9f486fd9 Author: Tomás Cohen Arazi Date: Mon Sep 14 11:23:35 2026 -0300 Bug 42310: (follow-up) Make 16.12.00.032 upgrade self-contained The historical 16.12.00.032 upgrade step (Bug 12063) instantiated Koha::Calendar to push reserves.expirationdate forward by the max pickup delay in open days. Depending on a live application class from a frozen upgrade step is fragile: when this bug renamed and removed Koha::Calendar, the migration had to be edited to chase the new namespace. Frozen updatedatabase.pl steps should be self-contained and prefer direct DB access. Reimplement the holiday-aware date advance inline, reading the legacy repeatable_holidays / special_holidays tables (which still exist at this point in the upgrade path) directly, with no dependency on any Koha::* calendar class. This keeps the step working regardless of later refactors and removes the calendar-class reference from updatedatabase.pl entirely. The weekly / day-month / single-closure logic and exception (open override) handling mirror the historical C4::Calendar semantics. Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit f4268951f08955d78bf5dee063df273def1f6239 Author: Tomás Cohen Arazi Date: Mon Sep 14 11:12:10 2026 -0300 Bug 42310: (follow-up) Fix POD coverage for Koha::Checkouts::_type The koha-qa pod_coverage check flags 'sub _type has no pod coverage' in Koha/Checkouts.pm. The POD block above the sub was headed '=head3 type' while the sub is named '_type', so the documentation was not associated with the sub. Correct the heading to '=head3 _type' to match, mirroring the adjacent object_class POD. Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 134ce6aa7c2d92ef4c1ab8fa3f3e3cf3ae060997 Author: Martin Renvoize Date: Wed Aug 5 09:07:04 2026 +0100 Bug 42310: (QA follow-up) Add test coverage for add_* cache invalidation, empty calendars, and leap-year repeating closures Coverage gaps identified during QA review: - add_single_closure/add_exception were only ever tested against a cold cache; nothing proved they invalidate a cache already warmed with the stale answer before the add. - No test exercised a library with no closures at all. - No test exercised a repeating (day/month) closure on 29 February across a leap and a non-leap year. Atomicupdate migration coverage is intentionally left out of scope. Test plan: 1) prove t/db_dependent/Koha/Library/Calendar.t t/db_dependent/Calendar.t t/db_dependent/Holidays.t t/db_dependent/HoldsQueue.t Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 3ef756f5a0e9adb6ce9d71592bd82a88846c5e83 Author: Martin Renvoize Date: Wed Aug 5 09:05:17 2026 +0100 Bug 42310: (QA follow-up) Refresh in-process closure state on add/delete_weekly_closure and add/delete_repeating_closure add_weekly_closure/delete_weekly_closure and add_repeating_closure/ delete_repeating_closure returned $self without refreshing $self->{weekly_closed_days}/{day_month_closed_days}, so a calendar object would keep reporting the pre-change state to is_holiday (and everything built on it - days_forward, next_open_days, etc.) until it was re-instantiated. This is distinct from the _holidays Koha::Caches entry, which single/exception closures already flush correctly on store/delete. Call _init to rebuild both structures from the database after each add/delete, so the same object reflects the change immediately. Test plan: 1) prove t/db_dependent/Koha/Library/Calendar.t t/db_dependent/Calendar.t t/db_dependent/Holidays.t t/db_dependent/HoldsQueue.t t/db_dependent/Holds/WaitingReserves.t t/db_dependent/Koha/CurbsidePickups.t t/db_dependent/Reserves/CancelExpiredReserves.t t/db_dependent/api/v1/libraries.t Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 004fe4de21e83ebb0695233a4e3d4a9604ee7a01 Author: Martin Renvoize Date: Wed Aug 5 09:02:27 2026 +0100 Bug 42310: (QA follow-up) Reject in-place date changes on SingleClosure/Exception store() only flushes the _holidays cache on insert, on the assumption that updates only ever touch title/description. That assumption held for every current caller (ModSingleholiday/ModExceptionholiday only ever change those two fields), but nothing enforced it - a future caller updating date in place would silently desync the cache for up to its TTL, with no error. Make the assumption explicit: reject an update that changes date, rather than silently allowing it. Callers that need to move a closure/exception to a different date must delete and re-add. Test plan: 1) prove t/db_dependent/Koha/Library/Calendar.t t/db_dependent/Calendar.t t/db_dependent/Holidays.t t/db_dependent/HoldsQueue.t Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 1399f8af42721e21125d4c0eefaec81dde11ceee Author: Martin Renvoize Date: Wed Aug 5 08:55:52 2026 +0100 Bug 42310: (QA follow-up) Restore weekday validation on weekly closures C4::Calendar::insert_week_day_holiday used to croak "Invalid weekday $weekday" unless $weekday =~ m/^[0-6]$/. That guard was dropped when the insert delegated to Koha::Library::Calendar::WeeklyClosure, and nothing replaced it - an out-of-range or undef weekday now persists silently to library_weekly_closures instead of failing at the API boundary. Add the check to WeeklyClosure->store() rather than the legacy wrapper, so every caller (C4::Calendar, Koha::Library::Calendar->add_weekly_closure, and any future REST/admin caller) gets it, not just the old entry point. Test plan: 1) prove t/db_dependent/Koha/Library/Calendar.t t/db_dependent/Calendar.t t/db_dependent/Holidays.t t/db_dependent/HoldsQueue.t t/db_dependent/Holds/WaitingReserves.t Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit d0645cc8b1c0c39c80efbf5027211555847dad1c Author: Martin Renvoize Date: Wed Aug 5 08:53:40 2026 +0100 Bug 42310: (QA follow-up) Restore in-memory holiday cache sync in C4::Calendar insert_single_holiday and insert_exception_holiday delegate to Koha::Library::Calendar::SingleClosure/Exception, but stopped updating $self->{single_holidays}/{exception_holidays} on the C4::Calendar object itself, unlike the sibling insert_week_day_holiday/insert_day_month_holiday methods which still do. isHoliday() reads exactly those hashes, so a date just inserted via insert_single_holiday/insert_exception_holiday would read back as "not a holiday" for the rest of that object's lifetime - reachable from tools/newHolidays.pl and tools/exceptionHolidays.pl, which loop over several dates on one $calendar object, checking isHoliday() before each insert to skip duplicates. While adding a regression test, also found that _init() has the same class of bug on the DB-load path: it builds the single/exception lookup keys from `split(/-/, $row->{date})`, which keeps the zero-padding from the DATE string (e.g. "06"), while isHoliday() numifies its lookup key (e.g. "6"). Any single/exception holiday with a single-digit month or day was therefore invisible to isHoliday() even on a freshly reloaded C4::Calendar object. Both call sites now numify year/month/day before building the hash key. Test plan: 1) prove t/db_dependent/Holidays.t t/db_dependent/Calendar.t t/db_dependent/Koha/Library/Calendar.t t/db_dependent/HoldsQueue.t Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit e56aff8dfc24351d0f77daf3b74c0a2b62a9d8e2 Author: Martin Renvoize Date: Wed Apr 22 15:36:25 2026 +0100 Bug 42310: (follow-up) Update Holidays.t for normalized calendar tables The normalization commit dropped `repeatable_holidays` and `special_holidays` but t/db_dependent/Holidays.t still referenced them directly via raw SQL, so the test blew up on the first `DELETE FROM special_holidays` with "Table doesn't exist". The earlier namespace follow-up touched this file but only renamed Koha::Calendar references, missing the SQL. Replace the legacy table references with the four new normalized tables: repeatable_holidays (weekday set) -> library_weekly_closures repeatable_holidays (weekday NULL) -> library_repeating_closures special_holidays (isexception=0) -> library_single_closures special_holidays (isexception=1) -> library_closure_exceptions - Two fixture-cleanup DELETEs now wipe all four new tables. - The copy_to_branch 'no duplicates' check, previously two raw-SQL queries against the old two tables, becomes four queries against the new tables, keyed on each table's natural unique key (library_id+weekday / library_id+day+month / library_id+date). - Plan for the copy_to_branch subtest bumps from 8 to 10 to cover the two extra duplicate-check assertions. Test plan: 1. prove t/db_dependent/Holidays.t 2. All 15 top-level tests pass, including the 10 subtest assertions in copy_to_branch. Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 811d8bfd37dc190a999ae8b2078872d3236062af Author: Martin Renvoize Date: Fri Apr 17 16:41:21 2026 +0100 Bug 42310: (follow-up) Move Koha::Calendar tree under Koha::Library::Calendar Koha::Calendar is, by construction, a per-library object — it croaks without a branchcode argument and every method is branch-scoped. The top-level namespace hides that. Move the whole tree under Koha::Library::Calendar to match the actual semantics, the existing /libraries/{library_id}/calendar REST routes, and the established Koha::Library::* convention (Group, Hour, FloatLimit, OverDriveInfo). This commit: - renames the Koha::Calendar(::*) tree to Koha::Library::Calendar(::*) - updates package declarations, POD and internal 'use' statements within the moved tree - updates the four DBIC Schema Result overrides (koha_object_class / koha_objects_class) to the new namespace - updates callers inside C4::* modules (Calendar, Circulation, Reserves, Overdues, HoldsQueue), Koha::{Patron,Hold,Checkouts, CurbsidePickup}, circ/returns.pl, the installer and cronjobs - updates the 42310-owned tests (Calendar tests, HoldsQueue.t, Holds/WaitingReserves.t, Holidays.t, Koha/CurbsidePickups.t, Reserves/CancelExpiredReserves.t and the libraries.t CRUD block) Koha::Library->calendar, the REST controllers and the 42311 tests are updated in separate follow-up commits under their respective bugs. Test plan: - prove t/db_dependent/Koha/Library/Calendar.t - prove t/db_dependent/Calendar.t - prove t/db_dependent/Holidays.t t/db_dependent/HoldsQueue.t - prove t/db_dependent/Holds/WaitingReserves.t - prove t/db_dependent/Reserves/CancelExpiredReserves.t Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 7a8a220842fd992a9ad9c6cf389183ad6af6e30a Author: Martin Renvoize Date: Fri Apr 17 07:36:04 2026 +0100 Bug 42310: (QA follow-up) Add closed_dates_in_range to Koha::Calendar Introduces a public Koha::Calendar->closed_dates_in_range($from_dt, $to_dt) method that returns an arrayref of ISO date strings representing every closed day in the inclusive range, honouring weekly, annual repeating, single and exception (open-override) closures. This replaces callers that were reaching into Koha::Calendar private state (_holidays, weekly_closed_days, day_month_closed_days) to reconstruct the same logic. A follow-up under Bug 42206 converts the REST controller; further callers can be migrated incrementally. Test plan: 1. prove t/db_dependent/Koha/Calendar.t 2. Verify the new 'closed_dates_in_range' subtest passes Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 5875ce4c752a75d9f98a6637bb8a636ce6b63054 Author: Martin Renvoize Date: Fri Apr 17 07:32:55 2026 +0100 Bug 42310: (QA follow-up) Report duplicate rows skipped during migration The new calendar tables add UNIQUE(library_id, weekday), UNIQUE(library_id, day, month) and UNIQUE(library_id, date) constraints that did not exist on repeatable_holidays / special_holidays, so the INSERT IGNORE migration can silently drop legacy duplicate rows. This patch compares source vs destination row counts for each of the four migrations and emits a say_warning naming the constraint and pointing the operator at their pre-upgrade backup so titles or descriptions can be recovered if needed. Success lines now include the migrated row count. DROP statements for the legacy tables are guarded with TableExists and reported via say_success for consistency with the rest of the atomicupdate. Test plan: 1) Apply the update on a database containing legacy duplicates and verify the warning is emitted with the correct count. 2) Apply on a database with no duplicates and verify no warning appears. 3) Re-run the update and verify it is idempotent (no warnings, no re-migration). Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 548903ba022338f9dca7863d1b3c156d9070d5b8 Author: Martin Renvoize Date: Fri Apr 17 07:31:52 2026 +0100 Bug 42310: (QA follow-up) Harden Koha::Calendar->copy_to Wrap the body in schema->txn_do so a failure partway through does not leave the target library partially populated. Flush the target's _holidays cache after the copy, and document the behaviour in POD: weekly and repeating closures are always copied, but single closures and exceptions are filtered to today-or-later dates by design. Test plan: 1) prove t/db_dependent/Koha/Calendar.t 2) Confirm existing copy_to tests still pass. Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit c3880a70e6dcbfba9c817c25ac0b77477a0e8cc6 Author: Martin Renvoize Date: Fri Apr 17 07:30:42 2026 +0100 Bug 42310: (QA follow-up) Fire per-row delete hooks in Koha::Calendar delete_* methods The four delete_*_closure / delete_exception methods in Koha::Calendar were calling ResultSet->delete, which issues a single bulk SQL DELETE and never calls the row-level delete() override. The cache-invalidation hooks on Koha::Calendar::SingleClosure->delete and Koha::Calendar::Exception->delete were therefore skipped when callers went through $library->calendar->delete_single_closure(...) or delete_exception(...), and the _holidays cache kept reporting deleted dates as closed until its TTL expired. The underlying tables enforce UNIQUE constraints on (library_id, weekday), (library_id, day, month) and (library_id, date), so each search can match at most one row. Switch the four methods to ->search({...}, { rows => 1 })->single followed by ->delete on the row, which both makes the single-row expectation explicit and ensures the per-row delete override runs. A regression test is added to t/db_dependent/Koha/Calendar.t asserting that the _holidays cache is cleared after delete_single_closure and delete_exception. Test plan: 1) prove t/db_dependent/Koha/Calendar.t 2) Confirm the new 'delete_*_closure clears _holidays cache' subtest passes. Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit d4e4f57072e86b65624a93115f4fd41b15281781 Author: Tomás Cohen Arazi Date: Thu Apr 9 12:48:59 2026 -0300 Bug 42310: (follow-up) Bake cache invalidation into Koha::Object classes When using the new Koha::Calendar::* classes for writing the CRUD API endpoints I noticed that in my attempt to keep C4::Calendar similar to what it was, I ended up with cache invalidation not always done in the right place. The holidays cache (keyed by {branchcode}_holidays) stores dates and their open/closed status, not titles or descriptions. This means only inserts and deletes need to invalidate it — metadata updates (title/description) do not. Following the pattern established by Koha::AuthorisedValue and Koha::ItemType, I added store() and delete() overrides to Koha::Calendar::SingleClosure and Koha::Calendar::Exception: - store() flushes the cache only on insert (!in_storage), not on updates, since the cache doesn't store titles or descriptions. - delete() always flushes, since removing a closure changes the cached set. This allowed removing the now-redundant _clear_cache calls from Koha::Calendar::add_single_closure, add_exception, delete_single_closure, delete_exception, and from C4::Calendar::ModSingleholiday and ModExceptionholiday. Signed-off-by: Tomás Cohen Arazi Signed-off-by: David Nind Signed-off-by: Martin Renvoize Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit cb7968387a96636eff093a6ca6d427088fa93990 Author: Tomás Cohen Arazi Date: Wed Apr 8 16:07:44 2026 -0300 Bug 42310: (follow-up) Add CRUD methods to Koha::Calendar, delegate C4::Calendar Add to Koha::Calendar: add_weekly_closure, add_repeating_closure, add_single_closure, add_exception, delete_weekly_closure, delete_repeating_closure, delete_single_closure, delete_exception, copy_to, _clear_cache C4::Calendar write methods now delegate to Koha::Calendar instead of using raw DBI. No old table references remain in C4::Calendar. Tests in t/db_dependent/Koha/Calendar.t cover all CRUD operations: create, verify via is_holiday, delete, copy_to (including idempotency). Signed-off-by: Tomás Cohen Arazi Signed-off-by: David Nind Signed-off-by: Martin Renvoize Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 4d23dff4339e14a8d527397652edd6c54d4b168e Author: Tomás Cohen Arazi Date: Wed Apr 8 15:48:56 2026 -0300 Bug 42310: (follow-up) Adapt Calendar tests to new schema Replace all references to the dropped tables (RepeatableHoliday, SpecialHoliday resultsets and raw DBI inserts) with Koha::Object classes: Koha::Calendar::WeeklyClosure, RepeatingClosure, SingleClosure, and Exception. Signed-off-by: Tomás Cohen Arazi Signed-off-by: David Nind Signed-off-by: Martin Renvoize Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit 166e9831ea3ede2971f9445cf037cf0bc722b952 Author: Martin Renvoize Date: Wed Aug 5 08:59:14 2026 +0100 Bug 42310: DBIC schema manual updates Add koha_object_class/koha_objects_class overrides for the four new Result classes backing the normalized calendar tables, below the auto-generated marker. Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit c0349ad1426e4668b94bf04e060d2982c0a829d8 Author: Martin Renvoize Date: Wed Aug 5 08:58:38 2026 +0100 Bug 42310: DBIC schema update Regenerated via dbic --force after the library_weekly_closures, library_repeating_closures, library_single_closures, and library_closure_exceptions tables replaced repeatable_holidays and special_holidays. Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim commit ca487a18e0d4ad2e9284079d395f4e301215894d Author: Tomás Cohen Arazi Date: Wed Apr 8 15:37:35 2026 -0300 Bug 42310: (follow-up) Add missing POD Signed-off-by: Tomás Cohen Arazi Signed-off-by: David Nind Signed-off-by: Martin Renvoize Signed-off-by: Tomás Cohen Arazi Signed-off-by: Pedro Amorim