---
id: ATS-COM-FUL-016
scope: CAP-COM-FUL-016
product_area: commerce
module: fulfillment
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-COM-FUL-016-01
    title: Warehouse identities and priorities remain stable
    level: api
    proves:
      - BR-CAP-COM-FUL-016-01
      - BR-CAP-COM-FUL-016-02
    preconditions: Two warehouses have priorities and a third has none.
    steps: 'Attempt duplicate identity and negative priority, then list warehouses.'
    expected: Invalid creation fails and the list orders priorities before unset values.
    negative: true
    data_needs: Fixtures for warehouse identities and priorities remain stable.
    bound_to:
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#writes
        the warehouse under the id its name suggests, with its address, at
        version 1, and reads it back the same
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#refuses
        a second warehouse under one id (400) and a negative priority (400)
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#lists
        the warehouses in allocation order (priority first, none last), the
        active ones alone on request, and by search
      - >-
        services-commerce:modules/inventory/tests/integration/db/inventory-tables.table.integration.spec.js#refuses
        an id that is not a configuration id, by
        warehouses_id_configuration_id_check, and a negative priority by
        warehouses_fulfillment_priority_check
      - TST-COM-FUL-060
      - TST-COM-FUL-059
    provenance: test
    source: >-
      services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#writes
      the warehouse under the id its name suggests, with its address, at version
      1, and reads it back the same
    category: validation
  - id: ATS-COM-FUL-016-02
    title: In-use places resist deletion and stale replacement
    level: api
    proves:
      - BR-CAP-COM-FUL-016-03
      - BR-CAP-COM-FUL-016-06
    preconditions: A warehouse owns a location containing stock.
    steps: >-
      Try stale replacement and dependent deletions, then remove dependencies
      and delete.
    expected: Stale and in-use actions fail; dependency-free deletion succeeds.
    negative: true
    data_needs: Fixtures for in-use places resist deletion and stale replacement.
    bound_to:
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#reads
        the warehouse made with the shelf, lists it, replaces it at the version
        read (a stale one 409) and refuses its delete while locations belong to
        it (409)
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#replaces
        the warehouse at its version (a stale one 409; another tenant’s 404)
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#refuses
        deleting a warehouse its locations belong to (409) and a location an
        item is held at (409); deletes them once free, 404 after
      - >-
        services-commerce:modules/inventory/tests/integration/db/inventory-tables.table.integration.spec.js#refuses
        deleting a warehouse its locations and items still name (RESTRICT), by
        one of its warehouse keys
      - TST-COM-FUL-057
      - TST-COM-FUL-060
      - TST-COM-FUL-059
    provenance: test
    source: >-
      services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#reads
      the warehouse made with the shelf, lists it, replaces it at the version
      read (a stale one 409) and refuses its delete while locations belong to it
      (409)
    category: concurrency
  - id: ATS-COM-FUL-016-03
    title: Location validation preserves its warehouse and code
    level: api
    proves:
      - BR-CAP-COM-FUL-016-04
    preconditions: A warehouse and location fixtures exist.
    steps: >-
      Try duplicate code, unknown kind, foreign ownership and moving an existing
      location.
    expected: Invalid changes fail and an omitted kind defaults to bin.
    negative: true
    data_needs: Fixtures for location validation preserves its warehouse and code.
    bound_to:
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#writes
        the location in its warehouse with the kind given (bin by default), at
        version 1
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#refuses
        a code twice in one warehouse (400), a warehouse the tenant has not
        (400), and a kind outside the six (400)
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#replaces
        the location at its version, keeps it in its warehouse (409 to move it),
        and refuses a stale version
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#creates
        a location (a code twice in one warehouse 400), lists the bins in pick
        order, replaces one (its warehouse stays, 409), and deletes a free one
        (404 after)
      - TST-COM-FUL-060
      - TST-COM-FUL-057
    provenance: test
    source: >-
      services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#writes
      the location in its warehouse with the kind given (bin by default), at
      version 1
    category: validation
  - id: ATS-COM-FUL-016-04
    title: Sellable-location selection follows warehouse and pick order
    level: api
    proves:
      - BR-CAP-COM-FUL-016-05
    preconditions: Two warehouses contain bins and restricted locations.
    steps: Read the sellable allocation locations.
    expected: >-
      Eligible bins appear in warehouse and pick-priority order, excluding
      quarantine and returns.
    negative: false
    data_needs: Fixtures for sellable-location selection follows warehouse and pick order.
    bound_to:
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#answers
        the sellable locations across warehouses in allocation order: the main
        warehouse (priority 1) before the depot (2), bins by pick priority,
        quarantine and returns left out
      - TST-COM-FUL-060
    provenance: test
    source: >-
      services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#answers
      the sellable locations across warehouses in allocation order: the main
      warehouse (priority 1) before the depot (2), bins by pick priority,
      quarantine and returns left out
    category: rule
  - id: ATS-COM-FUL-016-05
    title: Inventory configuration access remains scoped
    level: api
    proves:
      - BR-CAP-COM-FUL-016-07
    preconditions: 'Reader, denied and absent identities and a second workspace are available.'
    steps: Try scoped reads and writes for each.
    expected: >-
      Readers can inspect only; denied or absent access fails and foreign
      records are unavailable.
    negative: true
    data_needs: Fixtures for inventory configuration access remains scoped.
    bound_to:
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#lets
        a reader list and read everything, and refuses it every write 403
        permission_missing
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#refuses
        a principal denied the application 403 app_not_permitted, no context
        401, and answers 404 in tenant B for tenant A’s warehouse
      - TST-COM-FUL-057
    provenance: test
    source: >-
      services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#lets a
      reader list and read everything, and refuses it every write 403
      permission_missing
    category: permission
  - id: ATS-COM-FUL-016-06
    title: An inactive warehouse refuses receipt and allocation
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-FUL-018-01
      - INV-DOM-COM-FUL-005-12
    exercises:
      - CAP-COM-FUL-016
      - CAP-COM-FUL-017
      - CAP-COM-FUL-018
    relies_on:
      - ATS-COM-FUL-016-05
      - ATS-COM-FUL-017-01
      - ATS-COM-FUL-018-01
    preconditions: The only sellable location belongs to an inactive warehouse.
    steps: >-
      Attempt a receipt and a placement claim, then repeat after authorized
      activation.
    expected: >-
      Inactive-place work is refused; active-place work is considered under its
      normal stock guards.
    negative: false
    data_needs: >-
      An isolated workspace with the products, records, authority and quantities
      described in the preconditions.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#lets
        a reader list and read everything, and refuses it every write 403
        permission_missing
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#moves
        quarantined beside on_hand and a scrap off it; refuses what the shelf
        cannot bear (400 naming the rule), a wrong sign (400) and a type staff
        do not record (400)
      - >-
        services-commerce:modules/inventory/tests/integration/services/stock/merchandise-claims.integration.spec.js#answers
        ok with one committed claim for the SKU and the quantity, under the
        claim ref the line is stamped with
  - id: ATS-COM-FUL-016-07
    title: Place ordering controls the units claimed from received stock
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-FUL-016-05
      - BR-CAP-COM-FUL-017-01
      - BR-CAP-COM-FUL-018-01
    exercises:
      - CAP-COM-FUL-016
      - CAP-COM-FUL-017
      - CAP-COM-FUL-018
    relies_on:
      - ATS-COM-FUL-016-04
      - ATS-COM-FUL-017-01
      - ATS-COM-FUL-018-01
    preconditions: >-
      Two active sellable bins have different pick priorities and receive the
      same SKU.
    steps: >-
      Receive stock in both and claim two units, then inspect their item and
      location references.
    expected: The claim uses the earlier sellable location before the later one.
    negative: false
    data_needs: >-
      An isolated workspace with the products, records, authority and quantities
      described in the preconditions.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#answers
        the sellable locations across warehouses in allocation order: the main
        warehouse (priority 1) before the depot (2), bins by pick priority,
        quarantine and returns left out
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#moves
        quarantined beside on_hand and a scrap off it; refuses what the shelf
        cannot bear (400 naming the rule), a wrong sign (400) and a type staff
        do not record (400)
      - >-
        services-commerce:modules/inventory/tests/integration/services/stock/merchandise-claims.integration.spec.js#answers
        ok with one committed claim for the SKU and the quantity, under the
        claim ref the line is stamped with
  - id: ATS-COM-FUL-016-08
    title: Imported opening stock participates in the normal ledger
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-FUL-020-12
      - BR-CAP-COM-FUL-017-03
    exercises:
      - CAP-COM-FUL-020
      - CAP-COM-FUL-017
      - CAP-COM-FUL-016
    relies_on:
      - ATS-COM-FUL-020-09
      - ATS-COM-FUL-017-02
      - ATS-COM-FUL-016-05
    preconditions: >-
      An implementation workspace has a migrated warehouse, location and product
      source identity.
    steps: >-
      Import twelve units with two damaged, read back the source key and inspect
      live balances and movements.
    expected: >-
      The item has ten available units, backed by count and damage entries; an
      inactive destination refuses a new item.
    negative: false
    data_needs: >-
      An isolated workspace with the products, records, authority and quantities
      described in the preconditions.
    bound_to:
      - >-
        services-commerce:modules/data-operations/tests/integration/services/operations/inventory-import.integration.spec.js#opens
        the mug’s item through the ledger: a count correction of twelve and a
        damage of two, so the trigger holds ten available
      - >-
        services-commerce:modules/data-operations/tests/integration/services/operations/inventory-import.integration.spec.js#opens
        the cap’s item under the product’s own SKU at the default location, with
        no movement for a count of nought
      - >-
        services-commerce:modules/data-operations/tests/integration/services/operations/inventory-import.integration.spec.js#refuses
        the same key loaded again as that item’s invalid value, moving nothing
      - >-
        services-commerce:modules/data-operations/tests/integration/services/operations/inventory-import.integration.spec.js#refuses
        an item at an inactive location as that item’s refusal, as the implicit
        creation would
      - TST-COM-FUL-007
    provenance: test
    source:
      - >-
        services-commerce:modules/data-operations/tests/integration/services/operations/inventory-import.integration.spec.js#opens
        the mug’s item through the ledger: a count correction of twelve and a
        damage of two, so the trigger holds ten available
      - >-
        services-commerce:modules/inventory/tests/integration/db/inventory-tables.table.integration.spec.js#refuses
        the application role a balance: UPDATE on on_hand is 42501 (the column
        grant), while its settings are its to change
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#lets
        a reader list and read everything, and refuses it every write 403
        permission_missing
  - id: ATS-COM-FUL-016-09
    title: A configured collection place prevents its removal
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-FUL-016-03
      - BR-CAP-COM-FUL-010-05
    exercises:
      - CAP-COM-FUL-016
      - CAP-COM-FUL-010
    relies_on:
      - ATS-COM-FUL-016-02
      - ATS-COM-FUL-010-03
    preconditions: An active warehouse is referenced by a pickup strategy.
    steps: >-
      Attempt to delete the warehouse, remove the strategy and retry deletion
      after clearing other dependencies.
    expected: The first deletion fails; dependency-free deletion succeeds.
    negative: false
    data_needs: >-
      An isolated workspace with the products, records, authority and quantities
      described in the preconditions.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#reads
        the warehouse made with the shelf, lists it, replaces it at the version
        read (a stale one 409) and refuses its delete while locations belong to
        it (409)
      - >-
        services-commerce:modules/shipping/tests/integration/services/persistence/shipping-configuration.integration.spec.js#holds
        the rules before the row: bands in ascending order with the open one
        last, a carrier naming its account, no bands on a flat one
evidence:
  - repository: services-commerce
    tests:
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#writes
        the warehouse under the id its name suggests, with its address, at
        version 1, and reads it back the same
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#refuses
        a second warehouse under one id (400) and a negative priority (400)
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#lists
        the warehouses in allocation order (priority first, none last), the
        active ones alone on request, and by search
      - >-
        services-commerce:modules/inventory/tests/integration/db/inventory-tables.table.integration.spec.js#refuses
        an id that is not a configuration id, by
        warehouses_id_configuration_id_check, and a negative priority by
        warehouses_fulfillment_priority_check
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#reads
        the warehouse made with the shelf, lists it, replaces it at the version
        read (a stale one 409) and refuses its delete while locations belong to
        it (409)
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#replaces
        the warehouse at its version (a stale one 409; another tenant’s 404)
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#refuses
        deleting a warehouse its locations belong to (409) and a location an
        item is held at (409); deletes them once free, 404 after
      - >-
        services-commerce:modules/inventory/tests/integration/db/inventory-tables.table.integration.spec.js#refuses
        deleting a warehouse its locations and items still name (RESTRICT), by
        one of its warehouse keys
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#writes
        the location in its warehouse with the kind given (bin by default), at
        version 1
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#refuses
        a code twice in one warehouse (400), a warehouse the tenant has not
        (400), and a kind outside the six (400)
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#replaces
        the location at its version, keeps it in its warehouse (409 to move it),
        and refuses a stale version
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#creates
        a location (a code twice in one warehouse 400), lists the bins in pick
        order, replaces one (its warehouse stays, 409), and deletes a free one
        (404 after)
      - >-
        services-commerce:modules/inventory/tests/integration/services/persistence/inventory-configuration.integration.spec.js#answers
        the sellable locations across warehouses in allocation order: the main
        warehouse (priority 1) before the depot (2), bins by pick priority,
        quarantine and returns left out
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#lets
        a reader list and read everything, and refuses it every write 403
        permission_missing
      - >-
        services-commerce:modules/inventory/tests/e2e/inventory.e2e.spec.js#refuses
        a principal denied the application 403 app_not_permitted, no context
        401, and answers 404 in tenant B for tenant A’s warehouse
  - repository: react-console
    tests: []
coverage:
  rule: covered
  transition: 'gap: FND-COM-FUL-071'
  validation: covered
  permission: covered
  edge: 'gap: FND-COM-FUL-071'
  failure: 'gap: FND-COM-FUL-071'
  boundary: 'gap: FND-COM-FUL-071'
  concurrency: covered
  invariant: 'gap: FND-COM-FUL-071'
  interaction: covered
coverage_notes:
  transition: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  edge: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  failure: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  boundary: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  invariant: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
transition_audit: []
permission_audit:
  - key: commerce.inventory.read
    where_checked: api
    coverage: 'gap: FND-COM-FUL-071'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.inventory.create
    where_checked: api
    coverage: 'gap: FND-COM-FUL-071'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.inventory.update
    where_checked: api
    coverage: 'gap: FND-COM-FUL-071'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.inventory.delete
    where_checked: api
    coverage: 'gap: FND-COM-FUL-071'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
related_audit:
  - capability: CAP-COM-FUL-017
    scenarios:
      - ATS-COM-FUL-016-06
      - ATS-COM-FUL-016-07
      - ATS-COM-FUL-016-08
  - capability: CAP-COM-FUL-018
    scenarios:
      - ATS-COM-FUL-016-06
      - ATS-COM-FUL-016-07
  - capability: CAP-COM-FUL-010
    scenarios:
      - ATS-COM-FUL-016-09
invariant_audit:
  - invariant: INV-DOM-COM-FUL-005-01
    scenarios:
      - ATS-COM-FUL-017-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/inventory/db/inventory-items.table.ts (column
      grants, apply_inventory_movement, apply_inventory_allocation)
  - invariant: INV-DOM-COM-FUL-005-02
    scenarios:
      - ATS-COM-FUL-017-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/inventory/db/inventory-items.table.ts:inventory_items_balances_check
  - invariant: INV-DOM-COM-FUL-005-03
    scenarios:
      - ATS-COM-FUL-017-01
      - ATS-COM-FUL-017-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/inventory/db/inventory-movements.table.ts:inventory_movements_quantity_sign_check
  - invariant: INV-DOM-COM-FUL-005-04
    scenarios:
      - ATS-COM-FUL-017-03
    coverage: covered
    provenance: documented
    source: 'services-commerce:docs/migrations/inventory/README.md#D-P8I-22'
  - invariant: INV-DOM-COM-FUL-005-05
    scenarios:
      - ATS-COM-FUL-018-05
    coverage: covered
    provenance: observed
    source: 'services-commerce:modules/inventory/db/inventory-allocations.table.ts'
  - invariant: INV-DOM-COM-FUL-005-06
    scenarios:
      - ATS-COM-FUL-018-03
    coverage: covered
    provenance: documented
    source: 'services-commerce:docs/migrations/inventory/README.md#D-P8I-21'
  - invariant: INV-DOM-COM-FUL-005-07
    scenarios:
      - ATS-COM-FUL-014-01
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-allocations.ts:shipUnits
  - invariant: INV-DOM-COM-FUL-005-08
    scenarios:
      - ATS-COM-FUL-017-05
    coverage: covered
    provenance: observed
    source: 'services-commerce:modules/inventory/services/stock/transfer-stock.ts'
  - invariant: INV-DOM-COM-FUL-005-09
    scenarios:
      - ATS-COM-FUL-017-04
    coverage: covered
    provenance: observed
    source: 'services-commerce:modules/inventory/services/stock/staff-movements.ts'
  - invariant: INV-DOM-COM-FUL-005-10
    scenarios:
      - ATS-COM-FUL-019-01
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/inventory-counts.ts:completeCount
  - invariant: INV-DOM-COM-FUL-005-11
    scenarios:
      - ATS-COM-FUL-019-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/inventory/db/inventory-exceptions.table.ts:inventory_exceptions_open_uidx
  - invariant: INV-DOM-COM-FUL-005-12
    scenarios:
      - ATS-COM-FUL-016-06
      - ATS-COM-FUL-017-09
      - ATS-COM-FUL-018-12
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/inventory/services/persistence/warehouses.ts;
      inventory-locations.ts
---

# Organize warehouses and stock locations: Capability Test Specification

## Coverage

The category map distinguishes available cases from missing proof. A covered category has a scenario; the lifecycle and permission audits retain gaps in exhaustive coverage. Proposed cases describe the intended verification and carry no execution result.

| Rule | Scenarios |
|---|---|
| `BR-CAP-COM-FUL-016-01` | `ATS-COM-FUL-016-01` |
| `BR-CAP-COM-FUL-016-02` | `ATS-COM-FUL-016-01` |
| `BR-CAP-COM-FUL-016-03` | `ATS-COM-FUL-016-02`, `ATS-COM-FUL-016-09` |
| `BR-CAP-COM-FUL-016-04` | `ATS-COM-FUL-016-03` |
| `BR-CAP-COM-FUL-016-05` | `ATS-COM-FUL-016-04`, `ATS-COM-FUL-016-07` |
| `BR-CAP-COM-FUL-016-06` | `ATS-COM-FUL-016-02`, `ATS-COM-FUL-016-09` |
| `BR-CAP-COM-FUL-016-07` | `ATS-COM-FUL-016-05`, `ATS-COM-FUL-016-06`, `ATS-COM-FUL-016-08` |

## Interactions With Related Capabilities

The interaction cases exercise keep stock movements and transfers accountable; allocate stock and explain what buyers can obtain; configure shipping coverage and collection options. They vary the upstream record or outcome and inspect the resulting work across the capability boundary. Workflow crossings also include stock, financial or application records when the flow depends on them. Existing test bindings retain their source anchors so a reviewer can distinguish supporting assertions from a complete workflow run.
