---
id: ATS-COM-FUL-014
scope: CAP-COM-FUL-014
product_area: commerce
module: fulfillment
revision: 1
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
scenarios:
  - id: ATS-COM-FUL-014-01
    title: Departure changes stock and delivery records atomically
    level: api
    proves:
      - BR-CAP-COM-FUL-014-01
    preconditions: Three units belong to a manifested shipment.
    steps: Confirm carrier handoff.
    expected: >-
      All units ship, one minus-three stock movement is retained, obligations
      complete, cost facts are emitted and order quantities update.
    negative: false
    data_needs: Fixtures for departure changes stock and delivery records atomically.
    bound_to:
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#hands
        off: the line handed to the carrier with its whole quantity shipped, the
        units shipped in the ledger, one shipment movement of minus three on the
        item, three fewer on hand
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#completes
        every unit’s obligation through the register (the allocation as the
        record), and emits one deferred cost relief fact per item
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#writes
        the shipped quantity on the order line, the order’s shipping_summary
        complete, and the order’s history
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#hands
      off: the line handed to the carrier with its whole quantity shipped, the
      units shipped in the ledger, one shipment movement of minus three on the
      item, three fewer on hand
  - id: ATS-COM-FUL-014-02
    title: Unauthorized or repeated departure cannot move stock
    level: api
    proves:
      - BR-CAP-COM-FUL-014-02
      - BR-CAP-COM-FUL-014-03
    preconditions: One shipment lacks obligation authorization and another already left.
    steps: Attempt handoff on both.
    expected: Both fail without movement and their refusals are recorded.
    negative: true
    data_needs: Fixtures for unauthorized or repeated departure cannot move stock.
    bound_to:
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        units_not_authorized, naming the obligation still pending, and moves
        nothing: the unit committed, nothing shipped, the shipment still
        manifested
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#raises
        the handoff_refused finding and writes the refusal on the shipment’s
        history
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        a second handoff of the same shipment (not manifested any more) and
        records the refusal
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
      units_not_authorized, naming the obligation still pending, and moves
      nothing: the unit committed, nothing shipped, the shipment still
      manifested
  - id: ATS-COM-FUL-014-03
    title: Cancellation fencing resolves contention with departure
    level: api
    proves:
      - BR-CAP-COM-FUL-014-04
      - BR-CAP-COM-FUL-014-05
    preconditions: A manifested shipment contains a unit selected for cancellation.
    steps: Fence before handoff and separately race cancellation against departure.
    expected: >-
      The fence blocks shipment; the race has one successful action and departed
      goods require return.
    negative: true
    data_needs: Fixtures for cancellation fencing resolves contention with departure.
    bound_to:
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#fences
        the whole range the unit is in (cancellation_pending under
        cancellation:<id>), nothing refused
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        the handoff shipment_cancelled_pull_package, naming the fenced line, and
        moves nothing
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#lets
        the handoff commit, and the cancellation that waited finds the line
        already handed off: refused, nothing fenced
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#answers
        the plan must_return for the unit: shipped, by the row
      - >-
        services-commerce:modules/shipping/tests/e2e/post-purchase-shipping.e2e.spec.js#refuses
        the cancellation of the shipped shirts: rejected, must_return with
        shipment_handed_off (B9)
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#fences
      the whole range the unit is in (cancellation_pending under
      cancellation:<id>), nothing refused
  - id: ATS-COM-FUL-014-04
    title: Retained units use a new shipment after fenced cancellation
    level: api
    proves:
      - BR-CAP-COM-FUL-014-06
    preconditions: A three-unit line is fenced for cancellation of one unit.
    steps: Apply cancellation and create shipment work for the retained quantity.
    expected: >-
      The old line and parcel are pulled with label voiding, and the two
      retained units ship separately.
    negative: false
    data_needs: Fixtures for retained units use a new shipment after fenced cancellation.
    bound_to:
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#cancels
        the fenced line at the cancel step: the units unstamped (still the
        order’s, picked), the label voided and the package pulled, the shipment
        cancelled
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#leaves
        the order’s units free for a new shipment: a second shipment carries
        both again
      - >-
        services-commerce:modules/shipping/tests/e2e/post-purchase-shipping.e2e.spec.js#fences
        and cancels the shipment line, pulls the package and voids the counter
        label, and refuses the handoff asked after (409)
      - >-
        services-commerce:modules/shipping/tests/e2e/post-purchase-shipping.e2e.spec.js#carries
        the two kept units on a new shipment (0..1)
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#cancels
      the fenced line at the cancel step: the units unstamped (still the
      order’s, picked), the label voided and the package pulled, the shipment
      cancelled
  - id: ATS-COM-FUL-014-05
    title: Collection requires collector and authorized staff
    level: api
    proves:
      - BR-CAP-COM-FUL-014-07
      - BR-CAP-COM-FUL-014-08
      - BR-CAP-COM-FUL-014-09
    preconditions: 'A packed pickup, a carrier shipment and a fenced pickup exist.'
    steps: >-
      Try reader handover, missing collector, valid handover, repetition and
      incompatible fixtures.
    expected: >-
      Only valid first collection succeeds with its stock, delivery and cost
      effects.
    negative: true
    data_needs: Fixtures for collection requires collector and authorized staff.
    bound_to:
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#hands
        it over: the lines, the package and the shipment collected with who
        collected it, the whole quantity shipped
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#moves
        the stock as the handoff does: the units shipped, one shipment movement
        of minus two (reason handover), two fewer on hand
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#completes
        the obligations through the register, emits the cost relief fact and
        writes the order’s shipped quantities
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        a second handover (not packed any more) and the cancellation of a
        collected shipment
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        the handover of a pick-up whose line the cancellation fenced,
        shipment_cancelled_pull_package, and moves nothing
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        the handover of a carrier’s shipment operation_not_supported
      - >-
        services-commerce:modules/shipping/tests/e2e/shipping.e2e.spec.js#refuses
        the handover to a reader 403 permission_missing, and one naming nobody
        who collected 400
    provenance: test
    source: >-
      services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#hands
      it over: the lines, the package and the shipment collected with who
      collected it, the whole quantity shipped
evidence:
  - repository: services-commerce
    tests:
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#hands
        off: the line handed to the carrier with its whole quantity shipped, the
        units shipped in the ledger, one shipment movement of minus three on the
        item, three fewer on hand
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#completes
        every unit’s obligation through the register (the allocation as the
        record), and emits one deferred cost relief fact per item
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#writes
        the shipped quantity on the order line, the order’s shipping_summary
        complete, and the order’s history
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        units_not_authorized, naming the obligation still pending, and moves
        nothing: the unit committed, nothing shipped, the shipment still
        manifested
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#raises
        the handoff_refused finding and writes the refusal on the shipment’s
        history
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        a second handoff of the same shipment (not manifested any more) and
        records the refusal
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#fences
        the whole range the unit is in (cancellation_pending under
        cancellation:<id>), nothing refused
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        the handoff shipment_cancelled_pull_package, naming the fenced line, and
        moves nothing
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#lets
        the handoff commit, and the cancellation that waited finds the line
        already handed off: refused, nothing fenced
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#answers
        the plan must_return for the unit: shipped, by the row
      - >-
        services-commerce:modules/shipping/tests/e2e/post-purchase-shipping.e2e.spec.js#refuses
        the cancellation of the shipped shirts: rejected, must_return with
        shipment_handed_off (B9)
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#cancels
        the fenced line at the cancel step: the units unstamped (still the
        order’s, picked), the label voided and the package pulled, the shipment
        cancelled
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#leaves
        the order’s units free for a new shipment: a second shipment carries
        both again
      - >-
        services-commerce:modules/shipping/tests/e2e/post-purchase-shipping.e2e.spec.js#fences
        and cancels the shipment line, pulls the package and voids the counter
        label, and refuses the handoff asked after (409)
      - >-
        services-commerce:modules/shipping/tests/e2e/post-purchase-shipping.e2e.spec.js#carries
        the two kept units on a new shipment (0..1)
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#hands
        it over: the lines, the package and the shipment collected with who
        collected it, the whole quantity shipped
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#moves
        the stock as the handoff does: the units shipped, one shipment movement
        of minus two (reason handover), two fewer on hand
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#completes
        the obligations through the register, emits the cost relief fact and
        writes the order’s shipped quantities
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        a second handover (not packed any more) and the cancellation of a
        collected shipment
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        the handover of a pick-up whose line the cancellation fenced,
        shipment_cancelled_pull_package, and moves nothing
      - >-
        services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#refuses
        the handover of a carrier’s shipment operation_not_supported
      - >-
        services-commerce:modules/shipping/tests/e2e/shipping.e2e.spec.js#refuses
        the handover to a reader 403 permission_missing, and one naming nobody
        who collected 400
---

# Record goods leaving with a carrier or collector: Acceptance Test Set

## Coverage

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