Bug 40445 - Point of Sale reconciliation input during daily summaries
Summary: Point of Sale reconciliation input during daily summaries
Status: Needs Signoff
Alias: None
Product: Koha
Classification: Unclassified
Component: Point of Sale (show other bugs)
Version: unspecified
Hardware: All All
: P5 - low enhancement
Assignee: Martin Renvoize (ashimema)
QA Contact: Testopia
URL:
Keywords:
Depends on: 19871 40625 41229
Blocks: 41299
  Show dependency treegraph
 
Reported: 2025-07-18 10:00 UTC by Hannah Dunne-Howrie
Modified: 2026-01-02 09:41 UTC (History)
6 users (show)

See Also:
GIT URL:
Initiative type: ---
Sponsorship status: Sponsored
Comma delimited list of Sponsors: OpenFifth <https://openfifth.co.uk/>
Crowdfunding goal: 0
Patch complexity: Medium patch
Documentation contact:
Documentation submission:
Text to go in the release notes:
Version(s) released in:
Circulation function:


Attachments
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (3.99 KB, patch)
2025-08-08 17:29 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add unit tests for cashup reconciliation functionality (17.64 KB, patch)
2025-08-08 17:29 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality to point of sale (25.07 KB, patch)
2025-08-08 17:29 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Exclude reconciliation accountlines from outstanding_accountlines (1.91 KB, patch)
2025-08-08 17:29 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Quick demo of new functionality (1.30 MB, video/mp4)
2025-08-27 11:47 UTC, Martin Renvoize (ashimema)
Details
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (3.99 KB, patch)
2025-09-21 11:54 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add unit tests for cashup reconciliation functionality (17.64 KB, patch)
2025-09-21 11:54 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality to point of sale (25.07 KB, patch)
2025-09-21 11:54 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Exclude reconciliation accountlines from outstanding_accountlines (1.91 KB, patch)
2025-09-21 11:55 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow for point of sale (79.24 KB, patch)
2025-09-21 11:55 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add two-phase cashup options to registers page (15.89 KB, patch)
2025-09-21 11:55 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement unified "Cashup selected" functionality with checkbox selection (24.23 KB, patch)
2025-09-21 11:55 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Use centralized exception handling in Cash Register methods (4.28 KB, patch)
2025-09-21 11:55 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (3.99 KB, patch)
2025-11-07 14:43 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add unit tests for cashup reconciliation functionality (17.64 KB, patch)
2025-11-07 14:44 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality to point of sale (25.07 KB, patch)
2025-11-07 14:44 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Exclude reconciliation accountlines from outstanding_accountlines (1.91 KB, patch)
2025-11-07 14:44 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow for point of sale (79.24 KB, patch)
2025-11-07 14:44 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add two-phase cashup options to registers page (15.89 KB, patch)
2025-11-07 14:44 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement unified "Cashup selected" functionality with checkbox selection (24.23 KB, patch)
2025-11-07 14:44 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Use centralized exception handling in Cash Register methods (4.70 KB, patch)
2025-11-07 14:44 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Fix desk and register session persistence on library change (4.39 KB, patch)
2025-11-07 14:44 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (3.99 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add unit tests for cashup reconciliation functionality (17.64 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality to point of sale (25.07 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Exclude reconciliation accountlines from outstanding_accountlines (1.91 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow for point of sale (79.24 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add two-phase cashup options to registers page (15.89 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement unified "Cashup selected" functionality with checkbox selection (24.44 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Use centralized exception handling in Cash Register methods (4.33 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Fix desk and register session persistence on library change (4.39 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add detailed error handling for cashup completion failures (3.79 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Prevent starting cashup with zero cash transactions (5.28 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup summary preview for in-progress cashups (7.13 KB, patch)
2025-11-07 17:07 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (3.99 KB, patch)
2025-11-10 14:17 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality (42.03 KB, patch)
2025-11-10 14:17 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow (113.17 KB, patch)
2025-11-10 14:18 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Improve error handling and validation (9.63 KB, patch)
2025-11-10 14:18 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup summary preview for in-progress cashups (8.89 KB, patch)
2025-11-10 14:18 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup summary preview for in-progress cashups (8.85 KB, patch)
2025-11-10 14:33 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (4.04 KB, patch)
2025-11-10 15:57 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality (42.03 KB, patch)
2025-11-10 15:57 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow (121.12 KB, patch)
2025-11-10 15:57 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Improve error handling and validation (9.57 KB, patch)
2025-11-10 15:57 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup summary preview for in-progress cashups (8.85 KB, patch)
2025-11-10 15:57 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Demo (4.68 MB, video/mp4)
2025-11-10 16:26 UTC, Martin Renvoize (ashimema)
Details
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (4.04 KB, patch)
2025-11-10 17:04 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality (43.16 KB, patch)
2025-11-10 17:04 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow (121.12 KB, patch)
2025-11-10 17:04 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Improve error handling and validation (9.57 KB, patch)
2025-11-10 17:04 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup summary preview for in-progress cashups (8.97 KB, patch)
2025-11-10 17:04 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (4.04 KB, patch)
2025-11-11 07:39 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality (43.16 KB, patch)
2025-11-11 07:39 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow (121.12 KB, patch)
2025-11-11 07:39 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Improve error handling and validation (9.57 KB, patch)
2025-11-11 07:40 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup summary preview for in-progress cashups (8.97 KB, patch)
2025-11-11 07:40 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add optional required reconciliation note validation (14.80 KB, patch)
2025-11-11 07:40 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add authorized value support for reconciliation notes (10.57 KB, patch)
2025-11-11 07:40 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (4.04 KB, patch)
2025-12-09 16:22 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality (43.16 KB, patch)
2025-12-09 16:22 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow (121.12 KB, patch)
2025-12-09 16:22 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Improve error handling and validation (9.57 KB, patch)
2025-12-09 16:22 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup summary preview for in-progress cashups (8.97 KB, patch)
2025-12-09 16:22 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add optional required reconciliation note validation (14.80 KB, patch)
2025-12-09 16:22 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add authorized value support for reconciliation notes (10.57 KB, patch)
2025-12-09 16:22 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Disable cashup button and checkbox when bankable is zero (5.83 KB, patch)
2025-12-09 16:22 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (4.04 KB, patch)
2025-12-09 16:41 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality (43.16 KB, patch)
2025-12-09 16:41 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow (121.50 KB, patch)
2025-12-09 16:41 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Improve error handling and validation (9.57 KB, patch)
2025-12-09 16:41 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup summary preview for in-progress cashups (8.97 KB, patch)
2025-12-09 16:41 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add optional required reconciliation note validation (14.80 KB, patch)
2025-12-09 16:41 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add authorized value support for reconciliation notes (10.57 KB, patch)
2025-12-09 16:41 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Disable cashup button and checkbox when bankable is zero (5.83 KB, patch)
2025-12-09 16:41 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Support negative cashup amounts for float deficits (14.39 KB, patch)
2025-12-09 17:26 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Update unit tests for negative cashup amounts (2.71 KB, patch)
2025-12-09 17:26 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Support negative cashup amounts for float deficits (20.36 KB, patch)
2025-12-10 08:04 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Update unit tests for negative cashup amounts (2.71 KB, patch)
2025-12-10 08:04 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types (4.04 KB, patch)
2025-12-10 18:36 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup reconciliation functionality (43.21 KB, patch)
2025-12-10 18:36 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Implement two-phase cashup workflow (121.55 KB, patch)
2025-12-10 18:36 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Improve error handling and validation (9.62 KB, patch)
2025-12-10 18:36 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add cashup summary preview for in-progress cashups (9.02 KB, patch)
2025-12-10 18:36 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add optional required reconciliation note validation (14.85 KB, patch)
2025-12-10 18:36 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Add authorized value support for reconciliation notes (10.62 KB, patch)
2025-12-10 18:36 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Disable cashup button and checkbox when bankable is zero (5.88 KB, patch)
2025-12-10 18:36 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Support negative cashup amounts for float deficits (20.41 KB, patch)
2025-12-10 18:37 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Update unit tests for negative cashup amounts (2.76 KB, patch)
2025-12-10 18:37 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: Refactor cashup modals to eliminate duplication (59.16 KB, patch)
2025-12-10 18:37 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review
Bug 40445: (follow-up) Improve cashup summary display for negative amounts (4.53 KB, patch)
2025-12-10 18:37 UTC, Martin Renvoize (ashimema)
Details | Diff | Splinter Review

Note You need to log in before you can comment on or make changes to this bug.
Description Hannah Dunne-Howrie 2025-07-18 10:00:07 UTC
We use a separate spreadsheet for our daily reconciliation of income taken which uses the cash register summaries. It occurs to me that this process can be streamlined by allowing an input stage to the summaries process so staff interaction with summaries is not the cashing up to package the transactions into a summary (we want the daily summaries to happen automatically) we want the staff input to be to add in (against totals for payment type and cash register) the amount of what was actually taken using the z reports and physical cash, i.e. a reconciliation stage so it will be easy for staff to see if the money is 'out' and then a process to reconciliate with a way to add in a note for the summary they are signing off with an perhaps a way for them to then 'balance the books' to account for the discrepancy.

We would then need this staff input on the summaries (the physical amount taken and any notes) to be stored in a table, somewhere logical, so we can then report on this and create a way in which library managers can check in on this if needed and audit.
Comment 1 Martin Renvoize (ashimema) 2025-08-08 17:29:08 UTC Comment hidden (obsolete)
Comment 2 Martin Renvoize (ashimema) 2025-08-08 17:29:10 UTC Comment hidden (obsolete)
Comment 3 Martin Renvoize (ashimema) 2025-08-08 17:29:12 UTC Comment hidden (obsolete)
Comment 4 Martin Renvoize (ashimema) 2025-08-08 17:29:14 UTC Comment hidden (obsolete)
Comment 5 Martin Renvoize (ashimema) 2025-08-08 17:29:51 UTC
# Test plan

## Prerequisites

1. **System Requirements:**
    - `UseCashRegisters` system preference set to 'Use' to enable cash management
    - `EnablePointOfSale` set to enabled to expose 'Point of sale' functionality
    - Staff user with `cash_management` permissions (specifically 'cashup' permission)
    - At least one cash register configured for the current library

## Test Scenarios

### 1. Basic Cashup Modal Interface

**Objective:** Verify the enhanced cashup modal interface and user experience

**Steps:**

1. Navigate to Point of Sale → Register (select a specific register)
2. Perform some transactions to create outstanding amounts (e.g., process a payment)
3. Click "Record cashup" button
4. **Verify:** Cashup modal opens with the following elements:
    - Expected amount clearly displayed (should match outstanding transactions)
    - Float amount shown
    - "Actual amount removed from register" field is **empty** (not pre-populated)
    - Field is marked as required with proper validation
    - Reconciliation section is hidden initially
    - Note field is hidden initially
5. **Verify:** Cannot submit form with empty amount field
6. Close modal and repeat to ensure consistency

### 2. Real-time Reconciliation Calculation

**Objective:** Test the dynamic reconciliation calculation as user types

**Steps:**

1. Open cashup modal (as above)
2. Note the expected amount (e.g., £15.00)
3. **Test Case 2a - Balanced Amount:**
    - Enter the exact expected amount (e.g., 15.00)
    - **Verify:** Reconciliation text shows "Balanced - no surplus or deficit"
    - **Verify:** Text appears in green/success styling
    - **Verify:** Note field remains hidden (no discrepancy)
4. **Test Case 2b - Surplus Amount:**
    - Enter amount higher than expected (e.g., 18.50 when expecting 15.00)
    - **Verify:** Reconciliation text shows "Surplus: £3.50"
    - **Verify:** Text appears in green/success styling
    - **Verify:** Note field appears for explanation
5. **Test Case 2c - Deficit Amount:**
    - Enter amount lower than expected (e.g., 12.00 when expecting 15.00)
    - **Verify:** Reconciliation text shows "Deficit: £3.00"
    - **Verify:** Text appears in warning styling (orange/yellow)
    - **Verify:** Note field appears for explanation
6. **Test Case 2d - Invalid Input:**
    - Clear the field
    - **Verify:** Reconciliation section hides
    - **Verify:** Note field hides
    - Enter invalid values (letters, special characters)
    - **Verify:** No reconciliation calculation occurs

### 3. Balanced Cashup Processing

**Objective:** Test cashup when actual amount equals expected amount

**Steps:**

1. Create transactions totaling £10.00 (or known amount)
2. Open cashup modal
3. Enter exact expected amount (£10.00)
4. **Optional:** Add a note (should be ignored for balanced cashups)
5. Click "Confirm cashup"
6. **Verify:** Page redirects successfully (POST/REDIRECT/GET pattern)
7. **Verify:** Cashup appears in cashup history
8. **Database Verification:**

    ```sql
    -- Check cashup action created
    SELECT * FROM cash_register_actions WHERE code = 'CASHUP' ORDER BY timestamp DESC LIMIT 1;

    -- Check NO surplus/deficit accountlines created
    SELECT * FROM accountlines WHERE register_id = [REGISTER_ID]
    AND (credit_type_code = 'CASHUP_SURPLUS' OR debit_type_code = 'CASHUP_DEFICIT');
    ```

9. **Verify:** No surplus/deficit entries in account lines

### 4. Surplus Cashup Processing

**Objective:** Test cashup when actual amount exceeds expected amount

**Steps:**

1. Create transactions totaling £15.00
2. Open cashup modal
3. Enter higher amount (£20.00 = £5.00 surplus)
4. **Verify:** Shows "Surplus: £5.00" in reconciliation
5. **Optional:** Add explanatory note: "Found extra £5 note in drawer"
6. Click "Confirm cashup"
7. **Verify:** Successful redirect
8. **Database Verification:**

    ```sql
    -- Check cashup action
    SELECT amount FROM cash_register_actions WHERE code = 'CASHUP' ORDER BY timestamp DESC LIMIT 1;
    -- Should show 20.00

    -- Check surplus accountline
    SELECT amount, description, note FROM accountlines
    WHERE register_id = [REGISTER_ID] AND credit_type_code = 'CASHUP_SURPLUS'
    ORDER BY date DESC LIMIT 1;
    -- Amount should be -5.00 (negative for credit)
    -- Note should contain user's explanation
    ```

9. **Verify:** Surplus accountline created with correct negative amount
10. **Verify:** User note stored correctly (if provided)

### 5. Deficit Cashup Processing

**Objective:** Test cashup when actual amount is less than expected

**Steps:**

1. Create transactions totaling £25.00
2. Open cashup modal
3. Enter lower amount (£22.00 = £3.00 deficit)
4. **Verify:** Shows "Deficit: £3.00" with warning styling
5. Add explanatory note: "£3 missing - possible incorrect change given"
6. Click "Confirm cashup"
7. **Verify:** Successful redirect
8. **Database Verification:**

    ```sql
    -- Check deficit accountline
    SELECT amount, description, note FROM accountlines
    WHERE register_id = [REGISTER_ID] AND debit_type_code = 'CASHUP_DEFICIT'
    ORDER BY date DESC LIMIT 1;
    -- Amount should be 3.00 (positive for debit)
    -- Note should contain explanation
    ```

9. **Verify:** Deficit accountline created with correct positive amount
10. **Verify:** User note stored correctly

### 6. Note Field Validation

**Objective:** Test note field behavior and validation

**Steps:**

1. Create discrepancy situation (surplus or deficit)
2. **Test Case 6a - Valid Note:**
    - Enter meaningful note (under 1000 characters)
    - **Verify:** Note saves correctly with cashup
3. **Test Case 6b - Empty/Whitespace Note:**
    - Leave note field empty OR enter only spaces/tabs
    - Submit cashup
    - **Verify:** No note stored in database (should be NULL/undef)
4. **Test Case 6c - Long Note:**
    - Enter note approaching 1000 character limit
    - **Verify:** Submission works correctly
    - Enter note exceeding 1000 characters
    - **Verify:** Note is truncated to 1000 characters
5. **Test Case 6d - Special Characters:**
    - Enter note with quotes, apostrophes, newlines
    - **Verify:** Special characters handled properly

### 7. Cashup Summary Modal Enhancement

**Objective:** Test the enhanced cashup summary display

**Steps:**

1. Perform various cashups (balanced, surplus, deficit)
2. Navigate to cashup history or click "Summary" link for completed cashups
3. **Verify:** Summary modal displays:
    - All regular transactions grouped properly
    - Reconciliation information displayed separately in footer
    - Surplus/deficit amounts highlighted distinctly
    - Clean separation between regular transactions and reconciliation data
4. **Test different scenarios:**
    - Summary of balanced cashup (no reconciliation footer)
    - Summary of surplus cashup (highlighted surplus in footer)
    - Summary of deficit cashup (highlighted deficit in footer)

### 8. Outstanding Accountlines Filtering

**Objective:** Verify surplus/deficit entries don't affect subsequent cashups

**Steps:**

1. Perform cashup with surplus/deficit (creates reconciliation accountlines)
2. Add new regular transactions
3. **Verify:** Outstanding accountlines total excludes previous reconciliation entries
4. Perform another cashup
5. **Verify:** Expected amount calculation is correct (not inflated by reconciliation entries)

### 9. Transaction Integrity and Error Handling

**Objective:** Test system behavior under error conditions

**Steps:**

1. **Database Transaction Test:**
    - Monitor database during cashup process
    - **Verify:** All changes (cashup action + reconciliation accountline) are atomic
2. **Permission Test:**
    - Test with user lacking 'cashup' permission
    - **Verify:** Appropriate error message displayed
3. **Invalid Amount Test:**
    - Try submitting with invalid amounts (negative, non-numeric)
    - **Verify:** Client-side validation prevents submission
    - **Verify:** Server-side validation as backup
4. **Network Interruption:**
    - Submit cashup and simulate network issue
    - **Verify:** No partial/duplicate cashup records created

### 10. Multi-Register Environment

**Objective:** Test functionality with multiple cash registers

**Steps:**

1. Configure multiple cash registers for same library
2. Perform cashups on different registers
3. **Verify:** Reconciliation entries are correctly associated with specific registers
4. **Verify:** Outstanding amounts are calculated per register
5. Test "Cashup All" functionality if available
6. **Verify:** Individual register reconciliation works correctly

## Expected Results Summary

**After successful testing, the system should demonstrate:**

1. **User Experience:**

    - Intuitive modal interface requiring conscious amount entry
    - Real-time feedback on discrepancies
    - Conditional note fields appearing only when needed
    - Clear visual distinction between different reconciliation states

2. **Data Integrity:**

    - Accurate cashup amounts recorded
    - Proper creation of surplus/deficit accountlines when needed
    - Correct mathematical relationships (credits negative, debits positive)
    - User notes preserved exactly as entered (or NULL if empty)

3. **System Behavior:**

    - Atomic database transactions ensuring consistency
    - Proper filtering of reconciliation entries from outstanding calculations
    - Successful POST/REDIRECT/GET pattern preventing duplicate submissions
    - Enhanced summary displays showing reconciliation data appropriately

4. **Audit Trail:**
    - Complete timestamp records for all actions
    - Manager ID linkage for accountability
    - Detailed descriptions for reconciliation entries
    - Preserved user explanations for discrepancies

## Automated Test Verification

**Run the test suite:**

```bash
docker exec --user kohadev-koha --workdir /kohadevbox/koha -i kohadev-koha-1 bash -c 'prove t/db_dependent/Koha/Cash/Register.t'
```

**Expected:** All tests pass, covering balanced cashup, surplus handling, deficit handling, note management, and transaction integrity.

---

**Note:** This test plan assumes the CASHUP_SURPLUS and CASHUP_DEFICIT account types are properly installed via the mandatory data files or database updates. If these are missing, the functionality will not work correctly.
Comment 6 Martin Renvoize (ashimema) 2025-08-27 11:47:05 UTC Comment hidden (obsolete)
Comment 7 Martin Renvoize (ashimema) 2025-09-21 11:54:55 UTC Comment hidden (obsolete)
Comment 8 Martin Renvoize (ashimema) 2025-09-21 11:54:57 UTC Comment hidden (obsolete)
Comment 9 Martin Renvoize (ashimema) 2025-09-21 11:54:59 UTC Comment hidden (obsolete)
Comment 10 Martin Renvoize (ashimema) 2025-09-21 11:55:01 UTC Comment hidden (obsolete)
Comment 11 Martin Renvoize (ashimema) 2025-09-21 11:55:03 UTC Comment hidden (obsolete)
Comment 12 Martin Renvoize (ashimema) 2025-09-21 11:55:06 UTC Comment hidden (obsolete)
Comment 13 Martin Renvoize (ashimema) 2025-09-21 11:55:08 UTC Comment hidden (obsolete)
Comment 14 Martin Renvoize (ashimema) 2025-09-21 11:55:10 UTC Comment hidden (obsolete)
Comment 15 Martin Renvoize (ashimema) 2025-11-07 14:43:58 UTC Comment hidden (obsolete)
Comment 16 Martin Renvoize (ashimema) 2025-11-07 14:44:01 UTC Comment hidden (obsolete)
Comment 17 Martin Renvoize (ashimema) 2025-11-07 14:44:03 UTC Comment hidden (obsolete)
Comment 18 Martin Renvoize (ashimema) 2025-11-07 14:44:05 UTC Comment hidden (obsolete)
Comment 19 Martin Renvoize (ashimema) 2025-11-07 14:44:08 UTC Comment hidden (obsolete)
Comment 20 Martin Renvoize (ashimema) 2025-11-07 14:44:10 UTC Comment hidden (obsolete)
Comment 21 Martin Renvoize (ashimema) 2025-11-07 14:44:13 UTC Comment hidden (obsolete)
Comment 22 Martin Renvoize (ashimema) 2025-11-07 14:44:15 UTC Comment hidden (obsolete)
Comment 23 Martin Renvoize (ashimema) 2025-11-07 14:44:17 UTC Comment hidden (obsolete)
Comment 24 Martin Renvoize (ashimema) 2025-11-07 17:07:21 UTC Comment hidden (obsolete)
Comment 25 Martin Renvoize (ashimema) 2025-11-07 17:07:24 UTC Comment hidden (obsolete)
Comment 26 Martin Renvoize (ashimema) 2025-11-07 17:07:26 UTC Comment hidden (obsolete)
Comment 27 Martin Renvoize (ashimema) 2025-11-07 17:07:29 UTC Comment hidden (obsolete)
Comment 28 Martin Renvoize (ashimema) 2025-11-07 17:07:31 UTC Comment hidden (obsolete)
Comment 29 Martin Renvoize (ashimema) 2025-11-07 17:07:34 UTC Comment hidden (obsolete)
Comment 30 Martin Renvoize (ashimema) 2025-11-07 17:07:36 UTC Comment hidden (obsolete)
Comment 31 Martin Renvoize (ashimema) 2025-11-07 17:07:39 UTC Comment hidden (obsolete)
Comment 32 Martin Renvoize (ashimema) 2025-11-07 17:07:41 UTC Comment hidden (obsolete)
Comment 33 Martin Renvoize (ashimema) 2025-11-07 17:07:44 UTC Comment hidden (obsolete)
Comment 34 Martin Renvoize (ashimema) 2025-11-07 17:07:46 UTC Comment hidden (obsolete)
Comment 35 Martin Renvoize (ashimema) 2025-11-07 17:07:49 UTC Comment hidden (obsolete)
Comment 36 Martin Renvoize (ashimema) 2025-11-07 17:08:45 UTC
Some nice polishing going on here given feedback and testing.. I'll post a new demo video next week.
Comment 37 Martin Renvoize (ashimema) 2025-11-10 14:17:55 UTC
Created attachment 189410 [details] [review]
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types

This patch adds two new system account types to support cashup reconciliation:

- CASHUP_SURPLUS (credit type): Used when actual cash found exceeds expected amount
- CASHUP_DEFICIT (debit type): Used when actual cash found is less than expected amount

Both types are system-managed and cannot be manually added by staff. They will be
automatically created during cashup processes when discrepancies are detected.

Changes include:
- Atomicupdate script for existing installations
- Mandatory YAML files for fresh installations
Comment 38 Martin Renvoize (ashimema) 2025-11-10 14:17:58 UTC
Created attachment 189411 [details] [review]
Bug 40445: Add cashup reconciliation functionality

Implements cashup reconciliation allowing staff to record actual cash
amounts and track surplus/deficit discrepancies.

Backend changes:
- Enhanced add_cashup() to accept actual_amount and optional notes
- Automatic CASHUP_SURPLUS/DEFICIT accountline creation for discrepancies
- Transaction handling ensures atomicity of cashup and reconciliation
- outstanding_accountlines() excludes reconciliation entries

Frontend changes:
- Interactive modal requiring actual amount entry
- Real-time surplus/deficit calculation
- Conditional note field for discrepancies (1000 char limit)
- Enhanced summary modal displays reconciliation details
- Full audit trail with timestamps and manager links

Test plan:
1. Apply all patches and restart services
2. Run prove t/db_dependent/Koha/Cash/Register.t
3. Create test transactions on a register
4. Perform cashup with balanced amount - verify no reconciliation accountlines
5. Perform cashup with surplus - verify CASHUP_SURPLUS credit created
6. Perform cashup with deficit - verify CASHUP_DEFICIT debit created
7. Add notes to reconciliation - verify stored correctly
8. Start new cashup - verify previous reconciliation excluded from outstanding
9. View cashup summary - verify reconciliation displayed prominently
Comment 39 Martin Renvoize (ashimema) 2025-11-10 14:18:00 UTC
Created attachment 189412 [details] [review]
Bug 40445: Implement two-phase cashup workflow

Introduces two-phase cashup system allowing staff to start a cashup
session, remove cash for counting, and complete later with reconciliation.

Key features:
- start_cashup(): Creates CASHUP_START action for counting session
- cashup_in_progress(): Checks if session is active
- Enhanced add_cashup(): Supports both legacy and two-phase modes
- Improved session boundary calculation handles mixed workflows
- Reconciliation lines backdated appropriately per mode

Single register interface:
- Dynamic toolbar shows "Start cashup" vs "Complete cashup"
- Status indicator when cashup in progress
- Dual-workflow modal with quick and two-phase options

Registers page enhancements:
- Checkbox selection for multiple registers
- "Select all" functionality with indeterminate state
- "Cashup selected" button with workflow modal
- Both workflows support single or multiple registers
- Comprehensive error handling for bulk operations

Test plan:
1. Apply patch and run prove t/db_dependent/Koha/Cash/Register.t
2. Single register two-phase:
   - Start cashup on register
   - Verify status indicator appears
   - Add more transactions
   - Complete cashup with actual amount
   - Verify session boundaries correct
3. Single register quick cashup:
   - Use "Quick cashup" option
   - Verify immediate completion
4. Registers page multiple selection:
   - Select multiple registers with checkboxes
   - Click "Cashup selected"
   - Choose "Start cashup" - verify all start successfully
   - Complete each individually
5. Registers page quick cashup:
   - Select multiple registers
   - Choose "Quick cashup" with reconciliation amounts
   - Verify all complete immediately
6. Mixed workflows:
   - Use both quick and two-phase on same register over time
   - Verify session boundaries calculate correctly
Comment 40 Martin Renvoize (ashimema) 2025-11-10 14:18:03 UTC
Created attachment 189413 [details] [review]
Bug 40445: Improve error handling and validation

Enhances cashup error handling and prevents invalid operations.

Changes:
- Centralized exception handling in Cash Register methods
- Detailed error messages for specific exception types:
  * MissingParameter: Shows parameter name
  * AmountNotPositive: Clarifies positive amount requirement
  * Unhandled: Displays debug information
- Validation prevents starting cashup with zero transactions
- Proper Koha::Exceptions thrown instead of raw DBIx::Class errors

Test plan:
1. Apply patch and run prove t/db_dependent/Koha/Cash/Register.t
2. Attempt to start cashup with no transactions:
   - Verify informational error: "Cannot start cashup - no cash transactions"
3. Attempt cashup operations triggering various exceptions:
   - Missing parameter: Verify parameter name shown
   - Zero/negative amount: Verify clear validation message
4. Add cash transaction and retry:
   - Verify cashup starts successfully
5. Test multi-register operations:
   - Verify appropriate errors for registers with no transactions
   - Verify other registers process successfully
Comment 41 Martin Renvoize (ashimema) 2025-11-10 14:18:05 UTC
Created attachment 189414 [details] [review]
Bug 40445: Add cashup summary preview for in-progress cashups

In two-phase workflow, staff start cashup then count cash while
continuing transactions. This adds preview capability to see what
will be included before completion.

Features:
- "Preview cashup summary" link in cashup progress alert
- Modal shows expected amounts with "(preview)" indicator
- Alert explains this is preview and reconciliation may be added
- API endpoint supports preview by accepting CASHUP_START action IDs
- All strings properly wrapped for translation

Test plan:
1. Start two-phase cashup on register
2. Verify "Cashup in progress" alert appears
3. Click "Preview cashup summary" link
4. Verify modal shows:
   - Title: "Cashup summary preview"
   - Info alert explaining preview status
   - Correct period dates
   - Current transaction totals
5. Add new cash transaction
6. Re-open preview - verify totals updated
7. Complete cashup normally
8. View completed cashup summary
9. Verify no preview notice, normal title shown
10. Check translations: Verify all strings wrapped with __() or t()/tx()
Comment 42 Martin Renvoize (ashimema) 2025-11-10 14:33:34 UTC Comment hidden (obsolete)
Comment 43 Martin Renvoize (ashimema) 2025-11-10 15:57:07 UTC Comment hidden (obsolete)
Comment 44 Martin Renvoize (ashimema) 2025-11-10 15:57:10 UTC Comment hidden (obsolete)
Comment 45 Martin Renvoize (ashimema) 2025-11-10 15:57:13 UTC Comment hidden (obsolete)
Comment 46 Martin Renvoize (ashimema) 2025-11-10 15:57:15 UTC Comment hidden (obsolete)
Comment 47 Martin Renvoize (ashimema) 2025-11-10 15:57:18 UTC Comment hidden (obsolete)
Comment 48 Martin Renvoize (ashimema) 2025-11-10 16:26:08 UTC Comment hidden (obsolete)
Comment 49 Martin Renvoize (ashimema) 2025-11-10 17:04:11 UTC Comment hidden (obsolete)
Comment 50 Martin Renvoize (ashimema) 2025-11-10 17:04:14 UTC Comment hidden (obsolete)
Comment 51 Martin Renvoize (ashimema) 2025-11-10 17:04:16 UTC Comment hidden (obsolete)
Comment 52 Martin Renvoize (ashimema) 2025-11-10 17:04:19 UTC Comment hidden (obsolete)
Comment 53 Martin Renvoize (ashimema) 2025-11-10 17:04:22 UTC Comment hidden (obsolete)
Comment 54 Martin Renvoize (ashimema) 2025-11-11 07:39:53 UTC Comment hidden (obsolete)
Comment 55 Martin Renvoize (ashimema) 2025-11-11 07:39:56 UTC Comment hidden (obsolete)
Comment 56 Martin Renvoize (ashimema) 2025-11-11 07:39:59 UTC Comment hidden (obsolete)
Comment 57 Martin Renvoize (ashimema) 2025-11-11 07:40:01 UTC Comment hidden (obsolete)
Comment 58 Martin Renvoize (ashimema) 2025-11-11 07:40:04 UTC Comment hidden (obsolete)
Comment 59 Martin Renvoize (ashimema) 2025-11-11 07:40:07 UTC
Created attachment 189481 [details] [review]
Bug 40445: Add optional required reconciliation note validation

This patch adds the ability to require reconciliation notes when
completing cashup with discrepancies between expected and actual amounts.

A new system preference `CashupReconciliationNoteRequired`` controls
whether notes are mandatory when surplus or deficit exists.

Test plan:
1. Enable CashupReconciliationNoteRequired system preference
2. Perform cashup with discrepancy without note - should fail
3. Perform cashup with discrepancy with note - should succeed
4. Perform cashup without discrepancy and no note - should succeed
5. Disable preference - cashup with discrepancy should work without note
6. Run tests: prove t/db_dependent/Koha/Cash/Register.t
Comment 60 Martin Renvoize (ashimema) 2025-11-11 07:40:09 UTC
Created attachment 189482 [details] [review]
Bug 40445: Add authorized value support for reconciliation notes

This patch adds the ability to restrict reconciliation notes to a
predefined list of authorized values for standardization and consistency.

A new system preference `CashupReconciliationNoteAuthorisedValue` allows
administrators to specify an authorized value category for the note
dropdown. If not configured, a free text textarea is used instead.

Test plan:
1. Create authorized value category (e.g., CASHUP_NOTE) with values
   like "Till count error", "Cash removed", "Foreign currency", etc.
2. Set CashupReconciliationNoteAuthorisedValue to CASHUP_NOTE
3. Perform cashup - note field should be dropdown with AV options
4. Clear preference - note field should revert to textarea
5. Verify notes are saved correctly in both modes
Comment 61 Martin Renvoize (ashimema) 2025-12-09 16:22:38 UTC
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 62 Martin Renvoize (ashimema) 2025-12-09 16:22:49 UTC Comment hidden (obsolete)
Comment 63 Martin Renvoize (ashimema) 2025-12-09 16:22:50 UTC Comment hidden (obsolete)
Comment 64 Martin Renvoize (ashimema) 2025-12-09 16:22:51 UTC Comment hidden (obsolete)
Comment 65 Martin Renvoize (ashimema) 2025-12-09 16:22:53 UTC Comment hidden (obsolete)
Comment 66 Martin Renvoize (ashimema) 2025-12-09 16:22:54 UTC Comment hidden (obsolete)
Comment 67 Martin Renvoize (ashimema) 2025-12-09 16:22:56 UTC Comment hidden (obsolete)
Comment 68 Martin Renvoize (ashimema) 2025-12-09 16:22:57 UTC Comment hidden (obsolete)
Comment 69 Martin Renvoize (ashimema) 2025-12-09 16:22:58 UTC
Created attachment 190368 [details] [review]
Bug 40445: (follow-up) Disable cashup button and checkbox when bankable is zero

When a register has no bankable transactions (bankable amount is 0.00),
the 'Record cashup' button and the corresponding checkbox should be
disabled to prevent attempting a cashup that will result in an error.

This patch:
- Disables the checkbox for registers with 0.00 bankable amount
- Disables the 'Record cashup' button when bankable is 0.00
- Adds tooltip "No bankable transactions" to both elements
- Applies to both the registers summary page and individual register page

Test plan:
1. Navigate to /cgi-bin/koha/pos/registers.pl
2. Find or create a register with no bankable transactions (0.00)
3. Verify the checkbox for that register is disabled with tooltip
4. Verify the 'Record cashup' button is disabled with tooltip
5. Navigate to the individual register page
6. Verify the toolbar 'Record cashup' button is disabled when bankable is 0.00
7. Verify registers with non-zero bankable amounts work as before
Comment 70 Martin Renvoize (ashimema) 2025-12-09 16:41:13 UTC Comment hidden (obsolete)
Comment 71 Martin Renvoize (ashimema) 2025-12-09 16:41:15 UTC Comment hidden (obsolete)
Comment 72 Martin Renvoize (ashimema) 2025-12-09 16:41:16 UTC Comment hidden (obsolete)
Comment 73 Martin Renvoize (ashimema) 2025-12-09 16:41:17 UTC Comment hidden (obsolete)
Comment 74 Martin Renvoize (ashimema) 2025-12-09 16:41:19 UTC Comment hidden (obsolete)
Comment 75 Martin Renvoize (ashimema) 2025-12-09 16:41:20 UTC Comment hidden (obsolete)
Comment 76 Martin Renvoize (ashimema) 2025-12-09 16:41:22 UTC Comment hidden (obsolete)
Comment 77 Martin Renvoize (ashimema) 2025-12-09 16:41:23 UTC Comment hidden (obsolete)
Comment 78 Martin Renvoize (ashimema) 2025-12-09 17:26:49 UTC
Created attachment 190379 [details] [review]
Bug 40445: (follow-up) Support negative cashup amounts for float deficits

When cash refunds exceed takings in a session, the register's float
is depleted, resulting in negative bankable amounts. This patch adds
full support for this scenario.

Backend changes:
- Removed abs() from start_cashup to preserve sign of amounts
- Updated validation to allow negative amounts (while preventing zero)
- Changed expected_amount calculation to: total * -1 (consistent)

Frontend changes (registers.tt):
- Dynamic modal messages based on amount sign
- Positive: "Remove £X cash from register to bank"
- Negative: "Top up the register with £X to restore the float"
- Updated input pattern to accept negative numbers: ^-?\d+(\.\d{2})?$
- Labels change based on context (add vs. remove)

Frontend changes (register.tt):
- Added Template Toolkit conditionals for negative amounts
- Updated input pattern to allow negative numbers
- Consistent labeling with registers page

All user-facing strings use _() for proper translation support.

Test plan for librarians:

Setup - Create negative cashup scenario:
1. Start with a register at its float amount (e.g., £100)
2. Process a large cash refund that exceeds takings
   Example: £80 in takings, £150 cash refund = -£70 bankable

Test "Record cashup" modal (Quick cashup):
3. Go to registers page (pos/registers.pl)
4. Click "Record cashup" for the register with negative balance
5. Verify the modal shows:
   - Quick cashup: "Top up the register with £70.00 to restore the float"
   - Float reminder: "This will bring the register back to the expected float of £100.00"
6. Click "Quick cashup"
7. Enter -70.00 in the amount field (negative number)
8. Verify cashup completes successfully

Test "Start cashup" modal (Two-phase):
9. Create another negative balance scenario
10. Click "Record cashup"
11. Verify Start cashup instructions show:
    - "Count cash in the register"
    - "The register can continue operating during counting"
    - "Complete the cashup by adding cash to restore the float"
12. Click "Start cashup"
13. Click "Complete cashup" for the register
14. Verify modal shows:
    - "Expected amount to add: £70.00"
    - Label: "Actual amount added to register:"
15. Enter -70.00 (the negative amount you're adding)
16. Verify cashup completes successfully

Test reconciliation with negative amounts:
17. Start cashup on register with -£70.00 expected
18. Complete cashup with -£68.00 actual (£2 less added than expected)
19. Verify reconciliation shows correct deficit/surplus calculation
20. Add a reconciliation note and complete

Test positive amounts still work (regression):
21. Create a normal positive cashup scenario
22. Verify all original messages appear correctly
23. Complete cashup with positive amount
24. Verify everything works as before

Test individual register page consistency:
25. Navigate to individual register page (pos/register.pl)
26. Verify negative amount handling matches registers page
27. Test both modals show consistent messaging

Expected results:
- Negative amounts are accepted in all cashup workflows
- Messages clearly indicate adding money vs. removing money
- Reconciliation calculations work correctly for negative amounts
- All translations display properly
- Positive amount workflows unchanged
Comment 79 Martin Renvoize (ashimema) 2025-12-09 17:26:50 UTC
Created attachment 190380 [details] [review]
Bug 40445: (follow-up) Update unit tests for negative cashup amounts

Updated tests to reflect that negative amounts are now valid:

1. start_cashup_parameter_validation - Changed expected amount test
   from >= 0 to != 0, since amounts can now be negative

2. add_cashup - Updated invalid_amount subtest:
   - Removed test expecting negative amounts to throw exception
   - Added test confirming negative amounts are now accepted
   - Verifies negative amount is stored correctly
   - Kept tests for zero, non-numeric, and empty amounts

All other tests remain unchanged as they don't specifically test
for positive-only validation.

To test:
prove t/db_dependent/Koha/Cash/Register.t
Comment 80 Martin Renvoize (ashimema) 2025-12-10 08:04:00 UTC
Created attachment 190388 [details] [review]
Bug 40445: (follow-up) Support negative cashup amounts for float deficits

When cash refunds exceed takings in a session, the register's float
is depleted, resulting in negative bankable amounts. This patch adds
full support for this scenario.

Backend changes:
- Removed abs() from start_cashup to preserve sign of amounts
- Updated validation to allow negative amounts (while preventing zero)
- Changed expected_amount calculation to: total * -1 (consistent)

Frontend changes (registers.tt):
- Dynamic modal messages based on amount sign
- Positive: "Remove £X cash from register to bank"
- Negative: "Top up the register with £X to restore the float"
- Updated input pattern to accept negative numbers: ^-?\d+(\.\d{2})?$
- Labels change based on context (add vs. remove)

Frontend changes (register.tt):
- Added Template Toolkit conditionals for negative amounts
- Updated input pattern to allow negative numbers
- Consistent labeling with registers page

All user-facing strings use _() for proper translation support.

Test plan for librarians:

Setup - Create negative cashup scenario:
1. Start with a register at its float amount (e.g., £100)
2. Process a large cash refund that exceeds takings
   Example: £80 in takings, £150 cash refund = -£70 bankable

Test "Record cashup" modal (Quick cashup):
3. Go to registers page (pos/registers.pl)
4. Click "Record cashup" for the register with negative balance
5. Verify the modal shows:
   - Quick cashup: "Top up the register with £70.00 to restore the float"
   - Float reminder: "This will bring the register back to the expected float of £100.00"
6. Click "Quick cashup"
7. Enter -70.00 in the amount field (negative number)
8. Verify cashup completes successfully

Test "Start cashup" modal (Two-phase):
9. Create another negative balance scenario
10. Click "Record cashup"
11. Verify Start cashup instructions show:
    - "Count cash in the register"
    - "The register can continue operating during counting"
    - "Complete the cashup by adding cash to restore the float"
12. Click "Start cashup"
13. Click "Complete cashup" for the register
14. Verify modal shows:
    - "Expected amount to add: £70.00"
    - Label: "Actual amount added to register:"
15. Enter -70.00 (the negative amount you're adding)
16. Verify cashup completes successfully

Test reconciliation with negative amounts:
17. Start cashup on register with -£70.00 expected
18. Complete cashup with -£68.00 actual (£2 less added than expected)
19. Verify reconciliation shows correct deficit/surplus calculation
20. Add a reconciliation note and complete

Test positive amounts still work (regression):
21. Create a normal positive cashup scenario
22. Verify all original messages appear correctly
23. Complete cashup with positive amount
24. Verify everything works as before

Test individual register page consistency:
25. Navigate to individual register page (pos/register.pl)
26. Verify negative amount handling matches registers page
27. Test both modals show consistent messaging

Expected results:
- Negative amounts are accepted in all cashup workflows
- Messages clearly indicate adding money vs. removing money
- Reconciliation calculations work correctly for negative amounts
- All translations display properly
- Positive amount workflows unchanged
Comment 81 Martin Renvoize (ashimema) 2025-12-10 08:04:01 UTC
Created attachment 190389 [details] [review]
Bug 40445: (follow-up) Update unit tests for negative cashup amounts

Updated tests to reflect that negative amounts are now valid:

1. start_cashup_parameter_validation - Changed expected amount test
   from >= 0 to != 0, since amounts can now be negative

2. add_cashup - Updated invalid_amount subtest:
   - Removed test expecting negative amounts to throw exception
   - Added test confirming negative amounts are now accepted
   - Verifies negative amount is stored correctly
   - Kept tests for zero, non-numeric, and empty amounts

All other tests remain unchanged as they don't specifically test
for positive-only validation.

To test:
prove t/db_dependent/Koha/Cash/Register.t
Comment 82 Martin Renvoize (ashimema) 2025-12-10 18:36:50 UTC
Created attachment 190404 [details] [review]
Bug 40445: Add CASHUP_SURPLUS and CASHUP_DEFICIT account types

This patch adds two new system account types to support cashup reconciliation:

- CASHUP_SURPLUS (credit type): Used when actual cash found exceeds expected amount
- CASHUP_DEFICIT (debit type): Used when actual cash found is less than expected amount

Both types are system-managed and cannot be manually added by staff. They will be
automatically created during cashup processes when discrepancies are detected.

Changes include:
- Atomicupdate script for existing installations
- Mandatory YAML files for fresh installations

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 83 Martin Renvoize (ashimema) 2025-12-10 18:36:51 UTC
Created attachment 190405 [details] [review]
Bug 40445: Add cashup reconciliation functionality

Implements cashup reconciliation allowing staff to record actual cash
amounts and track surplus/deficit discrepancies.

Backend changes:
- Enhanced add_cashup() to accept actual_amount and optional notes
- Automatic CASHUP_SURPLUS/DEFICIT accountline creation for discrepancies
- Transaction handling ensures atomicity of cashup and reconciliation
- outstanding_accountlines() excludes reconciliation entries

Frontend changes:
- Interactive modal requiring actual amount entry
- Real-time surplus/deficit calculation
- Conditional note field for discrepancies (1000 char limit)
- Enhanced summary modal displays reconciliation details
- Full audit trail with timestamps and manager links

Test plan:
1. Apply all patches and restart services
2. Run prove t/db_dependent/Koha/Cash/Register.t
3. Create test transactions on a register
4. Perform cashup with balanced amount - verify no reconciliation accountlines
5. Perform cashup with surplus - verify CASHUP_SURPLUS credit created
6. Perform cashup with deficit - verify CASHUP_DEFICIT debit created
7. Add notes to reconciliation - verify stored correctly
8. Start new cashup - verify previous reconciliation excluded from outstanding
9. View cashup summary - verify reconciliation displayed prominently

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 84 Martin Renvoize (ashimema) 2025-12-10 18:36:53 UTC
Created attachment 190406 [details] [review]
Bug 40445: Implement two-phase cashup workflow

Introduces two-phase cashup system allowing staff to start a cashup
session, remove cash for counting, and complete later with reconciliation.

Key features:
- start_cashup(): Creates CASHUP_START action for counting session
- cashup_in_progress(): Checks if session is active
- Enhanced add_cashup(): Supports both legacy and two-phase modes
- Improved session boundary calculation handles mixed workflows
- Reconciliation lines backdated appropriately per mode

Single register interface:
- Dynamic toolbar shows "Start cashup" vs "Complete cashup"
- Status indicator when cashup in progress
- Dual-workflow modal with quick and two-phase options

Registers page enhancements:
- Checkbox selection for multiple registers
- "Select all" functionality with indeterminate state
- "Cashup selected" button with workflow modal
- Both workflows support single or multiple registers
- Comprehensive error handling for bulk operations

Test plan:
1. Apply patch and run prove t/db_dependent/Koha/Cash/Register.t
2. Single register two-phase:
   - Start cashup on register
   - Verify status indicator appears
   - Add more transactions
   - Complete cashup with actual amount
   - Verify session boundaries correct
3. Single register quick cashup:
   - Use "Quick cashup" option
   - Verify immediate completion
4. Registers page multiple selection:
   - Select multiple registers with checkboxes
   - Click "Cashup selected"
   - Choose "Start cashup" - verify all start successfully
   - Complete each individually
5. Registers page quick cashup:
   - Select multiple registers
   - Choose "Quick cashup" with reconciliation amounts
   - Verify all complete immediately
6. Mixed workflows:
   - Use both quick and two-phase on same register over time
   - Verify session boundaries calculate correctly

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 85 Martin Renvoize (ashimema) 2025-12-10 18:36:54 UTC
Created attachment 190407 [details] [review]
Bug 40445: Improve error handling and validation

Enhances cashup error handling and prevents invalid operations.

Changes:
- Centralized exception handling in Cash Register methods
- Detailed error messages for specific exception types:
  * MissingParameter: Shows parameter name
  * AmountNotPositive: Clarifies positive amount requirement
  * Unhandled: Displays debug information
- Validation prevents starting cashup with zero transactions
- Proper Koha::Exceptions thrown instead of raw DBIx::Class errors

Test plan:
1. Apply patch and run prove t/db_dependent/Koha/Cash/Register.t
2. Attempt to start cashup with no transactions:
   - Verify informational error: "Cannot start cashup - no cash transactions"
3. Attempt cashup operations triggering various exceptions:
   - Missing parameter: Verify parameter name shown
   - Zero/negative amount: Verify clear validation message
4. Add cash transaction and retry:
   - Verify cashup starts successfully
5. Test multi-register operations:
   - Verify appropriate errors for registers with no transactions
   - Verify other registers process successfully

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 86 Martin Renvoize (ashimema) 2025-12-10 18:36:55 UTC
Created attachment 190408 [details] [review]
Bug 40445: Add cashup summary preview for in-progress cashups

In two-phase workflow, staff start cashup then count cash while
continuing transactions. This adds preview capability to see what
will be included before completion.

Features:
- "Preview cashup summary" link in cashup progress alert
- Modal shows expected amounts with "(preview)" indicator
- Alert explains this is preview and reconciliation may be added
- API endpoint supports preview by accepting CASHUP_START action IDs
- All strings properly wrapped for translation

Test plan:
1. Start two-phase cashup on register
2. Verify "Cashup in progress" alert appears
3. Click "Preview cashup summary" link
4. Verify modal shows:
   - Title: "Cashup summary preview"
   - Info alert explaining preview status
   - Correct period dates
   - Current transaction totals
5. Add new cash transaction
6. Re-open preview - verify totals updated
7. Complete cashup normally
8. View completed cashup summary
9. Verify no preview notice, normal title shown
10. Check translations: Verify all strings wrapped with __() or t()/tx()

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 87 Martin Renvoize (ashimema) 2025-12-10 18:36:57 UTC
Created attachment 190409 [details] [review]
Bug 40445: Add optional required reconciliation note validation

This patch adds the ability to require reconciliation notes when
completing cashup with discrepancies between expected and actual amounts.

A new system preference `CashupReconciliationNoteRequired`` controls
whether notes are mandatory when surplus or deficit exists.

Test plan:
1. Enable CashupReconciliationNoteRequired system preference
2. Perform cashup with discrepancy without note - should fail
3. Perform cashup with discrepancy with note - should succeed
4. Perform cashup without discrepancy and no note - should succeed
5. Disable preference - cashup with discrepancy should work without note
6. Run tests: prove t/db_dependent/Koha/Cash/Register.t

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 88 Martin Renvoize (ashimema) 2025-12-10 18:36:58 UTC
Created attachment 190410 [details] [review]
Bug 40445: Add authorized value support for reconciliation notes

This patch adds the ability to restrict reconciliation notes to a
predefined list of authorized values for standardization and consistency.

A new system preference `CashupReconciliationNoteAuthorisedValue` allows
administrators to specify an authorized value category for the note
dropdown. If not configured, a free text textarea is used instead.

Test plan:
1. Create authorized value category (e.g., CASHUP_NOTE) with values
   like "Till count error", "Cash removed", "Foreign currency", etc.
2. Set CashupReconciliationNoteAuthorisedValue to CASHUP_NOTE
3. Perform cashup - note field should be dropdown with AV options
4. Clear preference - note field should revert to textarea
5. Verify notes are saved correctly in both modes

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 89 Martin Renvoize (ashimema) 2025-12-10 18:36:59 UTC
Created attachment 190411 [details] [review]
Bug 40445: (follow-up) Disable cashup button and checkbox when bankable is zero

When a register has no bankable transactions (bankable amount is 0.00),
the 'Record cashup' button and the corresponding checkbox should be
disabled to prevent attempting a cashup that will result in an error.

This patch:
- Disables the checkbox for registers with 0.00 bankable amount
- Disables the 'Record cashup' button when bankable is 0.00
- Adds tooltip "No bankable transactions" to both elements
- Applies to both the registers summary page and individual register page

Test plan:
1. Navigate to /cgi-bin/koha/pos/registers.pl
2. Find or create a register with no bankable transactions (0.00)
3. Verify the checkbox for that register is disabled with tooltip
4. Verify the 'Record cashup' button is disabled with tooltip
5. Navigate to the individual register page
6. Verify the toolbar 'Record cashup' button is disabled when bankable is 0.00
7. Verify registers with non-zero bankable amounts work as before

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 90 Martin Renvoize (ashimema) 2025-12-10 18:37:01 UTC
Created attachment 190412 [details] [review]
Bug 40445: (follow-up) Support negative cashup amounts for float deficits

When cash refunds exceed takings in a session, the register's float
is depleted, resulting in negative bankable amounts. This patch adds
full support for this scenario.

Backend changes:
- Removed abs() from start_cashup to preserve sign of amounts
- Updated validation to allow negative amounts (while preventing zero)
- Changed expected_amount calculation to: total * -1 (consistent)

Frontend changes (registers.tt):
- Dynamic modal messages based on amount sign
- Positive: "Remove £X cash from register to bank"
- Negative: "Top up the register with £X to restore the float"
- Updated input pattern to accept negative numbers: ^-?\d+(\.\d{2})?$
- Labels change based on context (add vs. remove)

Frontend changes (register.tt):
- Added Template Toolkit conditionals for negative amounts
- Updated input pattern to allow negative numbers
- Consistent labeling with registers page

All user-facing strings use _() for proper translation support.

Test plan for librarians:

Setup - Create negative cashup scenario:
1. Start with a register at its float amount (e.g., £100)
2. Process a large cash refund that exceeds takings
   Example: £80 in takings, £150 cash refund = -£70 bankable

Test "Record cashup" modal (Quick cashup):
3. Go to registers page (pos/registers.pl)
4. Click "Record cashup" for the register with negative balance
5. Verify the modal shows:
   - Quick cashup: "Top up the register with £70.00 to restore the float"
   - Float reminder: "This will bring the register back to the expected float of £100.00"
6. Click "Quick cashup"
7. Enter -70.00 in the amount field (negative number)
8. Verify cashup completes successfully

Test "Start cashup" modal (Two-phase):
9. Create another negative balance scenario
10. Click "Record cashup"
11. Verify Start cashup instructions show:
    - "Count cash in the register"
    - "The register can continue operating during counting"
    - "Complete the cashup by adding cash to restore the float"
12. Click "Start cashup"
13. Click "Complete cashup" for the register
14. Verify modal shows:
    - "Expected amount to add: £70.00"
    - Label: "Actual amount added to register:"
15. Enter -70.00 (the negative amount you're adding)
16. Verify cashup completes successfully

Test reconciliation with negative amounts:
17. Start cashup on register with -£70.00 expected
18. Complete cashup with -£68.00 actual (£2 less added than expected)
19. Verify reconciliation shows correct deficit/surplus calculation
20. Add a reconciliation note and complete

Test positive amounts still work (regression):
21. Create a normal positive cashup scenario
22. Verify all original messages appear correctly
23. Complete cashup with positive amount
24. Verify everything works as before

Test individual register page consistency:
25. Navigate to individual register page (pos/register.pl)
26. Verify negative amount handling matches registers page
27. Test both modals show consistent messaging

Expected results:
- Negative amounts are accepted in all cashup workflows
- Messages clearly indicate adding money vs. removing money
- Reconciliation calculations work correctly for negative amounts
- All translations display properly
- Positive amount workflows unchanged

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 91 Martin Renvoize (ashimema) 2025-12-10 18:37:02 UTC
Created attachment 190413 [details] [review]
Bug 40445: (follow-up) Update unit tests for negative cashup amounts

Updated tests to reflect that negative amounts are now valid:

1. start_cashup_parameter_validation - Changed expected amount test
   from >= 0 to != 0, since amounts can now be negative

2. add_cashup - Updated invalid_amount subtest:
   - Removed test expecting negative amounts to throw exception
   - Added test confirming negative amounts are now accepted
   - Verifies negative amount is stored correctly
   - Kept tests for zero, non-numeric, and empty amounts

All other tests remain unchanged as they don't specifically test
for positive-only validation.

To test:
prove t/db_dependent/Koha/Cash/Register.t

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 92 Martin Renvoize (ashimema) 2025-12-10 18:37:03 UTC
Created attachment 190414 [details] [review]
Bug 40445: Refactor cashup modals to eliminate duplication

This patch refactors the cashup modal implementation across register.tt
and registers.tt pages to eliminate significant code duplication by
following Koha's conventions for shared modal templates and JavaScript.

Changes:

1. Created shared modal templates:
   - includes/modals/trigger_cashup.inc: Shared trigger cashup modal
   - includes/modals/confirm_cashup.inc: Shared confirm cashup modal
     with reconciliation support

2. Created shared JavaScript module:
   - js/modals/cashup_modals.js: Initialization functions for both
     modals with configuration-driven behavior

3. Updated backend scripts:
   - pos/register.pl: Added redirect_to parameter support for flexible
     redirects, fixed regex to accept negative cashup amounts
   - pos/registers.pl: Added authorized value and system preference
     parameters for consistent functionality

4. Updated template files:
   - pos/register.tt: Replaced inline modals and JavaScript with shared
     includes (~165 lines removed)
   - pos/registers.tt: Replaced inline modals and JavaScript with
     shared includes (~150 lines removed)

Benefits:
- Eliminates ~355 lines of duplicated code
- Single source of truth for cashup modal logic
- Consistent functionality across both pages
- Flexible redirect behavior (stay on registers page or go to
  individual register page)
- Proper support for negative cashup amounts (float deficits)
- Follows established Koha patterns for shared modals

Test plan:
1. Apply patch and run: yarn build
2. Test cashup workflows on register.tt:
   - Start cashup and complete with reconciliation
   - Quick cashup
   - Test with positive and negative amounts
3. Test cashup workflows on registers.tt:
   - Individual register cashup (should redirect back to registers)
   - Verify authorized value dropdown appears if configured
   - Test required note validation if enabled
4. Verify reconciliation calculations work correctly
5. Test cross-page workflow: start cashup in registers.tt, complete
   in register.tt

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Comment 93 Martin Renvoize (ashimema) 2025-12-10 18:37:05 UTC
Created attachment 190415 [details] [review]
Bug 40445: (follow-up) Improve cashup summary display for negative amounts

When refunds exceed collections during a cashup session, the summary
modal now clearly explains the negative amounts. Adds an informational
notice and adjusts labels to indicate cash needs to be added to the
register rather than collected.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>