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