Causality APIs 33: Promotion Profit Under Inventory And Margin Constraints

Rocket Vector rocket logo on a dark branded background.

A merchant sees the promotion calendar filling up and the weekly sales report starts to look better. Units move, revenue lifts, and the dashboard marks the campaign green. The harder question arrives later, when finance asks whether the promotion created profitable demand or simply sold low-margin inventory to customers who would have bought anyway.

Share: A promotion can lift sales and still miss profit. Inventory, margin, substitution, returns, and fulfillment cost decide whether the lift is useful. #Causality #RetailAnalytics #Pricing

Synthetic teaching model

This article uses a synthetic retail model. It is not pricing, legal, financial, operational, compliance, or merchandising advice. The sources below justify why some variables belong in the model. The probabilities are invented so the reasoning path is easy to inspect.

The Operating Problem Is Usually Wider Than The Metric

Retail teams rarely run promotions in a clean laboratory. The discount changes conversion, but it can also change margin, basket mix, return behavior, stockout risk, and customer expectations about the next price. A promotion can therefore be operationally successful and economically disappointing at the same time.

Why The Dashboard Can Mislead

The dashboard can mislead because it usually sees the lift before it sees the tradeoff. Incremental demand, margin pressure, stockouts, and cannibalization do not move independently. If a deep discount creates sales while changing which products customers buy, the campaign can look better in gross sales than in contribution profit.

Plain-language modeling note

A Bayesian belief network, or BBN, is a graph for asking conditional questions. Each node is a condition, each arrow says one condition informs another, and each probability is explicit. You do not need to know the SDK to read the graph: the SDK code is only there when we need a repeatable action query.

The Question For This Example

This example asks how a promotion-profit shortfall risk changes after observing a deep-discount, low-margin, tight-inventory case, and what changes if the discount is moderated, targeting improves, and inventory is made adequate.

The target outcome is PromotionProfitShortfall, which means promotion profit shortfall in this teaching model.

A Small Model Of The Situation

The model treats a promotion as a small retail system rather than a single lift number. It leaves out vendor funding, real elasticity estimates, tax, markdown accounting, seasonality, and customer-level heterogeneity.

The graph has 17 nodes:

  • BaselineDemand: Baseline demand (adequate / low)
  • PriceDiscountDepth: Price discount depth (modest / deep)
  • CompetitorPromotion: Competitor promotion (no / yes)
  • InventoryDepth: Inventory depth (adequate / low)
  • ProductMargin: Product margin (adequate / low)
  • TrafficQuality: Traffic quality (good / poor)
  • EmailTargetingQuality: Email targeting quality (good / poor)
  • BasketAttachment: Basket attachment (adequate / low)
  • SubstitutionRisk: Substitution risk (low / high)
  • StockoutRisk: Stockout risk (no / yes)
  • ReturnRate: Return rate (low / high)
  • FulfillmentCost: Fulfillment cost (low / high)
  • CustomerPriceMemory: Customer price memory (low / high)
  • IncrementalDemand: Incremental demand (adequate / low)
  • ContributionMarginPressure: Contribution margin pressure (low / high)
  • CannibalizationRisk: Cannibalization risk (low / high)
  • PromotionProfitShortfall: Promotion profit shortfall (no / yes)

Retail Promotion Profit BBN graph with source-informed retail variables and synthetic probabilities.

What Is Sourced And What Is Synthetic

The sources support the structure, not the numeric probabilities. Deloitte’s retail outlook discusses price-conscious consumers, dynamic pricing, promotions, inventory visibility, and margin pressure. NRF’s AI materials support using analytics in marketing and personalization, while the Q2 Deloitte trends report supports demand, inventory, sourcing, and pricing as connected decisions.

Promotion economics
Deloitte frames retail growth around profitable transactions, value-seeking consumers, dynamic pricing, inventory visibility, and pressure on margins.
Targeting and personalization
NRF and Deloitte both discuss personalization and AI-supported retail decisions, which motivates including targeting quality and traffic quality.
Supply and margin constraints
Retail outlook sources support including inventory and fulfillment cost as constraints on whether a sales lift becomes useful profit.

Boundary of the evidence

The sources support the general mechanisms in the graph. They do not estimate this article’s node states, thresholds, or conditional probability values. Those are synthetic teaching values.

The Query The Graph Cannot Show By Itself

The visual graph is the best way to inspect the structure. The code-backed query is there for a narrower reason: we want to separate what is learned by observing a messy retail case from what changes if one condition is set differently.

Using the Darkstar Python SDK, a subscribed SDK user can load the same BBN JSON, ask for the target probability after evidence is entered, then run the action query by setting a node before querying again. The download includes this as illustrative SDK code, while the standalone query_example.py reproduces the article numbers without shipping the SDK.

import json

from darkstar import DiscreteModel

TARGET = "PromotionProfitShortfall"
OBSERVED_EVIDENCE = {
    "PriceDiscountDepth": "deep",
    "ProductMargin": "low",
    "InventoryDepth": "low",
    "FulfillmentCost": "high"
}
INTERVENTION_CONTEXT = {
    "ProductMargin": "low",
    "FulfillmentCost": "high"
}
INTERVENTION = {
    "PriceDiscountDepth": "modest",
    "EmailTargetingQuality": "good",
    "InventoryDepth": "adequate"
}


def probability_after_observing(model, evidence):
    query = {"nodes": [TARGET], "evidence": evidence}
    result = json.loads(model.pquery(json.dumps(query)))
    return result[TARGET]["yes"]


def probability_after_setting(model, setting, evidence):
    changed_model = model.intervene(json.dumps(setting))
    return probability_after_observing(changed_model, evidence)


with DiscreteModel(model_json) as model:
    observed = probability_after_observing(model, OBSERVED_EVIDENCE)
    acted = probability_after_setting(model, INTERVENTION, INTERVENTION_CONTEXT)

That is the article’s main modeling distinction. Observing a pattern is not the same as setting one part of the system differently.

The standalone query code gives this synthetic result:

Baseline promotion profit shortfall: 23.3%
Observed scenario (deep discount with thin margin and tight inventory): 33.0%
Action scenario (targeted modest discount with adequate inventory): 24.2%
Same context with the action left unfavorable: 34.8%
Synthetic reduction versus the observed scenario: 8.8 percentage points

What We Learn By Observing The Situation

The observed scenario sets:

  • Price discount depth = deep
  • Product margin = low
  • Inventory depth = low
  • Fulfillment cost = high

In the synthetic model, observing a deep discount, low product margin, low inventory depth, and high fulfillment cost moves shortfall risk above baseline. The graph is not saying promotions are bad. It is saying this promotion has the pattern of a campaign whose lift may be expensive.

Reasoning comparison for Retail Promotion Profit BBN.

What Changes If We Set One Condition Differently

The action scenario sets:

  • Price discount depth = modest
  • Email targeting quality = good
  • Inventory depth = adequate

The action query sets the discount to modest, improves targeting quality, and makes inventory adequate. It does not assume competitors disappear or demand becomes easy. It asks whether a more selective promotion with enough supply looks less likely to disappoint on contribution profit.

What This Example Cannot Prove

This model cannot estimate the right discount, replace controlled experiments, or predict a real retailer’s margin. It is a teaching model for why sales lift and profit lift are different causal questions.

Try this in the shared model

Open the companion model, change one upstream condition at a time, and watch the target probability move. Start with the observed scenario above, then reset one condition that looks actionable. The point is to compare stories, not to treat the toy probabilities as a forecast.

Try The Model

Open the companion Darkstar model: Open Retail Promotion Profit BBN

In the shared model, keep the discount deep but improve ProductMargin. Then reset and improve only EmailTargetingQuality. The comparison shows why better targeting cannot always rescue a structurally expensive offer.

Download the teaching package: Retail Promotion Profit BBN ZIP

The ZIP contains the synthetic model JSON, standalone Python query code, illustrative Darkstar Python SDK code, tests, and figures. It does not contain the Darkstar Python SDK, private price data, merchandising files, customer records, or chart-generation code.

Sources

  1. Deloitte: 2025 US Retail Industry Outlook
  2. Deloitte: Q2 2025 Emerging Retail and Consumer Trends
  3. NRF: Retail Trends in AI

Leave a Reply

Discover more from Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading