Replaces the broad manage_circ_rules permission requirement on the
circulation triggers page with a new dedicated manage_circ_triggers
sub-permission (under parameters, flag 3).
- Add manage_circ_triggers to userpermissions.sql
- Update atomicupdate to add the permission, grant it to existing
edit_notice_status_triggers users, and remove the old permission
- Update admin/circulation_triggers.pl to require manage_circ_triggers
- Add manage_circ_triggers as an OR option on all circulation_rules
API endpoints (GET/PUT /circulation_rules, /kinds, /config)
- Restrict manage_circ_triggers users in the API controller to
overdue_* rule names only on write
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The Transport Type options when displaying in 'edit' mode were showing as
a comma separated string rather than as separate options (as they do when being set).
Ammends this so that they display as separate options consistently.
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
When editing a specific rule (e.g. */Kids/Books) alongside an all/all/all
rule, the conflict check incorrectly reported a conflict. The effective=true
API response always returns context as */*/* (fallback), so ruleSetInDb.context
differed from currentRuleSet.context (which was overridden to the real context).
Fix by overriding ruleSetInDb.context before the hasConflict comparison,
consistent with the existing pattern in setCurrentRuleSet.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The x-koha-authorization was using 'parameters: catalogue' which the
Koha auth system interprets as a 'catalogue' subpermission within the
'parameters' module (which doesn't exist), causing a 403 for any user.
The correct format for the top-level 'catalogue' permission is
'catalogue: "1"', consistent with all other read-only API endpoints.
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- Add OR-type x-koha-authorization to /circulation_rules, /circulation_rules/kinds,
and /circulation_rules/config endpoints so users with either
circulate:circulate_remaining_permissions OR parameters:manage_circ_rules
can access them
- Enforce manage_circ_rules_from_any_libraries in the set_rules controller:
users without this permission may only set rules for their own library and
cannot set default (*) rules
- Add explicit use C4::Auth qw(haspermission) import to CirculationRules.pm
- Lock the library selector in the Vue UI for users who lack
manage_circ_rules_from_any_libraries, defaulting them to their own library
- Update set_rules() tests to cover the new permission restrictions
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
1. Letter context: setFilteredLetters() was reading library_id from
currentRuleSet (which has no top-level library_id property) instead
of this.context.library_id, causing library-specific letter templates
to never match.
2. False conflict on edit: conflict check fetched rule set from DB with
effective=false (raw), but the in-memory snapshot was fetched with
effective=true (with fallbacks). Comparing raw vs effective always
triggered a conflict when a context inherited any value from a more
general rule. Fixed by using effective=true for the DB fetch too.
3. Incomplete deletion: updateCircRuleSets() inside deleteRuleSet() was
called without await, creating a race condition where the page refresh
could complete before the deletion API call, leaving stale data visible.
Also added a guard to skip rule sets with no explicit rules for the
trigger being deleted, and simplified rulesForDeletion construction.
4. No rules displayed on initial load: the route watcher in
CirculationTriggersList fired immediately before init() had loaded
patron categories and item types, causing setAllExhaustiveEffectiveRuleSets()
to produce an empty result. Fixed with a metaInitialized flag that the
watcher waits for before proceeding.
5. DefaultToLoggedInLibraryOverdueTriggers syspref not respected: the
default_view template variable was computed but never applied to the
store's currentLibraryId. Fixed by passing it to init().
6. UI colors: info box background changed from #84c1f3 to #DAECFB (lighter,
matching the circulation rules page). Error alert messages changed from
alert-info (blue) to alert-warning (yellow) to match Koha conventions.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The config endpoint was gated on parameters: manage_circ_rules, while the
actual GET/PUT /circulation_rules endpoints require circulate:
circulate_remaining_permissions. Any user who can read/write circulation
rules should also be able to load the config that drives the UI.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Permissions.t:
- Remove edit_notice_status_triggers from userpermissions.sql so fresh installs
no longer seed this deprecated permission (existing installs are handled by
the atomic update)
- Add a defensive DELETE in the test to cover DBs that pre-date the atomic update
CirculationTriggers_spec.ts:
- Fix getMockCirculationRule: the helper was returning the old {rule_name,
rule_value, branchcode, ...} format; update to the current API format
{context: {...}, overdue_N_delay: ..., ...}
- Remove assertions for UI elements that do not exist (success/error flash
messages, "Existing triggers" heading, "rule set will be removed" text)
- Fix reset confirmation text to match actual component output
- Fix duplicate patron_category_id "ST" in mock patron categories
- Remove aspirational tests that checked non-implemented behaviour
- Add describe block for the no-default-triggers warning (no rules anywhere,
rules only at specific libraries, library link switches the filter)
- Add regression test for NaN trigger number when adding first rule for a library
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
When viewing the default library context with no triggers defined, show
a warning message explaining defaults apply to all libraries. If any
libraries have specific triggers, list them as clickable links that
switch the filter to that library. If no rules exist anywhere, show a
prompt to add the first trigger.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
When no circulation rules exist for a library, triggerCounts[library_id]
is undefined, causing undefined + 1 = NaN. Use nullish coalescing to
default to 0 so the first trigger correctly gets number 1.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
has_rules was a purely frontend marker stored as a circulation rule to
signal that a context had explicitly-saved overdue trigger rules. The
backend never reads it; the information is fully derivable from whether
any of delay/notice/mtt/restrict are non-null for a given context.
Replace all has_rules DB reads/writes with a hasExplicitRulesForTrigger()
helper that checks the four real rule suffixes directly. has_rules remains
as a computed in-memory concept in the Vue store (derived in findEffectiveRule)
so templates require no changes.
Also adds an atomicupdate to delete existing has_rules rows from the DB,
and removes the has_rules insert from the bug_10190 migration script.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- overdue_notices.pl: fix verbose sprintf - remove spurious \$triggered
argument (CLI 0/1 flag had replaced delay value in output) and use
the \$borr string that was computed but never included in the message
- overdue_notices.pl: remove %already_queued hash which was populated
in _enact_trigger but never read; dead code since the refactor
- C4/Overdues.pm GetBranchcodesWithOverdueRules: guard the global-rule
expansion with @branchcodes check so an empty result (no rules at all)
correctly returns an empty list instead of all branches
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The config endpoint is used exclusively by the Circulation Triggers
Vue app, which is gated on parameters/manage_circ_rules. Using
acquisition/'*' and erm/1 was inconsistent copy-paste from an
unrelated endpoint and would 403 circ-rules admins while granting
access to unrelated module users.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- Patron.pm has_restricting_overdues: sort ASC not DESC so the oldest
(most overdue) item is checked per branch/itemtype; DESC caused the
deduplication skip to discard the very items most likely to trigger
a restriction
- overdue_notices.pl: fix --itemtypesout option name in GetOptions
(was 'itemtypeouts', never matched the documented --itemtypesout flag)
- overdue_notices.pl: fix typo 'catagorycode' -> 'categorycode' in
--borcatout search, which silently broke category exclusion
- circulation_triggers.pl: add flagsrequired => parameters/manage_circ_rules
so the admin page enforces the correct permission; also add missing
use Koha::Notice::Templates
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- Store patron name/address fields in \$borrower_overdues so
prepare_letter_for_printing has data for printed/CSV/text notices
- Fix email->print fallback: look up items under original MTT key,
not the effective (fallback) key
- Set \$admin_email_address from \$library unconditionally in
_enact_trigger; previously undef in non-patron_homelibrary mode,
stripping the from_address on all queued notices
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
The previous migration had two fundamental errors:
1. It manufactured phantom empty rows for all patron categories that
had no rule, which corrupted the "most frequent" calculation.
2. It created categorycode=NULL (all-categories) default rules for
every branchcode seen, silently extending overdue notice coverage
to patron categories that had no configured rule in the old system.
The backend (overdue_notices.pl) does not consult has_rules, so
these invented defaults would cause notices to be sent to patrons
that were deliberately uncovered.
The rewrite migrates only explicit (branchcode, categorycode) pairs
that had a positive delay configured. No default rules are created.
branchcode='' maps to NULL as before. exit is replaced with return
to avoid killing subsequent atomicupdate scripts.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
user_permissions rows do not need manual cleanup because the FK on
user_permissions(module_bit, code) references permissions(module_bit, code)
ON DELETE CASCADE, so deleting from permissions automatically removes
per-patron rows.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- prevent the initial API call and subsequent exhaustive applied ruleset list generation logic from running twice
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- scroll to the add/edit form on button click
- prevent redundant full page reload upon the user swapping between adding and editing while the modal is open
- ensure robust scroll behaviour, handling:
- the URL being accessed directly
- the edit button in the table in the main page being used to access the form directly
- the stepper workflow being used
- the user swapping between add and edit once already looking at the form
- dynamic display of 'Transport Type' consistency: only show if a 'Notice' has been selected
- if a notice has been selected, prevent form submission if transport type isn't set and display an alert on submission attempt
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- improve modal scroll behaviour
- improve modal dimensions
- display contexts as a horizontal list to make better use of the available space
- fully contain dropdowns within the modal body
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
- add a config API endpoint to Circulations Triggers so permissions can be fetched
- update the permissions in the Vue App so that manage_circ_rules is required
- update the permissions in the Circulation Rules API so that manage_circ_rules is required for PUT operations
- update the circulation-rules store to so that it is compatible with recently intorduced compostables
- implement a redirect into the route so that permission requirements are honoured
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch aims to resolve the following issues as reported by comment 193:
- missing atomic update for overde_X_has_rules (amended to account for comment 227)
- existing delays being overwritten by the client when a rule set is displayed
- inability to save circulation overdue rule sets for context for which circulations rules where already set
- address bug_10190.pl db script warnings (undef values were being concatenated with strings)
- add a guard clause to bug_101090.pl: check that the tables the script pulls the data from do still exist, otherwise exit.
- remove duplicate Letters options in the circulation triggers add / edit form
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch significantly enhances the Cypress test coverage for the new
Circulation Triggers administration interface, expanding from basic
breadcrumb checks to comprehensive end-to-end testing.
Test Coverage:
- Initial page load and API error handling
- Context filtering (library, patron category, item type)
- View toggling between explicit and all applicable rules
- Tab navigation between multiple triggers
- Full CRUD operations (Create, Read, Update, Delete)
- Rule set reset functionality
- Letter template filtering by library context
- Form validation and constraint checking
- Loading states and empty states
- Error handling for all operations
- Browser navigation (back/forward buttons)
- Complex scenarios with inheritance hierarchies
New Features:
- Mock data helper functions for test fixtures
- Comprehensive API interception for all endpoints
- Tests for both success and error paths
- Placeholder value testing for fallback rules
- Increment/decrement button testing
- Multi-step form workflow validation
- Confirmation dialog testing for destructive operations
The tests follow Koha's Cypress testing patterns established in the
ERM module, using proper API mocking, clear test descriptions, and
organized test suites.
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch updates the link from the tools homepage to open the new
circulation triggers administration page.
We then remove the old overduerules controller and template, and finally
we drop the no longer referenced
C4::Overdues::GetOverdueMessageTransportTypes method and associated unit
tests.
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch updates the Koha::Patron->has_restriction_overdues method to
refer to the migrated overdue rules.
We also correct an oversight in the method prior to this patch that
meant that not all overdues were being correctly checked for a
restriction.. we were incorrectly filtering to only overdues at the
current checkin branch.
Finally, we also take account of the itemtype level addition here too.
NOTE: There weren't any unit tests for this Koha::Patron method.. we
should add some here!
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch introduces a modern Vue.js-based interface for managing circulation triggers (overdue notice/status triggers), replacing the legacy Tools-based interface with a more intuitive, feature-rich administration page.
New Features
Enhanced Visibility & Navigation
- Exhaustive effective rule lists showing all rules that apply to each context
- Toggle between "all exhaustive rules" and "explicitly set rules" views
- Advanced filtering by patron category and/or item type
- Clear display of fallback/default rules for each context
Rule Management Actions
- Delete triggers (last trigger in a sequence for any given library)
- Reset entire rule sets for a given context (with safeguards)
- Edit existing triggers with improved context awareness
- Add new triggers with intelligent delay constraints
Improved User Experience
- Multi-step form wizard with clear workflow progression
- Context-aware letter template filtering (only shows applicable templates)
- Placeholder values showing fallback rules when clearing inputs
- Dynamic min/max constraints for delay values based on neighboring triggers
- Real-time form validation and feedback
- Partial page reloads (only reload affected sections, not entire page)
- Specific loading messages for different operations
Technical Improvements
- Centralized Vuex store for state management
- Reusable CirculationTriggersForm component
- API clients for libraries, circulation rules, item types, and patron categories
- Consistent async/await pattern throughout
- Separation of repositories, utilities, and services
- Improved naming consistency and code maintainability
- "Dumb" TriggersTable component for better separation of concerns
Test Plan
Prerequisites
1. Log in to staff interface with appropriate permissions (tools_edit_notice_status_triggers)
2. Ensure you have test data: multiple libraries, patron categories, item types, and notice templates
3. Navigate to Administration > Circulation triggers (new interface)
Part 1: Basic Navigation & Interface
1. Verify the new "Circulation triggers" link appears in Administration home under the Circulation section
2. Access the new interface and confirm it loads successfully
3. Verify the default view shows either "All libraries" or your logged-in library based on DefaultToLoggedInLibraryOverdueTriggers system preference
4. Confirm the interface displays a list of triggers organized by context (library/patron category/item type combinations)
Part 2: Viewing and Filtering Rules
1. Toggle between "All exhaustive rules" and "Explicitly set rules" views
- Verify "All exhaustive rules" shows inherited/fallback rules
- Verify "Explicitly set rules" shows only rules you've specifically configured
2. Test the patron category filter:
- Select a specific patron category
- Confirm only rules for that category are displayed
3. Test the item type filter:
- Select a specific item type
- Confirm only rules for that item type are displayed
4. Test combined filters (patron category + item type simultaneously)
5. Clear filters and verify all rules display again
Part 3: Adding New Triggers
1. Click "Add trigger" button
2. Step 1 - Confirm Context:
- Select Library (required)
- Select Patron category (required)
- Select Item type (required)
- Click "Confirm context"
3. Step 2 - Review Existing Triggers:
- Verify existing triggers for this context are displayed
- Note the trigger numbers and delays
4. Step 3 - Configure New Trigger:
- Enter a delay value (should be constrained by neighboring triggers)
- Try entering an invalid delay (too low or too high) - verify validation
- Set "Restricts checkouts" (Yes/No/Fallback to default)
- Note the placeholder showing the fallback value
- Select a letter template
- Verify only templates for the selected library context appear
- Set "Debarring" options if desired
- Select "Charged notice fees" if applicable
5. Submit the form
6. Verify the new trigger appears in the list without a full page reload
7. Verify success message is displayed
Part 4: Editing Existing Triggers
1. Locate an existing trigger in the list
2. Click the edit icon/button
3. Verify the form pre-populates with existing values
4. Test delay modification:
- Try changing the delay within valid bounds - should succeed
- Try changing delay beyond neighboring triggers - should show validation error
- Use the increment/decrement buttons to adjust delay
5. Test clearing values:
- Clear a field (e.g., delay or restrict checkouts)
- Verify placeholder shows the fallback/default value
- Submit with cleared value - should save as null and inherit fallback
6. Change the letter template to a different valid template
7. Submit changes
8. Verify the trigger updates in the list without full page reload
9. Verify the changes persist after refreshing the page
Part 5: Deleting Triggers
1. Identify a trigger that is the last in its sequence
2. Click the delete button/icon
3. Verify a confirmation dialog appears
4. Confirm deletion
5. Verify the trigger is removed from the list without page reload
6. Verify the deletion persists after page refresh
7. Test delete constraints:
- Try to delete a trigger that's not the last in sequence
- Verify appropriate error/warning message
Part 6: Resetting Rule Sets
1. Locate a context with explicitly set rules (not just inherited)
2. Ensure this is not the only rule set for this trigger sequence
3. Click the "Reset" button for that context
4. Verify confirmation dialog explains what will be reset
5. Confirm the reset
6. Verify the explicit rules are removed and context now shows inherited rules
7. Verify changes persist after page refresh
8. Test reset constraints:
- Try to reset when it would leave no rules for that trigger
- Verify appropriate warning/prevention
Part 7: Context-Specific Behavior
1. Test library-specific letter filtering:
- Create/edit a trigger for a specific library
- Verify only letter templates with matching branchcode or default templates appear
- Switch to a different library context
- Verify the letter list updates accordingly
2. Test default rules:
- View rules for "All libraries" / "All patron categories" / "All item types"
- Verify these are labeled as "Default rule for [context]"
- Confirm these serve as fallback for more specific rules
3. Test DefaultToLoggedInLibraryOverdueTriggers preference:
- Set preference to "Yes"
- Reload circulation triggers page
- Verify it defaults to your logged-in library
- Set preference to "No"
- Verify it defaults to "All libraries"
Part 8: Form Workflow & Validation
1. Test required fields:
- Try submitting add/edit form without selecting library - should fail
- Try submitting without patron category - should fail
- Try submitting without item type - should fail
2. Test stepper navigation:
- Start adding a trigger
- Verify you must confirm context before proceeding
- Verify you see existing triggers before editing/adding
- Verify trigger form only appears after context confirmation
3. Test cancellation:
- Start adding/editing a trigger
- Click Cancel
- Verify you return to the list without changes
- Verify no partial data was saved
Part 9: Loading States & Messages
1. On slow connections or with many rules:
- Verify "Loading context..." appears while fetching context data
- Verify "Loading rule set information..." appears while fetching rules
- Verify section-specific loading messages appear during updates
2. After form submission:
- Verify appropriate success/error messages display
- Verify loading indicators during async operations
Part 10: Permissions
1. Log in as a user without tools_edit_notice_status_triggers permission
2. Verify the "Circulation triggers" link does not appear in Administration
3. Try accessing /cgi-bin/koha/admin/circulation_triggers directly
4. Verify access is denied
Part 11: Data Integrity & Persistence
1. Create a complex set of rules with multiple triggers across different contexts
2. Refresh the page and verify all rules persist
3. Restart the Koha services
4. Verify all rules still display correctly
5. Check the database circulation_rules table:
- Verify rules are stored with correct rule_name pattern (overdue_1_delay, etc.)
- Verify null values are properly stored for inheritance
- Verify the overdue_X_has_rules rule kind is present
Part 12: Edge Cases
1. Test with no existing triggers - verify empty state message
2. Test with maximum trigger sequences (e.g., trigger 1, 2, 3)
3. Test rapid successive edits
4. Test with special characters in letter template names
5. Test browser back/forward buttons during form workflow
Part 13: Comparison with Legacy Interface
1. Access the old interface if still available (via Tools menu)
2. Create a trigger using the new interface
3. Verify it appears correctly in the old interface (if applicable)
4. Create a trigger using the old interface (if still available)
5. Verify it appears correctly in the new interface
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch enhances the overdue_notices script to understand the newly
introduced itemtype level for overdue rules.
The original logic for digesting overdues in the overdue notices script
was flawed given the additional itemtype handling introduced in this
patchset and the way in which it handles effective fallbacks for rules.
This patch tidies the file and reworks the logic so that we fetch
overdues by patron category and branch and then iterate through those
comparing to the correct effective rules and combing them into digest
groups based on notice + trigger level.
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch updates the C4::Overdues method
GetBranchecodesWithOverdueRules to refer to the new location of these
rules in the circulation rules table. We also update the unit tests to
move the mocked data into the right location.
We could perhaps migrate this method in Koha::CirculationRules at a
later date?
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch adds support for _X_ grouped circulation rules to both the
internal and external API's for handling circulation rules.
This allows us to group overdue_X_rulename rules by an 'X' integer so we
can have triggers incremented and grouped together.
We also add the new overdue_x_* rule definition here for overdue trigger
rules.
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This patch adds the data migration for overduerules to circulation
rules.
We attempt to create the default rules based on most commonly occuring
rule values and then add overrides for all other rule values we find.
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: George Harkins <George.Harkins@cityofglasgowcollege.ac.uk>
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>