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.
Created attachment 185289 [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
Created attachment 185290 [details] [review] Bug 40445: Add unit tests for cashup reconciliation functionality This patch adds comprehensive unit tests for the cashup reconciliation system: - Tests for balanced cashups (no surplus/deficit accountlines created) - Tests for surplus scenarios with CASHUP_SURPLUS credit creation - Tests for deficit scenarios with CASHUP_DEFICIT debit creation - Tests for user note handling and storage in reconciliation accountlines - Tests for transaction integrity ensuring atomicity - Tests for note sanitization (whitespace trimming, empty note handling) The tests ensure that: - Reconciliation accountlines are only created when there's a discrepancy - Surplus/deficit amounts are calculated and stored correctly - User notes are properly combined with system reconciliation details - Database transactions maintain consistency - Account types are linked correctly to cash registers
Created attachment 185291 [details] [review] Bug 40445: Add cashup reconciliation functionality to point of sale This patch implements comprehensive cashup reconciliation capabilities for the Koha point-of-sale system, allowing staff to record actual cash amounts and automatically track surplus or deficit discrepancies. Backend Changes: - Enhanced Koha::Cash::Register->add_cashup() method to accept actual_amount and optional notes - Automatic creation of CASHUP_SURPLUS or CASHUP_DEFICIT accountlines when discrepancies detected - Database transaction handling ensures atomicity of cashup actions and reconciliation records - Input validation and sanitization for amounts and notes Frontend Changes: - Interactive cashup modal requiring staff to enter actual amount removed from register - Real-time reconciliation calculation showing surplus/deficit as user types - Conditional note field (1000 char limit) appears only when discrepancies are detected - Enhanced cashup summary modal displays reconciliation details prominently - Empty amount field forces conscious entry (no pre-population) Features: - Balanced cashups: Only cashup action created (no reconciliation accountlines) - Surplus cashups: Creates CASHUP_SURPLUS credit with audit details - Deficit cashups: Creates CASHUP_DEFICIT debit with audit details - Staff notes: Optional explanations for discrepancies stored with system calculations - Full audit trail: All reconciliation data preserved with timestamps and manager links The implementation ensures mathematical balance is maintained while providing complete audit capabilities for cash register discrepancies.
Created attachment 185292 [details] [review] Bug 40445: (follow-up) Exclude reconciliation accountlines from outstanding_accountlines The outstanding_accountlines method should exclude CASHUP_SURPLUS and CASHUP_DEFICIT accountlines that are created during cashup reconciliation. These reconciliation entries represent discrepancies found during cashup and should not be counted as outstanding amounts for subsequent cashups. This prevents surplus/deficit accountlines from being included in the total when calculating expected amounts for future cashups. Test plan: 1. Perform a cashup with surplus or deficit 2. Verify that reconciliation accountlines are created 3. Check that subsequent calls to outstanding_accountlines() exclude these reconciliation entries 4. Run prove t/db_dependent/Koha/Cash/Register.t
# 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.
Created attachment 185809 [details] Quick demo of new functionality
Created attachment 186636 [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
Created attachment 186637 [details] [review] Bug 40445: Add unit tests for cashup reconciliation functionality This patch adds comprehensive unit tests for the cashup reconciliation system: - Tests for balanced cashups (no surplus/deficit accountlines created) - Tests for surplus scenarios with CASHUP_SURPLUS credit creation - Tests for deficit scenarios with CASHUP_DEFICIT debit creation - Tests for user note handling and storage in reconciliation accountlines - Tests for transaction integrity ensuring atomicity - Tests for note sanitization (whitespace trimming, empty note handling) The tests ensure that: - Reconciliation accountlines are only created when there's a discrepancy - Surplus/deficit amounts are calculated and stored correctly - User notes are properly combined with system reconciliation details - Database transactions maintain consistency - Account types are linked correctly to cash registers
Created attachment 186638 [details] [review] Bug 40445: Add cashup reconciliation functionality to point of sale This patch implements comprehensive cashup reconciliation capabilities for the Koha point-of-sale system, allowing staff to record actual cash amounts and automatically track surplus or deficit discrepancies. Backend Changes: - Enhanced Koha::Cash::Register->add_cashup() method to accept actual_amount and optional notes - Automatic creation of CASHUP_SURPLUS or CASHUP_DEFICIT accountlines when discrepancies detected - Database transaction handling ensures atomicity of cashup actions and reconciliation records - Input validation and sanitization for amounts and notes Frontend Changes: - Interactive cashup modal requiring staff to enter actual amount removed from register - Real-time reconciliation calculation showing surplus/deficit as user types - Conditional note field (1000 char limit) appears only when discrepancies are detected - Enhanced cashup summary modal displays reconciliation details prominently - Empty amount field forces conscious entry (no pre-population) Features: - Balanced cashups: Only cashup action created (no reconciliation accountlines) - Surplus cashups: Creates CASHUP_SURPLUS credit with audit details - Deficit cashups: Creates CASHUP_DEFICIT debit with audit details - Staff notes: Optional explanations for discrepancies stored with system calculations - Full audit trail: All reconciliation data preserved with timestamps and manager links The implementation ensures mathematical balance is maintained while providing complete audit capabilities for cash register discrepancies.
Created attachment 186639 [details] [review] Bug 40445: (follow-up) Exclude reconciliation accountlines from outstanding_accountlines The outstanding_accountlines method should exclude CASHUP_SURPLUS and CASHUP_DEFICIT accountlines that are created during cashup reconciliation. These reconciliation entries represent discrepancies found during cashup and should not be counted as outstanding amounts for subsequent cashups. This prevents surplus/deficit accountlines from being included in the total when calculating expected amounts for future cashups. Test plan: 1. Perform a cashup with surplus or deficit 2. Verify that reconciliation accountlines are created 3. Check that subsequent calls to outstanding_accountlines() exclude these reconciliation entries 4. Run prove t/db_dependent/Koha/Cash/Register.t
Created attachment 186640 [details] [review] Bug 40445: Implement two-phase cashup workflow for point of sale This commit introduces a two-phase cashup system that allows staff to start a cashup session, remove cash for counting, and complete the cashup later with reconciliation against the actual counted amount. Key changes: 1. **New cashup workflow methods**: - start_cashup(): Creates CASHUP_START action to begin counting session - cashup_in_progress(): Checks if a cashup session is active - Enhanced add_cashup(): Supports both legacy 'Quick cashup' and new two-phase modes 2. **Improved session boundary calculation**: - _get_session_start_timestamp(): Handles mixed quick/two-phase workflows - outstanding_accountlines(): Uses session boundaries instead of last CASHUP - Session boundaries correctly account for CASHUP_START timestamps 3. **Enhanced reconciliation logic**: - Reconciliation lines are backdated appropriately for each mode - Two-phase mode: Backdate to before CASHUP_START timestamp - Legacy mode: Backdate to before current time 4. **Updated cashup summary calculations**: - _get_session_boundaries(): Properly calculates session start/end - accountlines(): Returns session-specific accountlines - summary(): Uses correct session boundaries for transaction grouping 5. **Register interface updates**: - Dynamic toolbar shows "Start cashup" vs "Complete cashup" - Status indicator when cashup is in progress - Dual-workflow modal with quick and two-phase options 6. **Comprehensive test coverage**: - Two-phase workflow scenarios - Session boundary calculations - Mixed workflow compatibility - Error handling for duplicate operations This implementation maintains full backward compatibility while enabling libraries to separate cash counting from register operation, supporting real-world workflows where counting takes time.
Created attachment 186641 [details] [review] Bug 40445: Add two-phase cashup options to registers page Update the registers page "Record cashup" buttons to use the same dual-workflow modal as the single register page. This provides staff with both quick and two-phase cashup options directly from the registers summary. Changes: - Add new triggerCashupModalRegister modal with Start/Quick cashup options - Update individual register Record cashup buttons to use new modal - Add JavaScript handlers for modal population and Quick cashup logic - Preserve existing "Cashup all" functionality unchanged Each register's Record cashup button now offers: - Start cashup: Two-phase workflow for counting while register operates - Quick cashup: Single-phase workflow when amounts are obviously correct
Created attachment 186642 [details] [review] Bug 40445: Implement unified "Cashup selected" functionality with checkbox selection This commit replaces the 'Cashup all' option on the branch registers page with a checkbox-based selection system that allows staff to selectively process multiple registers using either quick or two-phase cashup workflows. Changes include: 1. Enhanced registers page template: - Added checkbox column with "Select all" functionality - Replaced "Cashup all" with "Cashup selected" in footer - Added comprehensive modal offering both workflow options - Implemented JavaScript for checkbox state management - Added indeterminate state handling for partial selections 2. Updated register.pl operation handlers: - Enhanced cud-cashup_start to handle comma-separated register IDs - Modified cud-cashup to support both single register reconciliation and multiple register quick cashup - Added comprehensive error handling for bulk operations - Maintained backward compatibility with single register operations 3. Unified approach: - Reuses existing operations instead of creating new ones - Supports both single and multiple register processing - Provides appropriate redirects based on operation scope The implementation allows libraries to: - Select specific registers for cashup processing - Choose between quick cashup (immediate completion) or two-phase workflow (start now, complete later) - Process multiple registers efficiently while maintaining individual reconciliation capability - Handle mixed register states appropriately
Created attachment 186643 [details] [review] Bug 40445: Use centralized exception handling in Cash Register methods Update start_cashup and add_cashup methods to use the new centralized exception translation system instead of letting raw DBIx::Class exceptions bubble up. This provides consistent Koha-specific exceptions across the API. Also update the corresponding unit tests to expect proper Koha::Exceptions::Object::FKConstraint exceptions instead of generic errors when invalid manager_id values are provided.
Created attachment 189333 [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
Created attachment 189334 [details] [review] Bug 40445: Add unit tests for cashup reconciliation functionality This patch adds comprehensive unit tests for the cashup reconciliation system: - Tests for balanced cashups (no surplus/deficit accountlines created) - Tests for surplus scenarios with CASHUP_SURPLUS credit creation - Tests for deficit scenarios with CASHUP_DEFICIT debit creation - Tests for user note handling and storage in reconciliation accountlines - Tests for transaction integrity ensuring atomicity - Tests for note sanitization (whitespace trimming, empty note handling) The tests ensure that: - Reconciliation accountlines are only created when there's a discrepancy - Surplus/deficit amounts are calculated and stored correctly - User notes are properly combined with system reconciliation details - Database transactions maintain consistency - Account types are linked correctly to cash registers
Created attachment 189335 [details] [review] Bug 40445: Add cashup reconciliation functionality to point of sale This patch implements comprehensive cashup reconciliation capabilities for the Koha point-of-sale system, allowing staff to record actual cash amounts and automatically track surplus or deficit discrepancies. Backend Changes: - Enhanced Koha::Cash::Register->add_cashup() method to accept actual_amount and optional notes - Automatic creation of CASHUP_SURPLUS or CASHUP_DEFICIT accountlines when discrepancies detected - Database transaction handling ensures atomicity of cashup actions and reconciliation records - Input validation and sanitization for amounts and notes Frontend Changes: - Interactive cashup modal requiring staff to enter actual amount removed from register - Real-time reconciliation calculation showing surplus/deficit as user types - Conditional note field (1000 char limit) appears only when discrepancies are detected - Enhanced cashup summary modal displays reconciliation details prominently - Empty amount field forces conscious entry (no pre-population) Features: - Balanced cashups: Only cashup action created (no reconciliation accountlines) - Surplus cashups: Creates CASHUP_SURPLUS credit with audit details - Deficit cashups: Creates CASHUP_DEFICIT debit with audit details - Staff notes: Optional explanations for discrepancies stored with system calculations - Full audit trail: All reconciliation data preserved with timestamps and manager links The implementation ensures mathematical balance is maintained while providing complete audit capabilities for cash register discrepancies.
Created attachment 189336 [details] [review] Bug 40445: (follow-up) Exclude reconciliation accountlines from outstanding_accountlines The outstanding_accountlines method should exclude CASHUP_SURPLUS and CASHUP_DEFICIT accountlines that are created during cashup reconciliation. These reconciliation entries represent discrepancies found during cashup and should not be counted as outstanding amounts for subsequent cashups. This prevents surplus/deficit accountlines from being included in the total when calculating expected amounts for future cashups. Test plan: 1. Perform a cashup with surplus or deficit 2. Verify that reconciliation accountlines are created 3. Check that subsequent calls to outstanding_accountlines() exclude these reconciliation entries 4. Run prove t/db_dependent/Koha/Cash/Register.t
Created attachment 189337 [details] [review] Bug 40445: Implement two-phase cashup workflow for point of sale This commit introduces a two-phase cashup system that allows staff to start a cashup session, remove cash for counting, and complete the cashup later with reconciliation against the actual counted amount. Key changes: 1. **New cashup workflow methods**: - start_cashup(): Creates CASHUP_START action to begin counting session - cashup_in_progress(): Checks if a cashup session is active - Enhanced add_cashup(): Supports both legacy 'Quick cashup' and new two-phase modes 2. **Improved session boundary calculation**: - _get_session_start_timestamp(): Handles mixed quick/two-phase workflows - outstanding_accountlines(): Uses session boundaries instead of last CASHUP - Session boundaries correctly account for CASHUP_START timestamps 3. **Enhanced reconciliation logic**: - Reconciliation lines are backdated appropriately for each mode - Two-phase mode: Backdate to before CASHUP_START timestamp - Legacy mode: Backdate to before current time 4. **Updated cashup summary calculations**: - _get_session_boundaries(): Properly calculates session start/end - accountlines(): Returns session-specific accountlines - summary(): Uses correct session boundaries for transaction grouping 5. **Register interface updates**: - Dynamic toolbar shows "Start cashup" vs "Complete cashup" - Status indicator when cashup is in progress - Dual-workflow modal with quick and two-phase options 6. **Comprehensive test coverage**: - Two-phase workflow scenarios - Session boundary calculations - Mixed workflow compatibility - Error handling for duplicate operations This implementation maintains full backward compatibility while enabling libraries to separate cash counting from register operation, supporting real-world workflows where counting takes time.
Created attachment 189338 [details] [review] Bug 40445: Add two-phase cashup options to registers page Update the registers page "Record cashup" buttons to use the same dual-workflow modal as the single register page. This provides staff with both quick and two-phase cashup options directly from the registers summary. Changes: - Add new triggerCashupModalRegister modal with Start/Quick cashup options - Update individual register Record cashup buttons to use new modal - Add JavaScript handlers for modal population and Quick cashup logic - Preserve existing "Cashup all" functionality unchanged Each register's Record cashup button now offers: - Start cashup: Two-phase workflow for counting while register operates - Quick cashup: Single-phase workflow when amounts are obviously correct
Created attachment 189339 [details] [review] Bug 40445: Implement unified "Cashup selected" functionality with checkbox selection This commit replaces the 'Cashup all' option on the branch registers page with a checkbox-based selection system that allows staff to selectively process multiple registers using either quick or two-phase cashup workflows. Changes include: 1. Enhanced registers page template: - Added checkbox column with "Select all" functionality - Replaced "Cashup all" with "Cashup selected" in footer - Added comprehensive modal offering both workflow options - Implemented JavaScript for checkbox state management - Added indeterminate state handling for partial selections 2. Updated register.pl operation handlers: - Enhanced cud-cashup_start to handle comma-separated register IDs - Modified cud-cashup to support both single register reconciliation and multiple register quick cashup - Added comprehensive error handling for bulk operations - Maintained backward compatibility with single register operations 3. Unified approach: - Reuses existing operations instead of creating new ones - Supports both single and multiple register processing - Provides appropriate redirects based on operation scope The implementation allows libraries to: - Select specific registers for cashup processing - Choose between quick cashup (immediate completion) or two-phase workflow (start now, complete later) - Process multiple registers efficiently while maintaining individual reconciliation capability - Handle mixed register states appropriately
Created attachment 189340 [details] [review] Bug 40445: Use centralized exception handling in Cash Register methods Update start_cashup and add_cashup methods to use the new centralized exception translation system instead of letting raw DBIx::Class exceptions bubble up. This provides consistent Koha-specific exceptions across the API. Also update the corresponding unit tests to expect proper Koha::Exceptions::Object::FKConstraint exceptions instead of generic errors when invalid manager_id values are provided.
Created attachment 189341 [details] [review] Bug 40445: Fix desk and register session persistence on library change When changing library in circ/set-library.pl, desk and register values were not being properly cleared from the session. This caused stale desk/register data from the previous library to persist, resulting in: - Incorrect cashup displays showing wrong library's register - POS defaulting to registers from different libraries - Session state inconsistent with visual UI Three issues fixed: 1. Template: Changed register "None" option ID from "set-library-noregister" to "noregister" to match JavaScript expectations (consistent with desk handling) 2. Desk logic: Changed condition to use defined() and explicitly clear session when "No desk" is selected 3. Register logic: Added session clearing when "No register" is selected and fixed condition to handle empty initial state Test plan: 1. Select Library A with Register 5 2. Change to Library B without selecting a register 3. Verify register is cleared from session (check POS page) 4. Repeat for desk selection 5. Verify explicit "-- None --" selection clears session values
Created attachment 189353 [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
Created attachment 189354 [details] [review] Bug 40445: Add unit tests for cashup reconciliation functionality This patch adds comprehensive unit tests for the cashup reconciliation system: - Tests for balanced cashups (no surplus/deficit accountlines created) - Tests for surplus scenarios with CASHUP_SURPLUS credit creation - Tests for deficit scenarios with CASHUP_DEFICIT debit creation - Tests for user note handling and storage in reconciliation accountlines - Tests for transaction integrity ensuring atomicity - Tests for note sanitization (whitespace trimming, empty note handling) The tests ensure that: - Reconciliation accountlines are only created when there's a discrepancy - Surplus/deficit amounts are calculated and stored correctly - User notes are properly combined with system reconciliation details - Database transactions maintain consistency - Account types are linked correctly to cash registers
Created attachment 189355 [details] [review] Bug 40445: Add cashup reconciliation functionality to point of sale This patch implements comprehensive cashup reconciliation capabilities for the Koha point-of-sale system, allowing staff to record actual cash amounts and automatically track surplus or deficit discrepancies. Backend Changes: - Enhanced Koha::Cash::Register->add_cashup() method to accept actual_amount and optional notes - Automatic creation of CASHUP_SURPLUS or CASHUP_DEFICIT accountlines when discrepancies detected - Database transaction handling ensures atomicity of cashup actions and reconciliation records - Input validation and sanitization for amounts and notes Frontend Changes: - Interactive cashup modal requiring staff to enter actual amount removed from register - Real-time reconciliation calculation showing surplus/deficit as user types - Conditional note field (1000 char limit) appears only when discrepancies are detected - Enhanced cashup summary modal displays reconciliation details prominently - Empty amount field forces conscious entry (no pre-population) Features: - Balanced cashups: Only cashup action created (no reconciliation accountlines) - Surplus cashups: Creates CASHUP_SURPLUS credit with audit details - Deficit cashups: Creates CASHUP_DEFICIT debit with audit details - Staff notes: Optional explanations for discrepancies stored with system calculations - Full audit trail: All reconciliation data preserved with timestamps and manager links The implementation ensures mathematical balance is maintained while providing complete audit capabilities for cash register discrepancies.
Created attachment 189356 [details] [review] Bug 40445: (follow-up) Exclude reconciliation accountlines from outstanding_accountlines The outstanding_accountlines method should exclude CASHUP_SURPLUS and CASHUP_DEFICIT accountlines that are created during cashup reconciliation. These reconciliation entries represent discrepancies found during cashup and should not be counted as outstanding amounts for subsequent cashups. This prevents surplus/deficit accountlines from being included in the total when calculating expected amounts for future cashups. Test plan: 1. Perform a cashup with surplus or deficit 2. Verify that reconciliation accountlines are created 3. Check that subsequent calls to outstanding_accountlines() exclude these reconciliation entries 4. Run prove t/db_dependent/Koha/Cash/Register.t
Created attachment 189357 [details] [review] Bug 40445: Implement two-phase cashup workflow for point of sale This commit introduces a two-phase cashup system that allows staff to start a cashup session, remove cash for counting, and complete the cashup later with reconciliation against the actual counted amount. Key changes: 1. **New cashup workflow methods**: - start_cashup(): Creates CASHUP_START action to begin counting session - cashup_in_progress(): Checks if a cashup session is active - Enhanced add_cashup(): Supports both legacy 'Quick cashup' and new two-phase modes 2. **Improved session boundary calculation**: - _get_session_start_timestamp(): Handles mixed quick/two-phase workflows - outstanding_accountlines(): Uses session boundaries instead of last CASHUP - Session boundaries correctly account for CASHUP_START timestamps 3. **Enhanced reconciliation logic**: - Reconciliation lines are backdated appropriately for each mode - Two-phase mode: Backdate to before CASHUP_START timestamp - Legacy mode: Backdate to before current time 4. **Updated cashup summary calculations**: - _get_session_boundaries(): Properly calculates session start/end - accountlines(): Returns session-specific accountlines - summary(): Uses correct session boundaries for transaction grouping 5. **Register interface updates**: - Dynamic toolbar shows "Start cashup" vs "Complete cashup" - Status indicator when cashup is in progress - Dual-workflow modal with quick and two-phase options 6. **Comprehensive test coverage**: - Two-phase workflow scenarios - Session boundary calculations - Mixed workflow compatibility - Error handling for duplicate operations This implementation maintains full backward compatibility while enabling libraries to separate cash counting from register operation, supporting real-world workflows where counting takes time.
Created attachment 189358 [details] [review] Bug 40445: Add two-phase cashup options to registers page Update the registers page "Record cashup" buttons to use the same dual-workflow modal as the single register page. This provides staff with both quick and two-phase cashup options directly from the registers summary. Changes: - Add new triggerCashupModalRegister modal with Start/Quick cashup options - Update individual register Record cashup buttons to use new modal - Add JavaScript handlers for modal population and Quick cashup logic - Preserve existing "Cashup all" functionality unchanged Each register's Record cashup button now offers: - Start cashup: Two-phase workflow for counting while register operates - Quick cashup: Single-phase workflow when amounts are obviously correct
Created attachment 189359 [details] [review] Bug 40445: Implement unified "Cashup selected" functionality with checkbox selection This commit replaces the 'Cashup all' option on the branch registers page with a checkbox-based selection system that allows staff to selectively process multiple registers using either quick or two-phase cashup workflows. Changes include: 1. Enhanced registers page template: - Added checkbox column with "Select all" functionality - Replaced "Cashup all" with "Cashup selected" in footer - Added comprehensive modal offering both workflow options - Implemented JavaScript for checkbox state management - Added indeterminate state handling for partial selections 2. Updated register.pl operation handlers: - Enhanced cud-cashup_start to handle comma-separated register IDs - Modified cud-cashup to support both single register reconciliation and multiple register quick cashup - Added comprehensive error handling for bulk operations - Maintained backward compatibility with single register operations 3. Unified approach: - Reuses existing operations instead of creating new ones - Supports both single and multiple register processing - Provides appropriate redirects based on operation scope The implementation allows libraries to: - Select specific registers for cashup processing - Choose between quick cashup (immediate completion) or two-phase workflow (start now, complete later) - Process multiple registers efficiently while maintaining individual reconciliation capability - Handle mixed register states appropriately
Created attachment 189360 [details] [review] Bug 40445: Use centralized exception handling in Cash Register methods Update start_cashup and add_cashup methods to use the new centralized exception translation system instead of letting raw DBIx::Class exceptions bubble up. This provides consistent Koha-specific exceptions across the API. Also update the corresponding unit tests to expect proper Koha::Exceptions::Object::FKConstraint exceptions instead of generic errors when invalid manager_id values are provided.
Created attachment 189361 [details] [review] Bug 40445: Fix desk and register session persistence on library change When changing library in circ/set-library.pl, desk and register values were not being properly cleared from the session. This caused stale desk/register data from the previous library to persist, resulting in: - Incorrect cashup displays showing wrong library's register - POS defaulting to registers from different libraries - Session state inconsistent with visual UI Three issues fixed: 1. Template: Changed register "None" option ID from "set-library-noregister" to "noregister" to match JavaScript expectations (consistent with desk handling) 2. Desk logic: Changed condition to use defined() and explicitly clear session when "No desk" is selected 3. Register logic: Added session clearing when "No register" is selected and fixed condition to handle empty initial state Test plan: 1. Select Library A with Register 5 2. Change to Library B without selecting a register 3. Verify register is cleared from session (check POS page) 4. Repeat for desk selection 5. Verify explicit "-- None --" selection clears session values
Created attachment 189362 [details] [review] Bug 40445: Add detailed error handling for cashup completion failures The cashup completion process in pos/register.pl was providing only a generic "Failed to complete cashup" message for all errors, making it difficult to diagnose issues during development and production use. This patch enhances error handling by: 1. Adding specific error messages for MissingParameter exceptions (displays the actual missing parameter name) 2. Adding specific error messages for AmountNotPositive exceptions (clarifies that amount must be positive and non-zero) 3. Displaying detailed error information for unhandled exceptions in the generic error case (aids debugging) These improvements provide clearer feedback to users and make it easier to troubleshoot cashup failures in both two-phase and legacy workflows. Test plan: 1. Attempt cashup operations that trigger various exceptions 2. Verify each exception type shows an appropriate, specific error message 3. Confirm the error details help identify the root cause
Created attachment 189363 [details] [review] Bug 40445: Prevent starting cashup with zero cash transactions In the two-phase cashup workflow, users could start a cashup session when there were no cash transactions, but then get trapped unable to complete it because the completion validation requires amount > 0. This creates a poor user experience where: 1. User starts cashup (allowed with 0 expected amount) 2. Modal shows "Expected cashup amount: 0.00" 3. User enters "0" as actual amount 4. Validation fails: "amount must be positive number greater than zero" 5. User is stuck - cannot complete, cashup session remains open This patch prevents the trap by validating at cashup start time: Backend changes: - start_cashup() now checks if expected_amount > 0 - Throws Koha::Exceptions::Object::BadValue if no transactions exist - Prevents creating a cashup session that cannot be completed Error handling: - pos/register.pl catches BadValue and displays informative message - pos/registers.pl catches BadValue for multi-register cashup - Error message clearly explains no transactions exist to cashup UI changes: - Added error_cashup_no_transactions template parameter - Displays as alert-info (informational) rather than alert-warning - Message: "Cannot start cashup - there are no cash transactions in this register since the last cashup" This validates the business rule consistently: cashups require cash transactions. Users are informed upfront rather than getting trapped in an incomplete workflow. Test plan: 1. Start a register with no cash transactions since last cashup 2. Attempt to start a cashup (two-phase workflow) 3. Verify error message appears preventing cashup start 4. Add a cash transaction to the register 5. Attempt to start cashup again 6. Verify cashup starts successfully 7. Test multi-register cashup on registers page 8. Verify appropriate error for registers with no transactions
Created attachment 189364 [details] [review] Bug 40445: Add cashup summary preview for in-progress cashups In the two-phase cashup workflow, staff start a cashup and then count cash while continuing to process transactions. There was no way to preview what would be included in the cashup until it was completed. This patch adds a "Preview expected summary" link in the "Cashup in progress" alert that allows staff to: - See what transactions will be included in the cashup - Review expected cash amounts before completing - Verify the session period is correct - Check for any unexpected transactions Changes: Backend (Koha/REST/V1/CashRegisters/Cashups.pm): - Modified get() endpoint to handle CASHUP_START actions for preview - Fallback lookup finds CASHUP_START by ID when not found as completed - Wraps CASHUP_START as Cashup object to generate summary Frontend (pos/register.tt): - Added "Preview expected summary" link in cashup-in-progress alert - Link includes data-in-progress="true" attribute for JS handling - Uses existing cashupSummaryModal for consistent UX JavaScript (cashup_modal.js): - Detects in-progress flag from link data attribute - Changes modal title to "Cashup summary preview (in progress)" - Adds informational alert explaining this is a preview - Note clarifies that transactions will update values until completion - Removes preview notice for completed cashup summaries The preview uses the same summary generation logic as completed cashups, showing accurate period boundaries and transaction totals. Staff can open the preview multiple times to see updated values as they process transactions. Test plan: 1. Start a cashup on a register (two-phase workflow) 2. Verify "Cashup in progress" alert appears 3. Click "Preview expected summary" link 4. Verify modal shows: - Title includes "(in progress)" - Blue info alert explaining this is a preview - Correct period dates - Current transaction totals 5. Add a new cash transaction 6. Re-open preview, verify totals updated 7. Complete the cashup normally 8. View completed cashup summary 9. Verify no preview notice shown, title is normal
Some nice polishing going on here given feedback and testing.. I'll post a new demo video next week.
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
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
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
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
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()
Created attachment 189415 [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()
Created attachment 189420 [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/>
Created attachment 189421 [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
Created attachment 189422 [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
Created attachment 189423 [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
Created attachment 189424 [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()
Created attachment 189425 [details] Demo
Created attachment 189426 [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/>
Created attachment 189427 [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
Created attachment 189428 [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
Created attachment 189429 [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
Created attachment 189430 [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()
Created attachment 189476 [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/>
Created attachment 189477 [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
Created attachment 189478 [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
Created attachment 189479 [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
Created attachment 189480 [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()
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
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
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Created attachment 190361 [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/>
Created attachment 190362 [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
Created attachment 190363 [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
Created attachment 190364 [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
Created attachment 190365 [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()
Created attachment 190366 [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
Created attachment 190367 [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
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
Created attachment 190369 [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/>
Created attachment 190370 [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
Created attachment 190371 [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
Created attachment 190372 [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
Created attachment 190373 [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()
Created attachment 190374 [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
Created attachment 190375 [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
Created attachment 190376 [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
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
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
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
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
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/>
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/>
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/>
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/>
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/>
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/>
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/>
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/>
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/>
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/>
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/>
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/>
Created attachment 191273 [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/>
Created attachment 191274 [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/>
Created attachment 191275 [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/>
Created attachment 191276 [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/>
Created attachment 191277 [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/>
Created attachment 191278 [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/>
Created attachment 191279 [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/>
Created attachment 191280 [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/>
Created attachment 191281 [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/>
Created attachment 191282 [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/>
Created attachment 191283 [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/>
Created attachment 191284 [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/>
Created attachment 191285 [details] [review] Bug 40445: (follow-up) Fix backend validation for non-cash transactions The previous commits fixed the frontend to allow cashup buttons when there are non-cash transactions, but the backend validation was still restricting cashups to cash-only scenarios. This patch fixes the backend validation in Koha::Cash::Register: 1. start_cashup() - Changed validation to check for ANY transactions instead of only CASH/SIP00 transactions. This allows starting a cashup when there are Card or other non-cash payment types. 2. add_cashup() - Removed the requirement that amount must be non-zero. When there are only non-cash transactions, the cashup amount can legitimately be 0.00 (no cash to count/remove). 3. Updated error messages in register.tt to reflect the new validation logic (removed references to "cash transactions" and "non-zero"). Without these backend fixes, the frontend changes would still result in validation errors when users attempted cashups with only non-cash transactions. Test plan: 1. Create transactions on a register using only Card payment type 2. Attempt to start a cashup - should succeed (not throw BadValue exception) 3. Enter 0.00 as the cashup amount - should complete successfully 4. Verify no surplus/deficit lines are created (balanced cashup) 5. Attempt to start cashup with zero transactions - should still fail with appropriate error message
Created attachment 191286 [details] [review] Bug 40445: (follow-up) Allow cashup with non-cash transactions Previously, the "Record cashup" buttons on both the register and registers pages were disabled when there were zero CASH/SIP00 transactions, even if other payment types (Card, etc.) had transactions. This was incorrect - cashup should be allowed as long as there are ANY transactions, regardless of payment type. Staff still need to record cashups even when all transactions were Card or other non-cash payment methods. Changes: - register.tt: Check total_transactions instead of total_bankable to determine if cashup button should be enabled - registers.tt: Check rtotal instead of rbankable for both checkbox and button enable/disable logic Test plan: 1. Create transactions on a register using only Card payment type 2. Visit the register page - verify "Record cashup" button is enabled 3. Visit the registers page - verify the register checkbox is enabled and "Record cashup" button is enabled 4. Perform a cashup - verify it completes successfully
Created attachment 191287 [details] [review] Bug 40445: (follow-up) Fix two-stage cashup completion not saving When attempting to complete a two-stage cashup, the submission was failing silently and not recording the cashup completion. This was caused by two bugs: 1. Backend bug: pos/registers.pl was ignoring the user-entered amount and reconciliation note from the form submission. Instead of reading the 'amount' parameter from the form, it was recalculating the expected amount, which meant reconciliation (surplus/deficit) was never performed. 2. Frontend bug: The JavaScript modal handler was crashing when trying to parse the expected amount because jQuery's .data() method returns a number (not a string) when the value looks numeric. The code was calling .replace() on this number, which caused a TypeError. This crash prevented the registerid from being set in the hidden form field, causing the form submission to be ignored by the backend. Test plan: 1. Create some cash transactions on a register 2. Click "Record cashup" → "Start cashup" 3. Click "Complete cashup" and enter an amount different from expected 4. Add a reconciliation note 5. Click "Complete cashup" 6. Verify the cashup completes successfully 7. Verify a CASHUP_SURPLUS or CASHUP_DEFICIT accountline was created 8. Verify the reconciliation note was saved
Created attachment 191288 [details] [review] Bug 40445: (follow-up) Update tests for zero amount cashups The previous commit changed add_cashup() to allow amount=0 (for non-cash transaction scenarios like Card-only payments), but the tests still expected amount=0 to be rejected. This patch updates the test expectations: 1. Changed the 'invalid_amount' subtest to accept zero amounts as valid instead of expecting an exception 2. Added verification that zero amounts are stored correctly 3. Updated test plan count from 4 to 6 tests (added zero amount verification test) 4. Updated test description and comments to reflect the new behavior The zero amount scenario is now valid for cashups where there are only non-cash transactions (Card, Bank Transfer, etc.) and no physical cash to count or remove from the register.
Created attachment 193123 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193124 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193125 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193126 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193127 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193128 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193129 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193130 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193131 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193132 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193133 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193134 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193135 [details] [review] Bug 40445: (follow-up) Fix backend validation for non-cash transactions The previous commits fixed the frontend to allow cashup buttons when there are non-cash transactions, but the backend validation was still restricting cashups to cash-only scenarios. This patch fixes the backend validation in Koha::Cash::Register: 1. start_cashup() - Changed validation to check for ANY transactions instead of only CASH/SIP00 transactions. This allows starting a cashup when there are Card or other non-cash payment types. 2. add_cashup() - Removed the requirement that amount must be non-zero. When there are only non-cash transactions, the cashup amount can legitimately be 0.00 (no cash to count/remove). 3. Updated error messages in register.tt to reflect the new validation logic (removed references to "cash transactions" and "non-zero"). Without these backend fixes, the frontend changes would still result in validation errors when users attempted cashups with only non-cash transactions. Test plan: 1. Create transactions on a register using only Card payment type 2. Attempt to start a cashup - should succeed (not throw BadValue exception) 3. Enter 0.00 as the cashup amount - should complete successfully 4. Verify no surplus/deficit lines are created (balanced cashup) 5. Attempt to start cashup with zero transactions - should still fail with appropriate error message Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193136 [details] [review] Bug 40445: (follow-up) Allow cashup with non-cash transactions Previously, the "Record cashup" buttons on both the register and registers pages were disabled when there were zero CASH/SIP00 transactions, even if other payment types (Card, etc.) had transactions. This was incorrect - cashup should be allowed as long as there are ANY transactions, regardless of payment type. Staff still need to record cashups even when all transactions were Card or other non-cash payment methods. Changes: - register.tt: Check total_transactions instead of total_bankable to determine if cashup button should be enabled - registers.tt: Check rtotal instead of rbankable for both checkbox and button enable/disable logic Test plan: 1. Create transactions on a register using only Card payment type 2. Visit the register page - verify "Record cashup" button is enabled 3. Visit the registers page - verify the register checkbox is enabled and "Record cashup" button is enabled 4. Perform a cashup - verify it completes successfully Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193137 [details] [review] Bug 40445: (follow-up) Fix two-stage cashup completion not saving When attempting to complete a two-stage cashup, the submission was failing silently and not recording the cashup completion. This was caused by two bugs: 1. Backend bug: pos/registers.pl was ignoring the user-entered amount and reconciliation note from the form submission. Instead of reading the 'amount' parameter from the form, it was recalculating the expected amount, which meant reconciliation (surplus/deficit) was never performed. 2. Frontend bug: The JavaScript modal handler was crashing when trying to parse the expected amount because jQuery's .data() method returns a number (not a string) when the value looks numeric. The code was calling .replace() on this number, which caused a TypeError. This crash prevented the registerid from being set in the hidden form field, causing the form submission to be ignored by the backend. Test plan: 1. Create some cash transactions on a register 2. Click "Record cashup" → "Start cashup" 3. Click "Complete cashup" and enter an amount different from expected 4. Add a reconciliation note 5. Click "Complete cashup" 6. Verify the cashup completes successfully 7. Verify a CASHUP_SURPLUS or CASHUP_DEFICIT accountline was created 8. Verify the reconciliation note was saved Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193138 [details] [review] Bug 40445: (follow-up) Update tests for zero amount cashups The previous commit changed add_cashup() to allow amount=0 (for non-cash transaction scenarios like Card-only payments), but the tests still expected amount=0 to be rejected. This patch updates the test expectations: 1. Changed the 'invalid_amount' subtest to accept zero amounts as valid instead of expecting an exception 2. Added verification that zero amounts are stored correctly 3. Updated test plan count from 4 to 6 tests (added zero amount verification test) 4. Updated test description and comments to reflect the new behavior The zero amount scenario is now valid for cashups where there are only non-cash transactions (Card, Bank Transfer, etc.) and no physical cash to count or remove from the register. Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193139 [details] [review] Bug 40445: (follow-up) Set branchcode for CASHUP_SURPLUS and CASHUP_DEFICIT accountlines When creating CASHUP_SURPLUS and CASHUP_DEFICIT accountlines during cashup reconciliation, the branchcode was not being set. This resulted in accountlines with NULL branchcode values, which violates the expectation that all accountlines should have an associated branch. This patch: - Sets branchcode from the cash register's branch for both CASHUP_SURPLUS and CASHUP_DEFICIT accountlines - Adds test coverage to verify branchcode is correctly set Test plan: 1. Apply patch 2. Run prove t/db_dependent/Koha/Cash/Register.t 3. Verify all tests pass, including new branchcode checks 4. In the staff interface, perform a cashup with a surplus or deficit 5. Verify the created accountline has the correct branchcode matching the cash register's branch Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193140 [details] [review] Bug 40445: (follow-up) Set payment_type for CASHUP_SURPLUS and CASHUP_DEFICIT accountlines When creating CASHUP_SURPLUS and CASHUP_DEFICIT accountlines during cashup reconciliation, the payment_type was not being set. This resulted in accountlines with NULL payment_type values, which should be 'CASH' to properly indicate these are cash-related transactions. This patch: - Sets payment_type to 'CASH' for both CASHUP_SURPLUS and CASHUP_DEFICIT accountlines created during the reconciliation process - Adds test coverage to verify payment_type is correctly set - Adds preference mocking to prevent test failures in subtests that don't specifically test reconciliation note requirements All required fields are now properly set for reconciliation accountlines: - payment_type (CASH) - manager_id - branchcode (from earlier follow-up) - register_id Test plan: 1. Apply patch 2. Run prove t/db_dependent/Koha/Cash/Register.t 3. Verify all tests pass, including new payment_type checks 4. In the staff interface, perform a cashup with a surplus or deficit 5. Verify the created CASHUP_SURPLUS or CASHUP_DEFICIT accountline has payment_type set to 'CASH' Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193141 [details] [review] Bug 40445: (follow-up) Set amountoutstanding for CASHUP_SURPLUS and CASHUP_DEFICIT accountlines CASHUP_SURPLUS and CASHUP_DEFICIT accountlines represent immediate reconciliation adjustments that should be considered settled at the time of creation. These records should have amountoutstanding set to 0 to indicate they are fully reconciled. This patch adds amountoutstanding => 0 when creating both types of reconciliation accountlines and updates the tests to verify this behavior. Test plan: 1. prove t/db_dependent/Koha/Cash/Register.t 2. Verify all tests pass, specifically the new tests for amountoutstanding Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193180 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193181 [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/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193182 [details] [review] Bug 40445: Implement optional two-phase cashup workflow This patch implements an optional two-phase cashup workflow for point of sale operations, along with improved error handling and validation. Two-Phase Cashup Workflow: - Staff can initiate cashup (CASHUP_START) and complete later - Prevents new transactions on registers with cashups in progress - Tracks cashup sessions with start/end timestamps - Supports both quick cashup (immediate) and staged cashup workflows - Updates batch cashup workflow operations across multiple registers Error Handling & Validation: - Centralized exception handling for cashup operations - Clear validation messages for missing parameters - Prevents cashup when no cash transactions exist - Improved handling of zero/negative amounts - Informative error messages for user guidance Negative Amount Support: - Supports negative cashup amounts for cashup deficits - Automatic detection when actual cash is less than expected amount - Creates appropriate CASHUP_DEFICIT records - UI handles both positive and negative reconciliation amounts - Updated calculations and display logic throughout Modal Refactoring: - Eliminates code duplication between register.tt and registers.tt - Centralized cashup modal functionality in cashup_modals.js - Shared confirm_cashup.inc and trigger_cashup.inc templates - Consistent user experience across all cashup workflows - Improved maintainability and code organization Backend changes (Koha::Cash::Register): - start_cashup(): Creates CASHUP_START action to begin session - cashup_in_progress(): Detects active cashup sessions - add_cashup(): Enhanced with two-phase completion support - outstanding_accountlines(): Respects cashup session boundaries Frontend changes: - Interactive modals for starting and completing cashups - Real-time calculation displays - Support for reconciliation with actual amounts - Batch operations UI for multiple registers - Responsive error messaging and validation feedback Test plan: 1. Apply patches and restart services 2. Run prove t/db_dependent/Koha/Cash/Register.t 3. Run prove t/db_dependent/Koha/Cash/Register/Cashup.t 4. Test single register workflows: - Start cashup, add transactions, verify blocked - Complete cashup with reconciliation amounts - Test with positive, negative, and zero amounts 5. Test multi-register workflows: - Select multiple registers on registers page - Perform batch cashup operations - Verify each register processes correctly 6. Test error conditions: - Attempt cashup with no transactions - Attempt cashup with invalid amounts - Verify clear error messages displayed Sponsored-by: OpenFifth <https://openfifth.co.uk/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Created attachment 193183 [details] [review] Bug 40445: Add configuration options and UI enhancements This patch adds configuration options for cashup reconciliation and enhances the user interface with preview functionality and improved interaction patterns. Configuration Options: 1. CashupReconciliationNoteRequired (System Preference): - Optional validation requiring reconciliation notes when discrepancies exist - Ensures documentation of surplus/deficit causes when needed - Can be disabled for less stringent workflows - Applied at cashup completion time 2. CashupReconciliationNoteAuthorisedValue (System Preference): - Allows use of authorized value dropdown for reconciliation notes - Provides standardized note options (e.g., "Till count error", "Cash removed") - Falls back to free text textarea when not configured - Improves consistency and reporting capabilities UI Enhancements: 1. Cashup Summary Preview: - Preview cashup summary for in-progress cashups - Shows current transaction totals before completion - Clearly indicates preview vs. final summary status - Helps staff verify amounts before committing 2. Improved User Experience: - Conditional note fields based on configuration - Authorized value dropdowns when configured - Clear validation messages - Responsive UI updates Backend changes: - Enhanced Koha::REST::V1::CashRegisters::Cashups with preview support - Database atomicupdate script for system preferences - Validation logic for required notes Frontend changes: - Preview modal functionality in cashup_modal.js - Conditional rendering of note input fields - Authorized value dropdown integration - Enhanced summary display logic Test plan: 1. Apply patches and run database update 2. Configure CashupReconciliationNoteRequired: - Enable preference - Perform cashup with discrepancy without note - should fail - Add note and retry - should succeed - Disable preference - verify note optional 3. Configure CashupReconciliationNoteAuthorisedValue: - Create AV category (e.g., CASHUP_NOTE) with values - Set preference to category name - Verify dropdown appears in cashup modal - Clear preference - verify textarea shown 4. Test cashup preview: - Start cashup on register - Click "Preview cashup summary" - Verify current totals displayed - Add transaction and re-preview - verify updated - Complete cashup - verify final summary Sponsored-by: OpenFifth <https://openfifth.co.uk/> Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
OK, I cleaned up the submission significantly to make it easier to QA
*** Bug 37530 has been marked as a duplicate of this bug. ***