---
id: CAP-COM-FUL-015
title: Process returned goods through inspection and disposition
feature: FEAT-COM-FUL-03
product_area: commerce
module: fulfillment
revision: 1
status: draft
product_intent: proposed
implementation_evidence: partially-observed
supersedes:
  - CAP-COM-SHP-018
  - CAP-COM-SHP-019
  - CAP-COM-SHP-020
  - CAP-COM-SHP-021
  - CAP-COM-SHP-022
  - CAP-COM-SHP-032
  - CAP-COM-REG-044
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
intent_sources: []
purpose: Warehouse staff account for returned goods and their agreed treatment.
outcomes:
  - Staff disposition determines which returned goods become sellable.
  - Return financial work follows its configured physical milestones.
concepts:
  - CON-COM-FUL-004
  - CON-COM-FUL-005
actors:
  - ACT-COM-010
surfaces:
  - api
preconditions: []
postconditions: []
permissions:
  - key: commerce.return-receipts.read
    where_checked: api
    scope: tenant
  - key: commerce.return-receipts.create
    where_checked: api
    scope: tenant
  - key: commerce.return-receipts.update
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-COM-FUL-015-01
    proved_by: [ATS-COM-FUL-015-01, TST-COM-FUL-074, TST-COM-FUL-082]
    statement: >-
      Receipt against a return authorization is idempotent under its receipt
      key, with retries returning the recorded receipt without stock movement.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#answers
      the retried receipt as the one recorded, moving nothing
    origin: none
  - id: BR-CAP-COM-FUL-015-02
    proved_by: [ATS-COM-FUL-015-01, TST-COM-FUL-074, TST-COM-FUL-082]
    statement: >-
      Receiving rejects quantities above each line's remaining authorization and
      rejects additional receipts on completed returns.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#refuses
      more than the line has left authorized (receipt_exceeds_authorized),
      writing no receipt
    origin: none
  - id: BR-CAP-COM-FUL-015-03
    proved_by: [ATS-COM-FUL-015-02, TST-COM-FUL-082]
    statement: >-
      Receiving advances the return to partially received or received without
      stock movement, requesting money on receipt only when the policy allows it
      and every authorized unit has arrived.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#records
      the first receipt numbered against the RMA at the warehouse, the two units
      counted with the outbound shipment line, the document partially received
      with its RMA, nothing on the shelf and no money yet
    origin: none
  - id: BR-CAP-COM-FUL-015-04
    proved_by: [ATS-COM-FUL-015-03, TST-COM-FUL-076, TST-COM-FUL-082]
    statement: >-
      Inspection records one of five conditions and any discrepancy for each
      received line, marks the receipt inspected once all lines are inspected
      and advances the return to inspecting.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#records
      the inspection on the line and moves the receipt to inspected and the
      document to inspecting
    origin: none
  - id: BR-CAP-COM-FUL-015-05
    proved_by: [ATS-COM-FUL-015-04, ATS-COM-FUL-015-09, ATS-COM-FUL-017-08, ATS-COM-FUL-018-11, TST-COM-FUL-074, TST-COM-FUL-082]
    statement: >-
      Restocking records a return-restock movement at the requested location,
      otherwise the original shipping location or first sellable warehouse
      location, and restores original layer cost.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#restocks
      the two units at the bin they shipped from: the return_restock movement
      naming the disposition, on hand up two, the two reliefs reversed at 1500
      with the restore_cogs fact of 3000
    origin: none
  - id: BR-CAP-COM-FUL-015-06
    proved_by: [ATS-COM-FUL-015-04, TST-COM-FUL-074, TST-COM-FUL-082]
    statement: >-
      Quarantine records restock followed by quarantine movement without
      available stock or restored cost, while scrap and return-to-customer
      dispositions leave stock and cost of goods sold unchanged.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#quarantines
      the damaged unit: return_restock then quarantine_in at the quarantine
      shelf, no cost restored, and the document completes with every unit back
      on the line
    origin: none
  - id: BR-CAP-COM-FUL-015-07
    proved_by: [ATS-COM-FUL-015-05, TST-COM-FUL-079, TST-COM-FUL-082]
    statement: >-
      Disposition rejects quantities above received units, unsupported
      replacements and choices prohibited by the return policy.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#refuses
      a disposition beyond what the line received, a replacement, and a
      disposition the policy does not allow; nothing dispositioned
    origin: none
  - id: BR-CAP-COM-FUL-015-08
    proved_by: [ATS-COM-FUL-007-09, ATS-COM-FUL-015-04, ATS-COM-FUL-015-08, TST-COM-FUL-074, TST-COM-FUL-082]
    statement: >-
      A fully dispositioned receipt permits return completion, with credit memo
      and refund processing after the disposition commit.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/e2e/post-purchase-shipping.e2e.spec.js#dispositions
      one unit restocked and one scrapped in one transaction: the shelf up one,
      the receipt dispositioned, the document completed with the memo and the
      refund for the two (B15, B11)
    origin: none
  - id: BR-CAP-COM-FUL-015-09
    proved_by: [ATS-COM-FUL-013-11, ATS-COM-FUL-015-06, ATS-COM-FUL-015-10, TST-COM-FUL-074, TST-COM-FUL-082]
    statement: >-
      An issued return label creates a one-parcel packed shipment toward the
      warehouse using the outbound account, otherwise an active carrier or
      manual carrier, and withdrawal before receipt cancels and pulls it.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#makes
      the return_label shipment of the three shipped units, packed in one
      parcel, addressed to the warehouse, labelled through UPS from the
      customer’s address
    origin: none
  - id: BR-CAP-COM-FUL-015-10
    proved_by: []
    statement: >-
      Return receipts retain unique numbers and idempotency keys and cannot be
      deleted.
    kind: invariant
    enforced_at:
      - database
    must_prove: false
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/db/return-receiving-tables.table.integration.spec.js#refuses
      a second receipt under the same number and under the same idempotency key,
      by return_receipts_number_uq and return_receipts_idempotency_key_uq
    origin: none
  - id: BR-CAP-COM-FUL-015-11
    proved_by: [ATS-COM-FUL-015-07, TST-COM-FUL-074]
    statement: >-
      Receipt creation, inspection and disposition require their return-receipt
      permissions and reject readers and portal callers.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: observed
    source: 'services-commerce:modules/shipping/aws/api/shipping.routes.ts'
    origin: none
scenarios:
  - id: SC-CAP-COM-FUL-015-01
    given: >-
      Two shirts have an authorized return and a manual incoming-label
      arrangement.
    when: 'Receive and inspect both, then restock one and scrap the other.'
    then: >-
      One unit returns to stock and disposition completes the receipt and return
      financial work.
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/e2e/post-purchase-shipping.e2e.spec.js#dispositions
      one unit restocked and one scrapped in one transaction: the shelf up one,
      the receipt dispositioned, the document completed with the memo and the
      refund for the two (B15, B11)
edge_cases:
  - id: SC-CAP-COM-FUL-015-02
    given: The return is withdrawn before receipt.
    when: Complete withdrawal.
    then: Incoming shipment work is cancelled and its parcel is pulled.
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js#cancels
      the return label shipment (packed at the counter, no label bought yet) and
      pulls its parcel when the return is withdrawn
constraints: []
depends_on:
  - CAP-COM-FUL-014
related:
  - CAP-COM-FUL-007
  - CAP-COM-FUL-017
journeys:
  - JNY-COM-FUL-004
open_questions: []
evidence:
  - repository: services-commerce
    paths:
      - >-
        modules/shipping/tests/integration/services/returns/return-receiving.integration.spec.js
      - modules/shipping/tests/e2e/post-purchase-shipping.e2e.spec.js
      - >-
        modules/shipping/tests/integration/db/return-receiving-tables.table.integration.spec.js
      - modules/shipping/aws/api/shipping.routes.ts
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-CRY-001, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-005, TC-VEN-001, TC-VEN-002, TC-VEN-003, TC-PRV-001, TC-PRV-002]
exercised_by: [FAS-COM-FUL-03-02, FAS-COM-FUL-03-04]
suites: [TST-COM-FUL-074, TST-COM-FUL-076, TST-COM-FUL-079, TST-COM-FUL-082]
---

# Process returned goods through inspection and disposition

## Purpose

Warehouse staff account for returned goods and their agreed treatment.

## How It Works

Staff receive goods against an existing return authorization. They record arrival before deciding what belongs back in sellable stock. Inspection supplies condition and discrepancy information. Disposition determines the stock and cost treatment of each received quantity. Completing the physical work allows the return's financial process to proceed at its configured point. An issued return label uses the shipment and carrier workflow for the incoming parcel. The product should provide receiving and disposition screens that show the remaining authorized and received quantities.

## Relationships

- Record goods leaving with a carrier or collector supplies or consumes related delivery records.
- Complete the financial work requested by a post-sale document supplies or consumes related delivery records.
- Keep stock movements and transfers accountable supplies or consumes related delivery records.
