Bug 41728

Summary: Add `Koha::Item::Checkin::Availability` to centralize logic
Product: Koha Reporter: Tomás Cohen Arazi (tcohen) <tomascohen>
Component: Architecture, internals, and plumbingAssignee: Tomás Cohen Arazi (tcohen) <tomascohen>
Status: Needs Signoff --- QA Contact: Testopia <testopia>
Severity: enhancement    
Priority: P5 - low CC: andrew, dcook, jonathan.druart, Laura.escamilla, martin.renvoize, nick, tomascohen
Version: Main   
Hardware: All   
OS: All   
GIT URL: Initiative type: ---
Sponsorship status: --- Comma delimited list of Sponsors:
Crowdfunding goal: 0 Patch complexity: Medium patch
Documentation contact: Documentation submission:
Text to go in the release notes:
Version(s) released in:
Circulation function:
Bug Depends on:    
Bug Blocks: 24401    
Attachments: Bug 41728: Add Koha::Availability::Result base class
Bug 41728: Add Koha::Item::Checkin::Availability class
Bug 41728: Make AddReturn use Koha::Item::Checkin::Availability
[POC] Bug 41728: Add Koha::Item::Checkout::Availability class

Description Tomás Cohen Arazi (tcohen) 2026-01-28 18:18:28 UTC
I propose we move the checks from `C4::Circulation::AddReturn` into a proper class for reusing it in other places, specially on the API controllers.
Comment 1 Tomás Cohen Arazi (tcohen) 2026-01-28 19:12:29 UTC
Created attachment 192130 [details] [review]
Bug 41728: Add Koha::Availability::Result base class

This patch introduces a standardized result class for availability checks,
providing a clean API with proper methods instead of raw hashrefs.

The Koha::Availability::Result class provides:
- add_blocker() - Add conditions that prevent the action
- add_confirmation() - Add conditions requiring user confirmation
- add_warning() - Add informational messages
- set_context() - Store related objects (item, checkout, patron, etc.)
- available() - Check if action can proceed (no blockers)
- needs_confirmation() - Check if confirmations are required
- Accessor methods for all categories
- to_hashref() for backward compatibility

This design:
- Provides a consistent interface across all availability checks
- Makes the API more discoverable and self-documenting
- Enables future enhancements without breaking changes
- Follows OO principles with proper encapsulation
- Can be used as base for checkout, hold, renewal availability

Test plan:
1. Apply patch
2. Run:
   $ ktd --shell
  k$ prove t/Koha/Availability/Result.t
=> SUCCESS: Tests pass!
3. Verify all methods work correctly
4. Sign off :-D
Comment 2 Tomás Cohen Arazi (tcohen) 2026-01-28 19:12:30 UTC
Created attachment 192131 [details] [review]
Bug 41728: Add Koha::Item::Checkin::Availability class

This patch introduces a new class to centralize and extract check-in
validation logic from C4::Circulation::AddReturn. The class provides
a clean interface for checking whether an item can be checked in,
returning a Koha::Availability::Result object.

The class is designed with the item as the subject of the check-in
operation, following the pattern: "Can THIS ITEM be checked in?"

The class extracts the following validation logic from AddReturn:
- Withdrawn item handling (BlockedWithdrawn blocker)
- Lost item handling (BlockedLost blocker)
- Branch check-in policy validation (Wrongbranch blocker)
- Not issued detection (NotIssued confirmation)

This separation enables:
- Reusable validation logic for REST API and legacy code
- Pre-flight availability checks without side effects
- Structured responses for confirmation flow implementation
- Better testability and maintainability

The check() method accepts an item object and returns a
Koha::Availability::Result object with blockers, confirmations,
warnings, and context (checkout, patron).

A convenience instance method is added to Koha::Item:
  $item->checkin_availability({ branch => $branch })

Test plan:
1. Apply patch
2. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Koha/Item/Checkin/Availability.t
=> SUCCESS: Tests pass!
3. Verify all validation scenarios work correctly:
   - Withdrawn items blocked when syspref enabled
   - Lost items blocked when syspref enabled
   - Wrong branch returns blocked per AllowReturnToBranch
   - Not issued items handled correctly
   - Checked out items return checkout and patron objects
4. Sign off :-D
Comment 3 Tomás Cohen Arazi (tcohen) 2026-01-28 19:12:32 UTC
Created attachment 192132 [details] [review]
Bug 41728: Make AddReturn use Koha::Item::Checkin::Availability

This patch refactors AddReturn to use the new Koha::Item::Checkin::Availability
class for validation logic, eliminating code duplication and centralizing
check-in validation.

Changes:
- Add use statement for Koha::Item::Checkin::Availability
- Look up item first, return BadBarcode if not found
- Call $item->checkin_availability() for validation
- Use Result object methods (available(), blockers, context)
- Replace inline withdrawn/lost/branch validation with blocker handling
- Remove duplicate CanBookBeReturned() call (now in Availability class)
- Preserve all existing behavior and error messages
- Maintain backward compatibility

The refactoring extracts ~40 lines of validation logic while maintaining
identical functionality. All validation results are obtained from a single
availability check that returns a Result object.

Note: The withdrawn message is set in two places depending on context:
- When BlockReturnOfWithdrawnItems is ON: set in blocker handler before early return
- When BlockReturnOfWithdrawnItems is OFF: set by existing check later in the flow
This preserves the original behavior where withdrawn items always get the
message, but are only blocked when the syspref is enabled.

Test plan:
1. Apply patch
2. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Koha/Item/Checkin/Availability.t
=> SUCCESS: Tests pass!
  k$ prove t/db_dependent/Circul*
=> SUCCESS: Tests pass!
3. Verify check-in operations work correctly:
   - Items not found return BadBarcode
   - Withdrawn items blocked when syspref enabled
   - Lost items blocked when syspref enabled
   - Wrong branch returns blocked per AllowReturnToBranch
   - Not issued items handled correctly
   - Normal check-ins complete successfully
4. Sign off :-D
Comment 4 Tomás Cohen Arazi (tcohen) 2026-01-28 19:55:17 UTC
Created attachment 192133 [details] [review]
[POC] Bug 41728: Add Koha::Item::Checkout::Availability class

This is for illustration purposes only! Not intended to be tested or pushed.

This patch introduces a checkout availability class that wraps
C4::Circulation::CanBookBeIssued in a Result object interface,
providing a consistent API for availability checks.

The class:
- Wraps CanBookBeIssued and maps its return values to Result object
- Maps 'impossible' to blockers
- Maps 'confirmation' to confirmations
- Maps 'alerts' and 'messages' to warnings
- Provides $item->checkout_availability() convenience method

This enables the REST API and other code to use a consistent
availability checking interface across different operations
(checkout, check-in, renewal, etc.).

Test plan:
1. Apply patch
2. Run:
   $ ktd --shell
  k$ prove t/db_dependent/Koha/Item/Checkout/Availability.t
=> SUCCESS: Tests pass!
3. Verify checkout availability checks work:
   - Available items return no blockers
   - Debarred patrons get DEBARRED blocker
   - Context includes patron and item objects
4. Sign off :-D