---
id: ATS-COM-ORD-004
scope: CAP-COM-ORD-004
product_area: commerce
module: orders
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-COM-ORD-004-01
    title: Equivalent entered codes identify one offer
    level: api
    proves:
      - BR-CAP-COM-ORD-004-01
    preconditions: The fixture defines the displayed early-bird code.
    steps:
      - do: Enter case and spacing variants including full-width text.
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#applies the one code to each,
          full-width letters and an ideographic space included (D-REC-12), shown by its display code, the
          entered code kept as typed (trimmed at the boundary)
    expected: Each resolves to the same code while retaining the trimmed entered form.
    negative: false
    data_needs: Use the controlled records and transports established by the cited tests.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#applies the one code to each,
        full-width letters and an ideographic space included (D-REC-12), shown by its display code, the
        entered code kept as typed (trimmed at the boundary)
      - TST-COM-ORD-038
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#applies the one code to each,
      full-width letters and an ideographic space included (D-REC-12), shown by its display code, the entered
      code kept as typed (trimmed at the boundary)
    category: validation
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#applies the one code to each,
      full-width letters and an ideographic space included (D-REC-12), shown by its display code, the entered
      code kept as typed (trimmed at the boundary)
  - id: ATS-COM-ORD-004-02
    title: Unsupported code text is rejected at the boundary
    level: api
    proves:
      - BR-CAP-COM-ORD-004-02
    preconditions: An editable cart is available.
    steps:
      - do: 'Submit slash, percent, backslash, unusual letter, emoji, NUL and blank cases from the bindings.'
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#refuses a
          code with a slash and a percent sign, 400, with the sentence (D-REC-6)
    expected: The response explains validation failure and retains no invalid code.
    negative: true
    data_needs: Use the controlled records and transports established by the cited tests.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#refuses a
        code with a slash and a percent sign, 400, with the sentence (D-REC-6)
      - >-
        services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#refuses a
        code holding a NUL character, 400, where the database would refuse the text as a 500
      - >-
        services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#refuses a
        code with no character that counts, 400
      - 'services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses a code of emoji, 400'
      - TST-COM-ORD-022
      - TST-COM-ORD-038
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#refuses a code
      with a slash and a percent sign, 400, with the sentence (D-REC-6)
    category: boundary
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#refuses a code
      with a slash and a percent sign, 400, with the sentence (D-REC-6)
  - id: ATS-COM-ORD-004-03
    title: Repeated promotion entry leaves the first use intact
    level: api
    proves:
      - BR-CAP-COM-ORD-004-03
    preconditions: An early-bird code is already entered.
    steps:
      - do: Enter it again and enter another code for the same promotion.
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses the same code entered
          again, 409 already_applied with the customer’s message
    expected: The response identifies already_applied and history records the rejected entry.
    negative: true
    data_needs: Use the controlled records and transports established by the cited tests.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses the same code entered
        again, 409 already_applied with the customer’s message
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#records the refusal on the trail
        as checkout.promotion_code_rejected, already_applied
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#rejects a second code of the same
        promotion already_applied, the first still applied
      - TST-COM-ORD-038
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses the same code entered again,
      409 already_applied with the customer’s message
    category: edge
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses the same code entered again,
      409 already_applied with the customer’s message
  - id: ATS-COM-ORD-004-04
    title: A non-qualifying code is recorded without a saving
    level: api
    proves:
      - BR-CAP-COM-ORD-004-04
    preconditions: A merchandise offer is entered on a membership-only purchase.
    steps:
      - do: Preview and place that cart.
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#rejects the code
          nothing_qualifies, with the customer’s message, and takes nothing off
    expected: The order remains at full price with a rejected-code reason and no redemption.
    negative: true
    data_needs: Use the controlled records and transports established by the cited tests.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#rejects the code
        nothing_qualifies, with the customer’s message, and takes nothing off
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#places the order at the full
        price, the code not applied
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#keeps the code on the order’s
        pricing snapshot as not applied, with its reason
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#writes no redemption and leaves
        the uses unchanged
      - TST-COM-ORD-038
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#rejects the code nothing_qualifies,
      with the customer’s message, and takes nothing off
    category: validation
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#rejects the code nothing_qualifies,
      with the customer’s message, and takes nothing off
  - id: ATS-COM-ORD-004-05
    title: A zero-value second discount consumes no use
    level: api
    proves:
      - BR-CAP-COM-ORD-004-05
    preconditions: An item first receives a full-value promotion and then another percentage code.
    steps:
      - do: Preview and place with both entries.
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#previews TENTH as giving
          nothing, FREEALL taking the whole $100.00
    expected: The first offer supplies the saving; the second remains unapplied and has no use count.
    negative: false
    data_needs: Use the controlled records and transports established by the cited tests.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#previews TENTH as giving nothing,
        FREEALL taking the whole $100.00
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#keeps TENTH on the order as not
        applied, with its reason
      - 'services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#consumes no use of TENTH'
      - TST-COM-ORD-038
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#previews TENTH as giving nothing,
      FREEALL taking the whole $100.00
    category: edge
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#previews TENTH as giving nothing,
      FREEALL taking the whole $100.00
  - id: ATS-COM-ORD-004-06
    title: Only placement records the redemption
    level: api
    proves:
      - BR-CAP-COM-ORD-004-06
    preconditions: A qualifying registration carries an applied early-bird code.
    steps:
      - do: Preview repeatedly and then place.
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#records the redemption applied
          with one allocation of 2500
    expected: Previews do not consume a use; placement records one redemption and one code and promotion use.
    negative: false
    data_needs: Use the controlled records and transports established by the cited tests.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#records the redemption applied
        with one allocation of 2500
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#takes one use of the code and of
        the promotion
      - TST-COM-ORD-038
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#records the redemption applied with
      one allocation of 2500
    category: transition
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#records the redemption applied with
      one allocation of 2500
  - id: ATS-COM-ORD-004-07
    title: Restricted offers fail closed when eligibility is unresolved
    level: api
    proves:
      - BR-CAP-COM-ORD-004-07
    preconditions: 'Fixtures cover matching-only, non-matching-only and indeterminate rules.'
    steps:
      - do: Preview and place as qualifying and non-qualifying purchasers.
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#applies to the
          member: the preview carries it and no rejection
    expected: >-
      The appropriate restricted offers apply, while refusal or indeterminate results prevent their redemption
      and placement rechecks them.
    negative: false
    data_needs: Use the controlled records and transports established by the cited tests.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#applies to the member:
        the preview carries it and no rejection
      - >-
        services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#rejects it in the
        preview as purchaser_not_eligible, with the customer’s sentence
      - >-
        services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#admits the buyer who
        does not match the rule: applied in the preview, placed with the discount
      - >-
        services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#rolls everything back:
        no order, no use, the checkout open
      - >-
        services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#refuses it even for
        must_not_match: an indeterminate decision is not "does not match"
      - TST-COM-ORD-037
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#applies to the member:
      the preview carries it and no rejection
    category: failure
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#applies to the member:
      the preview carries it and no rejection
  - id: ATS-COM-ORD-004-08
    title: Portal snapshots omit staff-only explanations
    level: api
    proves:
      - BR-CAP-COM-ORD-004-08
    preconditions: The offer belongs to a different business unit.
    steps:
      - do: Enter it in staff and portal contexts and inspect the returned snapshot.
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#tells the console clerk the
          staff message, which says business unit
    expected: Staff receive the operational explanation; the portal result retains only customer wording.
    negative: false
    data_needs: Use the controlled records and transports established by the cited tests.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#tells the console clerk the staff
        message, which says business unit
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#tells the portal member the
        customer message alone, which does not say business unit
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#keeps the staff message out of the
        price snapshot the portal member reads
      - TST-COM-ORD-038
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#tells the console clerk the staff
      message, which says business unit
    category: permission
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#tells the console clerk the staff
      message, which says business unit
  - id: ATS-COM-ORD-004-09
    title: Removing a code restores the full preview
    category: transition
    level: api
    proves:
      - BR-CAP-COM-ORD-004-09
    preconditions: A cart has an applied discount code.
    steps:
      - do: 'Remove it, read the preview and history, then remove it again.'
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#answers
          404 to the removal of a code the checkout does not carry, naming the code
    expected: 'The full price returns, removal appears once in history and the repeated removal returns 404.'
    negative: false
    data_needs: Use an isolated workspace with the records and responses named in the preconditions.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#re-runs the preview without the
        code: nothing applied, the full price
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#records
        checkout.promotion_code_removed naming the code as it was entered
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses removing a code the
        checkout does not carry, 404
      - TST-COM-ORD-038
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#answers 404 to
      the removal of a code the checkout does not carry, naming the code
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#answers 404 to
      the removal of a code the checkout does not carry, naming the code
  - id: ATS-COM-ORD-004-10
    title: A better exclusive code replaces the automatic saving
    category: rule
    level: api
    proves:
      - BR-CAP-COM-ORD-004-10
    preconditions: The fixture automatic offer prices a shirt at 22.50 dollars.
    steps:
      - do: Apply the inferior code and then the better exclusive code in separate carts; place both.
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/automatic-promotions.e2e.spec.js#lets VIP20 replace the
          automatic promotion when it leaves less to pay: $20.00
    expected: >-
      The inferior code leaves 22.50 dollars due; the better code leaves 20 dollars due and consumes only its
      own offer use.
    negative: false
    data_needs: Use an isolated workspace with the records and responses named in the preconditions.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/automatic-promotions.e2e.spec.js#keeps the automatic
        promotion when VIP5 would leave more to pay: $22.50, VIP5 explained
      - >-
        services-commerce:modules/checkout/tests/e2e/automatic-promotions.e2e.spec.js#lets VIP20 replace the
        automatic promotion when it leaves less to pay: $20.00
      - >-
        services-commerce:modules/checkout/tests/e2e/automatic-promotions.e2e.spec.js#redeems VIP20 and not
        the automatic promotion it replaced
      - TST-COM-ORD-020
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/automatic-promotions.e2e.spec.js#lets VIP20 replace the
      automatic promotion when it leaves less to pay: $20.00
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/automatic-promotions.e2e.spec.js#lets VIP20 replace the
      automatic promotion when it leaves less to pay: $20.00
  - id: ATS-COM-ORD-004-11
    title: A stranger cannot change the cart discount
    category: permission
    level: api
    proves:
      - BR-CAP-COM-ORD-004-11
    preconditions: A member has a cart and another member is signed in.
    steps:
      - do: Submit a code against the first member’s cart.
        provenance: test
        source: >-
          services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses another member entering
          a code on a checkout that is not theirs, 403
    expected: The request returns 403.
    negative: false
    data_needs: Use an isolated workspace with the records and responses named in the preconditions.
    bound_to:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses another member entering a
        code on a checkout that is not theirs, 403
      - TST-COM-ORD-038
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses another member entering a
      code on a checkout that is not theirs, 403
    expected_provenance: test
    expected_source: >-
      services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses another member entering a
      code on a checkout that is not theirs, 403
  - id: ATS-COM-ORD-004-12
    title: A changed promotion verdict rolls back purchase commitment
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-ORD-004-06
      - BR-CAP-COM-ORD-005-08
    preconditions: A reviewed code is eligible but its subject becomes ineligible before placement.
    steps:
      - do: Place the cart and inspect order and redemption records.
        provenance: proposed
        source:
          - >-
            services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#takes one use of the code and
            of the promotion
          - >-
            services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#refuses the
            placement 409 promotion_refused, purchaser_not_eligible
    expected: The request refuses the promotion and retains neither an order nor a redemption.
    negative: false
    data_needs: Use an isolated workspace with the records and responses named in the preconditions.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#takes one use of the code and of
        the promotion
      - >-
        services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#refuses the placement
        409 promotion_refused, purchaser_not_eligible
    exercises:
      - CAP-COM-ORD-004
      - CAP-COM-ORD-005
    related_capabilities:
      - CAP-COM-ORD-005
    expected_provenance: proposed
    expected_source:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#takes one use of the code and of
        the promotion
      - >-
        services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#refuses the placement
        409 promotion_refused, purchaser_not_eligible
  - id: ATS-COM-ORD-004-13
    title: A later code extends the sale’s retained discount history
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-ORD-004-06
      - BR-CAP-COM-ORD-015-07
    preconditions: An accepted sale carries an earlier offer and qualifies for a distinct combinable offer.
    steps:
      - do: Apply the later offer with authorized staff and inspect both allocations and credit.
        provenance: proposed
        source:
          - >-
            services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#takes one use of the code and
            of the promotion
          - >-
            services-commerce:modules/orders/tests/e2e/apply-promotion-amendment.e2e.spec.js#answers 200 with
            the apply_promotion amendment completed, its plan on the document, its net owed to the buyer
    expected: The earlier allocation remains and the later saving has its own amendment and financial adjustment.
    negative: false
    data_needs: Use an isolated workspace with the records and responses named in the preconditions.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#takes one use of the code and of
        the promotion
      - >-
        services-commerce:modules/orders/tests/e2e/apply-promotion-amendment.e2e.spec.js#answers 200 with the
        apply_promotion amendment completed, its plan on the document, its net owed to the buyer
    exercises:
      - CAP-COM-ORD-004
      - CAP-COM-ORD-015
    related_capabilities:
      - CAP-COM-ORD-015
    expected_provenance: proposed
    expected_source:
      - >-
        services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#takes one use of the code and of
        the promotion
      - >-
        services-commerce:modules/orders/tests/e2e/apply-promotion-amendment.e2e.spec.js#answers 200 with the
        apply_promotion amendment completed, its plan on the document, its net owed to the buyer
evidence:
  - >-
    Examined reference:
    services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#refuses a code
    holding a NUL character, 400, where the database would refuse the text as a 500
  - >-
    Examined reference:
    services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#refuses a code
    with a slash and a percent sign, 400, with the sentence (D-REC-6)
  - >-
    Examined reference:
    services-commerce:modules/checkout/tests/e2e/checkout-promotion-code-refusals.e2e.spec.js#refuses a code
    with no character that counts, 400
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#admits
    the buyer who does not match the rule: applied in the preview, placed with the discount
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#applies
    to the member: the preview carries it and no rejection
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#refuses
    it even for must_not_match: an indeterminate decision is not "does not match"
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#rejects
    it in the preview as purchaser_not_eligible, with the customer’s sentence
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotion-eligibility.e2e.spec.js#rolls
    everything back: no order, no use, the checkout open
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#applies the one
    code to each, full-width letters and an ideographic space included (D-REC-12), shown by its display code,
    the entered code kept as typed (trimmed at the boundary)
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#consumes no use of
    TENTH
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#keeps TENTH on the
    order as not applied, with its reason
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#keeps the code on
    the order’s pricing snapshot as not applied, with its reason
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#keeps the staff
    message out of the price snapshot the portal member reads
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#places the order
    at the full price, the code not applied
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#previews TENTH as
    giving nothing, FREEALL taking the whole $100.00
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#records the
    redemption applied with one allocation of 2500
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#records the
    refusal on the trail as checkout.promotion_code_rejected, already_applied
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses a code of
    emoji, 400
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#refuses the same
    code entered again, 409 already_applied with the customer’s message
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#rejects a second
    code of the same promotion already_applied, the first still applied
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#rejects the code
    nothing_qualifies, with the customer’s message, and takes nothing off
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#takes one use of
    the code and of the promotion
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#tells the console
    clerk the staff message, which says business unit
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#tells the portal
    member the customer message alone, which does not say business unit
  - >-
    Examined reference: services-commerce:modules/checkout/tests/e2e/promotions.e2e.spec.js#writes no
    redemption and leaves the uses unchanged
coverage:
  rule: covered
  transition: covered
  validation: covered
  permission: 'gap: FND-COM-ORD-061'
  edge: covered
  failure: covered
  boundary: covered
  concurrency: 'gap: FND-COM-ORD-061'
  invariant: 'gap: FND-COM-ORD-061'
  interaction: covered
coverage_definition: Covered means a design scenario exists; executable coverage and execution results are separate.
permission_coverage:
  - key: commerce.checkouts.update
    where_checked: api
    scenarios:
      - ATS-COM-ORD-004-11
    gap: FND-COM-ORD-061
    note: >-
      The listed examples do not establish a complete allow-and-deny matrix for this key; unused catalogue
      keys need no invented route.
    provenance: unknown
    source: FND-COM-ORD-061
transition_coverage: []
invariant_coverage:
  - invariant: INV-DOM-COM-ORD-001-01
    scenarios: []
    gap: FND-COM-ORD-061
    provenance: unknown
    source: 'services-commerce:modules/checkout/db/checkouts.table.ts:checkouts_placed_order_check'
    note: Broader invariant coverage remains open beyond the concrete examples.
  - invariant: INV-DOM-COM-ORD-001-02
    scenarios: []
    gap: FND-COM-ORD-061
    provenance: unknown
    source: 'services-commerce:modules/checkout/db/checkouts.table.ts:checkouts_placed_order_uq'
    note: Broader invariant coverage remains open beyond the concrete examples.
  - invariant: INV-DOM-COM-ORD-001-03
    scenarios: []
    gap: FND-COM-ORD-061
    provenance: unknown
    source: >-
      services-commerce:modules/checkout/db/checkouts.table.ts:checkouts_currency_check,
      checkouts_ordering_profile_source_check
    note: Broader invariant coverage remains open beyond the concrete examples.
  - invariant: INV-DOM-COM-ORD-001-04
    scenarios: []
    gap: FND-COM-ORD-061
    provenance: unknown
    source: 'services-commerce:modules/checkout/services/persistence/checkouts.ts:CHECKOUT_TRANSITIONS'
    note: Broader invariant coverage remains open beyond the concrete examples.
  - invariant: INV-DOM-COM-ORD-001-05
    scenarios: []
    gap: FND-COM-ORD-061
    provenance: unknown
    source: >-
      services-commerce:modules/checkout/tests/e2e/placement.e2e.spec.js#leaves the checkout placed, naming
      the order, its items frozen with what prepare attested, and its trail telling the story;
      services-commerce:modules/checkout/services/persistence/checkouts.ts:updateCheckout, appendCheckoutEvent
    note: Broader invariant coverage remains open beyond the concrete examples.
  - invariant: INV-DOM-COM-ORD-001-06
    scenarios: []
    gap: FND-COM-ORD-061
    provenance: unknown
    source: 'services-commerce:modules/checkout/db/checkouts.table.ts:checkouts_ship_to_check'
    note: Broader invariant coverage remains open beyond the concrete examples.
  - invariant: INV-DOM-COM-ORD-001-07
    scenarios: []
    gap: FND-COM-ORD-061
    provenance: unknown
    source: 'services-commerce:modules/checkout/tests/e2e/checkout-security.e2e.spec.js'
    note: Broader invariant coverage remains open beyond the concrete examples.
  - invariant: INV-DOM-COM-ORD-001-08
    scenarios: []
    gap: FND-COM-ORD-061
    provenance: unknown
    source: >-
      services-commerce:modules/checkout/db/checkout-items.table.ts:checkout_items_quantity_check;
      modules/checkout/services/checkout/checkout-part-checks.ts
    note: Broader invariant coverage remains open beyond the concrete examples.
workflow_coverage:
  - workflow: WF-COM-ORD-001
    scenarios:
      - ATS-COM-ORD-001-19
    gap: FND-COM-ORD-061
    provenance: proposed
    source:
      - 'services-commerce:modules/checkout/tests/e2e/ordering-profile-resolution.e2e.spec.js'
      - 'services-commerce:modules/checkout/services/checkout/purchasing-roles.ts'
      - >-
        services-commerce:modules/checkout/tests/e2e/holds-and-claims.e2e.spec.js#refuses another buyer the
        booth: 409 hold_unavailable with the participant’s reason, and their preview marks the item
        unavailable
      - 'services-commerce:modules/checkout/tests/e2e/checkout-preprocessing.e2e.spec.js'
      - 'services-commerce:modules/checkout/tests/e2e/participant-unavailable.e2e.spec.js'
      - 'services-commerce:modules/checkout/tests/e2e/product-purchase-eligibility.e2e.spec.js'
      - 'services-commerce:modules/checkout/tests/e2e/accounting-tax.e2e.spec.js'
      - 'services-commerce:modules/checkout/tests/e2e/checkouts.e2e.spec.js'
      - 'services-commerce:modules/checkout/aws/lambda/SWEEPER.ts:handler'
  - workflow: WF-COM-ORD-002
    scenarios:
      - ATS-COM-ORD-005-19
    gap: FND-COM-ORD-061
    provenance: proposed
    source:
      - 'services-commerce:modules/checkout/tests/e2e/placement.e2e.spec.js'
      - >-
        services-commerce:modules/checkout/tests/e2e/holds-and-claims.e2e.spec.js#refuses a placement made
        after the T-shirt was gone with the same 409 claim_conflict, never a preparation refusal
      - 'services-commerce:modules/checkout/tests/e2e/engine-pricing.e2e.spec.js'
      - >-
        services-commerce:modules/checkout/tests/e2e/accounting-tax.e2e.spec.js#is a tax_quote_refused problem
        on the preview and refuses the placement, placing nothing
      - >-
        services-commerce:modules/checkout/tests/e2e/holds-and-claims.e2e.spec.js#rolled the first seat claim
        back with the transaction, and left the booth held for the buyer to retry with
      - >-
        services-commerce:modules/checkout/tests/e2e/holds-and-claims.e2e.spec.js#confirms it on the sweep:
        the ledger committed, the participant’s claim committed, claim_confirmed on the order
      - >-
        services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#leaves the order placed and
        pending with one attempt; the buyer’s tender bills it first and proceeds
  - workflow: WF-COM-ORD-005
    scenarios:
      - ATS-COM-ORD-008-14
    gap: FND-COM-ORD-061
    provenance: proposed
    source:
      - >-
        services-commerce:modules/checkout/tests/e2e/order-void.e2e.spec.js#refuses a second void, 409
        order_not_voidable, and a read answers the order voided
      - 'services-commerce:modules/orders/services/orders/void-refund.ts:voidRefundLegsOf'
      - >-
        services-commerce:modules/checkout/tests/e2e/order-void.e2e.spec.js#released the participant’s claim,
        the ledger and the obligations
      - 'services-commerce:modules/orders/services/orders/void-order.ts:voidOrder'
      - >-
        services-commerce:modules/orders/tests/e2e/billing-and-tender.e2e.spec.js#ran the plan through the
        adjustment worker: the card leg refunded under the void’s key, then the memo of the sale invoice
      - 'services-commerce:modules/fulfillment/services/register/intervention-audit.ts:auditIntervention'
  - workflow: WF-COM-ORD-010
    scenarios:
      - ATS-COM-ORD-014-19
    gap: FND-COM-ORD-061
    provenance: proposed
    source:
      - >-
        services-commerce:modules/orders/tests/e2e/cancellations.e2e.spec.js#refuses a placed order 409
        order_not_cancellable, another member 403 not_your_party, a reader 403 permission_missing, another
        tenant 404
      - >-
        services-commerce:modules/orders/tests/e2e/cancellations.e2e.spec.js#refuses a member on the console
        approve route 403, and a clerk approving 403 permission_missing
      - >-
        services-commerce:modules/orders/tests/e2e/cancellations.e2e.spec.js#fences a DELIVERED seat through
        the participant’s commerce_claim_cancellation, and the participant’s cancel gives the capacity back
      - 'services-commerce:modules/orders/services/cancellations/cancellation-workflow.ts'
      - >-
        services-commerce:modules/orders/services/cancellations/cancellation-settlement.ts:settleCancellationAfterObligation
      - >-
        services-commerce:modules/orders/tests/e2e/cancellations.e2e.spec.js#raises the fee invoice, applies
        the freed money to it and refunds the remainder
      - >-
        services-commerce:modules/orders/tests/e2e/cancellations.e2e.spec.js#shows the cancellation’s credit
        on the order’s money mirror at once, read right after the cancel
  - workflow: WF-COM-ORD-012
    scenarios:
      - ATS-COM-ORD-015-16
    gap: FND-COM-ORD-061
    provenance: proposed
    source:
      - 'services-commerce:modules/orders/tests/e2e/apply-promotion-amendment.e2e.spec.js'
      - 'services-commerce:modules/orders/tests/e2e/promotion-alternatives.e2e.spec.js'
      - 'services-commerce:modules/orders/services/amendments/promotion-amendment.ts'
      - 'services-commerce:modules/orders/services/adjustments/resume-adjustments.ts'
interaction_coverage:
  - with: CAP-COM-ORD-005
    scenarios:
      - ATS-COM-ORD-004-12
  - with: CAP-COM-ORD-015
    scenarios:
      - ATS-COM-ORD-004-13
unproved_rules: []
---

# Use promotion codes before the sale: Capability Test Specification

## Coverage

| Rule | Scenario or finding |
|---|---|
| `BR-CAP-COM-ORD-004-01` | `ATS-COM-ORD-004-01` |
| `BR-CAP-COM-ORD-004-02` | `ATS-COM-ORD-004-02` |
| `BR-CAP-COM-ORD-004-03` | `ATS-COM-ORD-004-03` |
| `BR-CAP-COM-ORD-004-04` | `ATS-COM-ORD-004-04` |
| `BR-CAP-COM-ORD-004-05` | `ATS-COM-ORD-004-05` |
| `BR-CAP-COM-ORD-004-06` | `ATS-COM-ORD-004-06`, `ATS-COM-ORD-004-12`, `ATS-COM-ORD-004-13` |
| `BR-CAP-COM-ORD-004-07` | `ATS-COM-ORD-004-07` |
| `BR-CAP-COM-ORD-004-08` | `ATS-COM-ORD-004-08` |
| `BR-CAP-COM-ORD-004-09` | `ATS-COM-ORD-004-09` |
| `BR-CAP-COM-ORD-004-10` | `ATS-COM-ORD-004-10` |
| `BR-CAP-COM-ORD-004-11` | `ATS-COM-ORD-004-11` |

## Interactions With Related Capabilities

A changed promotion verdict rolls back purchase commitment. A reviewed code is eligible but its subject becomes ineligible before placement. Place the cart and inspect order and redemption records.

A later code extends the sale’s retained discount history. An accepted sale carries an earlier offer and qualifies for a distinct combinable offer. Apply the later offer with authorized staff and inspect both allocations and credit.

Crossing workflow examples also cover preparation, commitment and recovery at their service handoffs. Their structured bindings distinguish specified outcomes from executable evidence.
