---
id: ATS-COM-FUL-007
scope: CAP-COM-FUL-007
product_area: commerce
module: fulfillment
revision: 1
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-COM-FUL-007-01
    title: Repeated document requests share one adjustment
    level: api
    proves:
      - BR-CAP-COM-FUL-007-01
    preconditions: A cancellation document needs financial execution.
    steps: Ask twice for financial execution of the same cancellation.
    expected: Both requests identify the same adjustment and pending plan.
    negative: false
    data_needs: Fixtures for repeated document requests share one adjustment.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#creates
        the adjustment once (the second request answers the first) with its
        steps pending
      - >-
        services-commerce:modules/fulfillment/tests/integration/db/register-tables.table.integration.spec.js#hold
        an enforcement once per obligation and cause (enforcements_cause_uq) and
        an adjustment once per document (financial_adjustments_document_uq)
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#creates
      the adjustment once (the second request answers the first) with its steps
      pending
  - id: ATS-COM-FUL-007-02
    title: Planning preserves financial-step order
    level: unit
    proves:
      - BR-CAP-COM-FUL-007-02
      - BR-CAP-COM-FUL-007-03
    preconditions: 'Documents vary payment, fees and amendment replacement invoices.'
    steps: Build the adjustment plan for each fixture.
    expected: >-
      Steps retain their fixed order and keys, unpaid work uses only the memo
      and amendments apply freed funds to the replacement invoice first.
    negative: false
    data_needs: Fixtures for planning preserves financial-step order.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#plans
        the memo, the fee, the credit from the freed money, its application to
        the fee and the refund of the remainder, in that order, each under its
        key
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#plans
        the memo alone for a line never paid, the fee invoice beside it when the
        terms charge one, and nothing without an invoice
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#treats
        a zero fee as no fee
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#applies
        the freed money to an amendment’s new invoice before the remainder (11
        §7.1, P7): a credit and its application by invoice id, then the credit
        of what is left
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#spells
        every key commerce:{document_kind}:{document_id}:{step}
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#plans
        the five steps of 04 §6 in order with their keys: the memo, the fee, the
        credit from the freed money, its application, the refund of the
        remainder
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#plans
      the memo, the fee, the credit from the freed money, its application to the
      fee and the refund of the remainder, in that order, each under its key
  - id: ATS-COM-FUL-007-03
    title: Interrupted financial commands retain their retry keys
    level: api
    proves:
      - BR-CAP-COM-FUL-007-04
      - BR-CAP-COM-FUL-007-05
    preconditions: An adjustment command throws and later gives a temporary refusal.
    steps: 'Execute, interrupt, resume and exercise retryable refusal.'
    expected: >-
      Recovery resends the same command key and temporary refusal leaves pending
      work without an exception.
    negative: false
    data_needs: Fixtures for interrupted financial commands retain their retry keys.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#leaves
        the step submitted when the command throws, and the resume re-sends the
        same key
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#leaves
        a retryable refusal pending for the next run, with the attempt counted
        and no exception
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#stops
        at the refund: the four steps before it succeeded, the refund failed,
        the adjustment failed with adjustment_failed raised
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#leaves
      the step submitted when the command throws, and the resume re-sends the
      same key
  - id: ATS-COM-FUL-007-04
    title: Processor-pending refunds wait for the final event
    level: api
    proves:
      - BR-CAP-COM-FUL-007-06
    preconditions: A refund remains pending at its processor.
    steps: 'Resume repeatedly, then exercise successful and failed refund events.'
    expected: >-
      Pending processing consumes no failure attempts; the final event completes
      or fails the work appropriately.
    negative: false
    data_needs: Fixtures for processor-pending refunds wait for the final event.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#is
        held pending at the processor, never failed, however many times it is
        asked again, with no exception
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#completes
        with the refund’s reference when the refund has settled
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#fails
        for Finance, with its exception, when the refund then fails at the
        processor
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/facts/financial-facts-handler.integration.spec.js#holds
        the refund pending at the processor, not failed, and counts no failed
        attempt (COMM-M1 R7-2)
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-pending-at-processor.spec.js#is
        true when the books are done and only the refund is pending at the
        processor
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#is
      held pending at the processor, never failed, however many times it is
      asked again, with no exception
  - id: ATS-COM-FUL-007-05
    title: Staff can retry failure or record external settlement
    level: api
    proves:
      - BR-CAP-COM-FUL-007-08
      - BR-CAP-COM-FUL-007-09
      - BR-CAP-COM-FUL-007-10
    preconditions: Two adjustments have failed and a reader identity is available.
    steps: >-
      List with and without scope, retry one, resolve another, repeat and try
      reader actions.
    expected: >-
      Unscoped reads and unauthorized actions fail; retry sends only failed work
      and external resolution closes its finding without repetition.
    negative: true
    data_needs: Fixtures for staff can retry failure or record external settlement.
    bound_to:
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#lists
        the order’s adjustments and the failed ones, answers one with its steps,
        and refuses a query naming neither an order nor a state
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#retries
        the failed adjustment on its route: the refund alone re-sent, completed;
        a reader is refused
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#resolves
        the other failed adjustment offline on its route, with its exception,
        and refuses a repeat
      - >-
        services-commerce:modules/operations/tests/integration/services/interventions/operations-interventions.integration.spec.js#retries
        the failed adjustment: resumed from the refund alone, completed, its
        exception resolved; a completed one is refused
      - >-
        services-commerce:modules/operations/tests/integration/services/interventions/operations-interventions.integration.spec.js#resolves
        the other failed adjustment offline, with its exception; a resolved one
        is refused
    provenance: test
    source: >-
      services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#lists
      the order’s adjustments and the failed ones, answers one with its steps,
      and refuses a query naming neither an order nor a state
  - id: ATS-COM-FUL-007-06
    title: Accounting commands preserve their required request shapes
    level: unit
    proves:
      - BR-CAP-COM-FUL-007-11
    preconditions: Fixtures represent every financial step.
    steps: 'Send commands against successful, refusal and server-error answers.'
    expected: >-
      Requests retain the expected keys and quantities, refusals are classified
      and interrupted work remains recoverable.
    negative: false
    data_needs: Fixtures for accounting commands preserve their required request shapes.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#sends
        the credit memo to POST /credit_memos/{tenantId} with the key twice, the
        lines as money, and answers the memo’s id
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#sends
        every memo line’s quantity as Accounting’s contract has it, a decimal
        string (0230: a number was refused 400)
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#sends
        the fee invoice issued at once under the commerce source, the credit
        from the payment, its application and the refund executed, each to its
        route
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#answers
        a refusal as failed with Accounting’s code, retryable for the refusals a
        later attempt may change and permanent for a decline
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#throws
        when Accounting answers a server error or a document without an id, so
        the step stays submitted for the resume
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#sends
      the credit memo to POST /credit_memos/{tenantId} with the key twice, the
      lines as money, and answers the memo’s id
evidence:
  - repository: services-commerce
    tests:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#creates
        the adjustment once (the second request answers the first) with its
        steps pending
      - >-
        services-commerce:modules/fulfillment/tests/integration/db/register-tables.table.integration.spec.js#hold
        an enforcement once per obligation and cause (enforcements_cause_uq) and
        an adjustment once per document (financial_adjustments_document_uq)
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#plans
        the memo, the fee, the credit from the freed money, its application to
        the fee and the refund of the remainder, in that order, each under its
        key
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#plans
        the memo alone for a line never paid, the fee invoice beside it when the
        terms charge one, and nothing without an invoice
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#treats
        a zero fee as no fee
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#applies
        the freed money to an amendment’s new invoice before the remainder (11
        §7.1, P7): a credit and its application by invoice id, then the credit
        of what is left
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-planning.spec.js#spells
        every key commerce:{document_kind}:{document_id}:{step}
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#plans
        the five steps of 04 §6 in order with their keys: the memo, the fee, the
        credit from the freed money, its application, the refund of the
        remainder
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#leaves
        the step submitted when the command throws, and the resume re-sends the
        same key
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#leaves
        a retryable refusal pending for the next run, with the attempt counted
        and no exception
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#stops
        at the refund: the four steps before it succeeded, the refund failed,
        the adjustment failed with adjustment_failed raised
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#is
        held pending at the processor, never failed, however many times it is
        asked again, with no exception
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#completes
        with the refund’s reference when the refund has settled
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/adjustments/adjustment-worker.integration.spec.js#fails
        for Finance, with its exception, when the refund then fails at the
        processor
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/facts/financial-facts-handler.integration.spec.js#holds
        the refund pending at the processor, not failed, and counts no failed
        attempt (COMM-M1 R7-2)
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/adjustment-pending-at-processor.spec.js#is
        true when the books are done and only the refund is pending at the
        processor
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#lists
        the order’s adjustments and the failed ones, answers one with its steps,
        and refuses a query naming neither an order nor a state
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#retries
        the failed adjustment on its route: the refund alone re-sent, completed;
        a reader is refused
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#resolves
        the other failed adjustment offline on its route, with its exception,
        and refuses a repeat
      - >-
        services-commerce:modules/operations/tests/integration/services/interventions/operations-interventions.integration.spec.js#retries
        the failed adjustment: resumed from the refund alone, completed, its
        exception resolved; a completed one is refused
      - >-
        services-commerce:modules/operations/tests/integration/services/interventions/operations-interventions.integration.spec.js#resolves
        the other failed adjustment offline, with its exception; a resolved one
        is refused
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#sends
        the credit memo to POST /credit_memos/{tenantId} with the key twice, the
        lines as money, and answers the memo’s id
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#sends
        every memo line’s quantity as Accounting’s contract has it, a decimal
        string (0230: a number was refused 400)
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#sends
        the fee invoice issued at once under the commerce source, the credit
        from the payment, its application and the refund executed, each to its
        route
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#answers
        a refusal as failed with Accounting’s code, retryable for the refusals a
        later attempt may change and permanent for a decline
      - >-
        services-commerce:modules/fulfillment/tests/unit/adjustments/accounting-adjustment-commands.spec.js#throws
        when Accounting answers a server error or a document without an id, so
        the step stays submitted for the resume
  - repository: react-console
    tests: []
---

# Complete the financial work requested by a post-sale document: Acceptance Test Set

## Coverage

| Rule | Acceptance Scenarios |
|---|---|
| `BR-CAP-COM-FUL-007-01` | `ATS-COM-FUL-007-01` |
| `BR-CAP-COM-FUL-007-02` | `ATS-COM-FUL-007-02` |
| `BR-CAP-COM-FUL-007-03` | `ATS-COM-FUL-007-02` |
| `BR-CAP-COM-FUL-007-04` | `ATS-COM-FUL-007-03` |
| `BR-CAP-COM-FUL-007-05` | `ATS-COM-FUL-007-03` |
| `BR-CAP-COM-FUL-007-06` | `ATS-COM-FUL-007-04` |
| `BR-CAP-COM-FUL-007-07` | Not required for approval |
| `BR-CAP-COM-FUL-007-08` | `ATS-COM-FUL-007-05` |
| `BR-CAP-COM-FUL-007-09` | `ATS-COM-FUL-007-05` |
| `BR-CAP-COM-FUL-007-10` | `ATS-COM-FUL-007-05` |
| `BR-CAP-COM-FUL-007-11` | `ATS-COM-FUL-007-06` |
| `BR-CAP-COM-FUL-007-12` | Not required for approval |
