Files
integreat/docs/testing/behaviors/payment.md
Bryce d627e3c5d0 refactor(all): rewrite all behavior docs in table format with checkboxes
Rewrite all 11 remaining behavior documents to match the streamlined
invoice.md format:

- dashboard.md: 250 lines, 62 behaviors
- payment.md: 260 lines, behaviors for list, void, check printing, ACH
- transaction.md: 310 lines, list, import, admin insights
- ledger.md: 519 lines, entries, P&L, balance sheet, cash flows
- company.md: 320 lines, profile, 1099s, Plaid/Yodlee, reports
- admin.md: 494 lines, clients, accounts, vendors, rules, jobs, history
- pos.md: 405 lines, sales, deposits, tenders, refunds, shifts
- search-indicators.md: 167 lines, search modal, indicators
- auth.md: 184 lines, login, logout, impersonation, sessions
- outgoing-invoice.md: 192 lines, create, line items, PDF
- legacy-spa.md: 340 lines, all legacy pages (docs only)

All documents now use:
- Testing Patterns section with reusable abstractions
- Numbered tables: # | Behavior | Test Strategy | Status
- It should... behavior descriptions
- Checkboxes [ ]/[x] for tracking implementation
- Cross-Cutting Behaviors for permissions, lock dates, etc.
- Test Data Requirements tables
- Existing Tests to Preserve sections

Total: 3,844 lines of behavior documentation across 12 subsystem docs.
2026-05-04 13:48:51 -07:00

14 KiB

Payment Behaviors

Overview

Payments represent disbursements to vendors for invoices. The payment system supports multiple payment types (check, cash, debit, balance credit) and tracks payments through statuses (pending, cleared, voided). Payments are created through the invoice payment flow and managed through a searchable grid interface.

Testing Philosophy

  • Prefer unit tests for pure business logic (calculations, validations, transformations)
  • Use integration tests for database interactions and cross-system flows
  • Use UI tests only for end-to-end happy paths that touch multiple pages
  • Every behavior must be user-visible; no tests for implementation details

Testing Patterns

Pattern: Grid Page Behaviors

Most list pages in Integreat follow the same pattern:

  1. Fetch IDs via Datomic query with filters
  2. Hydrate results via pull-many
  3. Render table with sortable columns
  4. Support selection (individual / all / all-filtered)
  5. Action buttons appear conditionally based on permissions and selection state

Test implications: Validate the query generation, not the rendering. UI tests only need to verify one filter and one sort work end-to-end.

Pattern: Permission Gates

Every mutating operation checks:

  1. assert-can-see-client — user has access to the client
  2. assert-not-locked — payment date >= client locked-until
  3. can? — user has the specific permission for the activity

Test implications: Integration test each gate independently. UI tests only verify the happy path with a permitted user.

Pattern: Check Generation Behaviors

Check printing involves:

  1. Validation of invoices and bank account
  2. Sequential check number assignment
  3. PDF generation with MICR encoding
  4. S3 upload and storage
  5. Transaction creation (for cash payments)

Test implications: Integration test the full flow once. Unit test validation logic and PDF content generation.


Payment List Page

Display Behaviors

# Behavior Test Strategy Status
1.1 It should display a table with columns: Client, Vendor, Bank Account, Check #, Status, Date, Amount, Links UI [ ]
1.2 It should show the Client column only when viewing payments for multiple clients Integration [ ]
1.3 It should hide the Bank Account and Date columns on smaller viewports UI [ ]
1.4 It should show "Cleared" status as a primary-colored pill UI [ ]
1.5 It should show "Pending" status as a secondary-colored pill UI [ ]
1.6 It should show "Voided" status as a red-colored pill UI [ ]
1.7 It should render check numbers as links to S3 PDFs when an s3-url exists UI [ ]
1.8 It should show plain check number text for payments without an s3-url UI [ ]
1.9 It should display a links dropdown showing associated invoices and transactions UI [ ]
1.10 It should display checkboxes for bulk selection on each row UI [ ]
1.11 It should show no check number for non-check payment types UI [ ]

Filtering Behaviors

# Behavior Test Strategy Status
2.1 It should filter payments by vendor typeahead selection Integration [ ]
2.2 It should filter payments by date range Integration [ ]
2.3 It should filter payments by check number (exact match or partial text) Integration [ ]
2.4 It should filter payments by invoice number (exact match) Integration [ ]
2.5 It should filter payments by amount range (min/max) Integration [ ]
2.6 It should filter payments by payment type via radio cards (All, Cash, Check, Debit) Integration [ ]
2.7 It should support exact-match navigation to a specific payment by ID, bypassing other filters Integration [ ]
2.8 It should filter payments by status via route (/payments/pending, /payments/cleared, /payments/voided) Integration [ ]
2.9 It should apply all filters via HTMX with debounced triggers Integration [ ]
2.10 It should combine all filters with AND logic Integration [ ]
2.11 It should use efficient time-bounded queries for date range filtering Integration [ ]
2.12 It should parse check number search as Long when possible, falling back to exact string match Unit + Integration [ ]
2.13 Given multiple filters are applied, when the user changes one filter, then the table should refresh with the combined filter set Integration [ ]
2.14 It should bypass all other filters when exact-match ID is provided Integration [ ]

Sorting Behaviors

# Behavior Test Strategy Status
3.1 It should sort by client name ascending/descending Integration [ ]
3.2 It should sort by vendor name ascending/descending Integration [ ]
3.3 It should sort by bank account ascending/descending Integration [ ]
3.4 It should sort by check number ascending/descending Integration [ ]
3.5 It should sort by date ascending/descending Integration [ ]
3.6 It should sort by amount ascending/descending Integration [ ]
3.7 It should sort by status ascending/descending Integration [ ]
3.8 Given the user clicks a column header twice, then the sort direction should toggle Integration [ ]

Pagination Behaviors

# Behavior Test Strategy Status
4.1 It should display 25 payments per page by default Integration [ ]
4.2 It should allow changing the per-page count Integration [ ]
4.3 It should calculate the total visible float and total float across all matching payments, not just the current page Unit [ ]

Selection Behaviors

# Behavior Test Strategy Status
5.1 It should allow selecting individual payments via checkboxes UI [ ]
5.2 It should allow selecting all visible payments via a header checkbox UI [ ]
5.3 It should allow selecting all filtered payments (up to 250) for bulk operations Integration [ ]
5.4 Given payments are selected, when the user applies a filter, then the selection should be cleared Integration [ ]

Row Action Behaviors

# Behavior Test Strategy Status
6.1 It should show a trash icon on each row unless the payment status is already voided UI [ ]
6.2 It should prompt for confirmation when clicking the trash icon ("Are you sure you want to void this payment?") UI [ ]
6.3 Given confirmation, when voiding a payment, then the row should be removed from the table with animation UI [ ]
6.4 It should block voiding cleared check payments Integration [ ]

Float Display Behaviors

# Behavior Test Strategy Status
7.1 It should display a "Visible in float" pill showing the sum of pending payment amounts in the current filter view Unit [ ]
7.2 It should display a "Total in float" pill showing the sum of all pending payments for the selected client(s) Unit [ ]
7.3 It should exclude voided payments from float calculations Unit [ ]
7.4 It should include only pending status payments in float calculations Unit [ ]

Bulk Void

# Behavior Test Strategy Status
8.1 It should show a confirmation modal with warning icon and count of payments to be voided UI [ ]
8.2 It should support "Selected only" mode to void only checkboxed payments UI [ ]
8.3 It should support "All selected" mode to void all payments matching current filters (up to 250) Integration [ ]
8.4 It should require admin permission for bulk void operations Integration [ ]
8.5 Given confirmation, when voiding, then the modal should close and a notification should show "Successfully voided X of Y payments" Integration [ ]
8.6 It should skip payments that already have transactions and skip already-voided payments Integration [ ]

Check Printing

# Behavior Test Strategy Status
9.1 It should generate physical check PDFs with MICR encoding at the bottom Integration [ ]
9.2 It should include payee, amount in numbers and words, date, memo, bank info, and client signature image Integration [ ]
9.3 It should generate voucher copies with full invoice details below the check Integration [ ]
9.4 It should store check PDFs in S3 under checks/{uuid}.pdf Integration [ ]
9.5 It should assign check numbers sequentially from the bank account's check number Integration [ ]
9.6 It should increment the bank account's check number by the number of vendors paid Integration [ ]
9.7 It should validate that the bank account has a starting check number Integration [ ]
9.8 It should merge multiple checks into a single PDF at merged-checks/{uuid}.pdf Integration [ ]
9.9 It should group invoices by vendor, creating one check per vendor per batch Integration [ ]
9.10 It should validate that all invoices belong to the same client and the selected bank account belongs to the same client Integration [ ]
9.11 It should reject check creation if the total amount is <= $0.00 Integration [ ]

ACH Payments

# Behavior Test Strategy Status
10.1 It should create pending payments with payment-type/debit Integration [ ]
10.2 It should not generate check PDFs for ACH payments Integration [ ]
10.3 It should not create transactions for ACH payments Integration [ ]

Balance Credit Payments

# Behavior Test Strategy Status
11.1 It should allow paying invoices from existing vendor credit with payment-type/balance-credit Integration [ ]
11.2 It should block balance credit payments when multiple vendors are selected Integration [ ]
11.3 It should offset positive-balance invoices against negative-balance invoices Integration [ ]
11.4 It should create a single cleared payment for the net amount, consuming credit invoices first-in Integration [ ]

Cash Payments

# Behavior Test Strategy Status
12.1 It should create payments with payment-type/cash automatically marked as cleared Integration [ ]
12.2 It should create an associated transaction with POSTED status Integration [ ]
12.3 It should use the account with numeric code 21000 for cash payment transactions Integration [ ]
12.4 It should set the payment date to the latest invoice date Integration [ ]

Cross-Cutting Behaviors

Voiding Behaviors

# Behavior Test Strategy Status
13.1 It should allow voiding pending payments Integration [ ]
13.2 It should allow voiding cash, debit, and balance-credit payments even when cleared Integration [ ]
13.3 It should block voiding cleared check payments Integration [ ]
13.4 It should set the payment amount to 0.0 when voided Integration [ ]
13.5 It should set the payment status to voided Integration [ ]
13.6 It should remove all invoice-payment links when voiding Integration [ ]
13.7 It should restore invoice outstanding balances by adding back the invoice-payment amount Integration [ ]
13.8 It should revert invoice status to unpaid when restored balance becomes non-zero Integration [ ]
13.9 It should unlink associated transactions when voiding Integration [ ]

Permission Behaviors

# Behavior Test Strategy Status
14.1 It should require client visibility for viewing payments Integration [ ]
14.2 It should require client visibility for voiding individual payments Integration [ ]
14.3 It should require admin permission for bulk voiding payments Integration [ ]
14.4 It should allow viewing S3 check PDFs to all users who can see the payment Integration [ ]

Lock Date Behaviors

# Behavior Test Strategy Status
15.1 It should block voiding payments dated before the client's locked-until date Integration [ ]
15.2 It should check lock dates on individual void operations Integration [ ]
15.3 It should check lock dates on bulk void operations Integration [ ]
15.4 It should exclude locked payments from bulk void results Integration [ ]
15.5 It should show a warning when some selected payments are locked UI [ ]

Test Data Requirements

Entity Requirements
Clients Multiple clients with different locations; some with locked-until dates
Vendors With/without default accounts; with/without terms and autopay settings
Bank Accounts Check, cash, and credit types; with/without starting check numbers
Invoices Various statuses, dates, amounts; positive and negative balances
Payments Check, cash, debit, and balance-credit types; pending, cleared, and voided statuses
Transactions Linked to cash payments with POSTED status
Files Check PDFs stored in S3

Existing Tests to Preserve

  • test/clj/auto_ap/integration/graphql/checks.clj — Check/payment GraphQL operations

Dependencies

  • Datomic for payment/invoice/transaction persistence
  • S3 for check PDF storage and retrieval
  • Solr for index updates after payment mutations
  • HTMX + Alpine.js for interactive grid behavior
  • clj-pdf for check PDF generation
  • clj-time for date parsing and coercion
  • auto-ap.datomic/scan-payments for efficient date-range queries
  • auto-ap.permissions/can? for permission checks
  • auto-ap.datomic/audit-transact for all mutations