---
id: TST-ACC-TRX-117
title: Reversals suite
kind: integration
product_area: accounting
module: transactions
revision: 1
status: draft
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
repository: services-accounting
files:
  - >-
    modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js
implements:
  - ATS-ACC-TRX-014-01
  - ATS-ACC-TRX-014-02
  - ATS-ACC-TRX-014-03
  - ATS-ACC-TRX-014-04
  - ATS-ACC-TRX-014-05
implements_parts:
  - scenario: ATS-ACC-TRX-014-01
    assertion: >-
      it refuses a draft invoice (invoice_not_draft), a line of another invoice
      (invoice_mismatch) and more than a line has left (over_application)
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js#it
      refuses a draft invoice (invoice_not_draft), a line of another invoice
      (invoice_mismatch) and more than a line has left (over_application)
  - scenario: ATS-ACC-TRX-014-02
    assertion: >-
      it wrote the credit memo of 4000 on the line, which freed the line’s 4000
      back onto the check (W-05)
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js#it
      wrote the credit memo of 4000 on the line, which freed the line’s 4000
      back onto the check (W-05)
  - scenario: ATS-ACC-TRX-014-02
    assertion: >-
      it issued the fee invoice of 500 and settled it with a credit of 500 made
      from the check’s freed money
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js#it
      issued the fee invoice of 500 and settled it with a credit of 500 made
      from the check’s freed money
  - scenario: ATS-ACC-TRX-014-02
    assertion: >-
      it requested the remainder of 3500 as a refund of the check for the staff
      to pay; the check holds it unapplied until then
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js#it
      requested the remainder of 3500 as a refund of the check for the staff to
      pay; the check holds it unapplied until then
  - scenario: ATS-ACC-TRX-014-03
    assertion: >-
      it completes with a remainder credit of 1000 from the check, the fee and
      refund steps skipped
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js#it
      completes with a remainder credit of 1000 from the check, the fee and
      refund steps skipped
  - scenario: ATS-ACC-TRX-014-04
    assertion: >-
      it refuses a reversal dated in no open period (period_not_open), writing
      nothing
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js#it
      refuses a reversal dated in no open period (period_not_open), writing
      nothing
  - scenario: ATS-ACC-TRX-014-04
    assertion: 'it replays the same key as the same reversal, writing nothing more'
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js#it
      replays the same key as the same reversal, writing nothing more
  - scenario: ATS-ACC-TRX-014-05
    assertion: >-
      it answers the figures of reversing 2000 more of the dues line with a fee
      of 300 and writes nothing
    provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js#it
      answers the figures of reversing 2000 more of the dues line with a fee of
      300 and writes nothing
environment: local
implementation_state: implemented
latest_result: not-run
latest_run_at: null
latest_run_ref: null
conformance: not-verified
estimated_minutes: 3
isolation: >-
  Suite-marked records in the prepared local test database; fixture teardown
  removes owned records.
provenance: test
source: >-
  services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js
evidence:
  - provenance: test
    source: >-
      services-accounting:modules/transactions/tests/integration/services/reversals/reversals.integration.spec.js
    assertion_titles:
      - the reversal operation (integration)
      - 'a line reversed with a fee, the remainder refunded'
      - >-
        answers the reversal numbered from 1,000,000, completed_with_exception
        refund_requested, 4000 freed, 500 fee, 3500 remainder
      - >-
        wrote the credit memo of 4000 on the line, which freed the line’s 4000
        back onto the check (W-05)
      - >-
        issued the fee invoice of 500 and settled it with a credit of 500 made
        from the check’s freed money
      - >-
        requested the remainder of 3500 as a refund of the check for the staff
        to pay; the check holds it unapplied until then
      - 'replays the same key as the same reversal, writing nothing more'
      - 'a part of a line reversed, the remainder credited'
      - >-
        takes the next number of the unit’s reversal seed (1,000,001 after the
        first reversal’s 1,000,000)
      - >-
        completes with a remainder credit of 1000 from the check, the fee and
        refund steps skipped
      - >-
        takes the line’s quantity instead of an amount: a quarter of the dues
        line is 1500
      - the preview
      - >-
        answers the figures of reversing 2000 more of the dues line with a fee
        of 300 and writes nothing
      - what cannot be reversed
      - >-
        refuses a draft invoice (invoice_not_draft), a line of another invoice
        (invoice_mismatch) and more than a line has left (over_application)
      - >-
        refuses a reversal dated in no open period (period_not_open), writing
        nothing
      - a credit memo alone frees paid money (W-05)
      - >-
        reverses the allocation a credited line no longer needs: the money back
        on the payment as unapplied
    imports:
      - 'const { sql } = require(''drizzle-orm'');'
      - 'const { stage } = require(''@rhythmsoftware/macroservice-testing/stage'');'
      - >-
        const { createCreditMemo } =
        require('../../../../services/change-memos/memo-commands');
      - >-
        const { createDraft } =
        require('../../../../services/invoices/invoice-drafts');
      - >-
        const { receivePayment } =
        require('../../../../services/payments/payment-receive');
      - >-
        const { previewReversal, reverseBilling } =
        require('../../../../services/reversals/reversal-commands');
      - '} = require(''../../payments-fixtures'');'
      - "\t\t\tconst { invoice } = world.require();"
      - "\t\t\tconst { check } = world.require();"
      - "\t\t\tconst outcome = reversed.require();"
      - "\t\t\tconst { invoice, check } = world.require();"
      - "\t\t\tconst outcome = reversed.require();"
      - "\t\t\tconst outcome = reversed.require();"
      - "\t\t\tconst { check } = world.require();"
      - "\t\t\tconst outcome = reversed.require();"
      - "\t\t\tconst { invoice } = world.require();"
      - "\t\t\texpect(again.reversal.id).to.equal(reversed.require().reversal.id);"
      - "\t\t\tconst { invoice } = world.require();"
      - "\t\t\texpect(credited.require().reversal.number).to.equal('1000001');"
      - "\t\t\tconst { check } = world.require();"
      - "\t\t\tconst outcome = credited.require();"
      - "\t\t\tconst { invoice } = world.require();"
      - "\t\t\tconst { invoice, check } = world.require();"
      - "\t\t\tconst { invoice } = world.require();"
      - "\t\t\tconst { invoice } = world.require();"
    test_double_declarations: []
---

# Reversals suite

## Verification Boundary

The suite exercises transaction commands and database protections in the local prepared test environment. Registration records the existing executable file; it does not report a run or establish product approval.

## What This Suite Proves

Its cited assertions contribute evidence for invalid reversal targets preserve billing; cancellation fee uses released receipt value; remainder returns to each contributing receipt; reversal refusal and replay retain one result; preview distinguishes processor and staff returns. The structured assertion bindings identify which parts of combined scenarios it executes.

## What It Does Not Prove

Local commands and route invocations do not establish deployed routing, live processor guarantees or the complete staff browser experience. An unbound feature chain remains proposed, and this registration carries no execution result.

## Real Dependencies and Test Doubles

The suite uses the imported commands, route handlers or persistence code against the local test database. Fixture helpers supply accounting context; any stepped clock, dummy processor or substituted external client is retained in the evidence declarations.

## Must Not Be Doubled

The command or persistence behavior under assertion and its relevant database protections must remain real. Substituting the final financial result removes evidence of transactional effects.
