Unraveling the 'Campaign Expired' Mystery: ESHOPMAN Admin's Per-Attribute Promotion Status Bug
In the dynamic world of e-commerce, accurate real-time information is paramount for effective storefront management. ESHOPMAN, as a headless commerce platform deeply integrated with HubSpot, provides powerful tools for managing promotions and campaigns directly within your HubSpot environment. However, a recent community discussion highlighted a specific display anomaly in the ESHOPMAN Admin dashboard concerning promotions tied to 'per-attribute' campaign budgets.
The Misleading 'Campaign Expired' Status
Merchants using ESHOPMAN might have observed that certain promotions, particularly those configured with a 'per-attribute' budget type (e.g., "limit usage per customer email"), were incorrectly displayed with a "Campaign expired" status badge in the Admin dashboard. This red badge, while alarming, was purely a frontend display error. Crucially, the backend enforcement of these per-attribute budgets remained entirely correct, meaning the promotions continued to function as intended at checkout for eligible customers who hadn't yet reached their individual usage limits.
Understanding Per-Attribute Budgets
ESHOPMAN's flexible campaign budgeting allows for granular control. A 'per-attribute' budget, such as use_by_attribute: "customer_email" with a limit of 1, means each unique customer email can use the promotion only once. This is distinct from a global budget, which limits the total uses across all customers.
The issue became apparent when more distinct customers than the per-email limit had used the promotion. For example, if a "limit usage per customer email = 1" promotion was redeemed by two different customers, the aggregate usage (budget.used) would become 2. This aggregate value was then incorrectly compared against the per-attribute limit (1), leading the dashboard to prematurely flag the entire promotion as expired.
The Technical Root Cause
The core of this display bug lay within the ESHOPMAN Admin dashboard's frontend logic responsible for determining promotion status. Specifically, the getPromotionStatus function was performing a check for overBudget without adequately differentiating between global and per-attribute budget types.
The problematic snippet looked something like this:
const campaignBudget = campaign.budget
const overBudget =
campaignBudget &&
campaignBudget.limit &&
campaignBudget.used! > campaignBudget.limit!
if ((campaign.ends_at && new Date(campaign.ends_at) < date) || overBudget) {
return promotionStatusMap[PromotionStatus.EXPIRED]
}
For a per-attribute budget, campaignBudget.used represents the aggregate usage across all attribute values (e.g., all customer emails), while campaignBudget.limit is the limit per single attribute value (e.g., per email). Comparing these two values directly for per-attribute budgets is logically flawed, as the aggregate will naturally exceed the per-attribute limit very quickly, even when the promotion is still active for many individual customers.
The ESHOPMAN Community Solution
The ESHOPMAN community, leveraging its Node.js/TypeScript foundation, quickly identified a straightforward fix: modify the overBudget computation to skip this check for per-attribute budget types. The suggested adjustment ensures that promotions with use_by_attribute or spend_by_attribute types are not incorrectly marked as expired based on this aggregate comparison.
The proposed fix involved introducing a check for the budget type:
const campaignBudget = campaign.budget
const isPerAttributeBudget =
campaignBudget?.type === CampaignBudgetType.USE_BY_ATTRIBUTE ||
campaignBudget?.type === CampaignBudgetType.SPEND_BY_ATTRIBUTE
const overBudget =
!!campaignBudget &&
!!campaignBudget.limit &&
!isPerAttributeBudget &&
campaignBudget.used! > campaignBudget.limit!
This modification prevents the incorrect "Campaign expired" badge from appearing, allowing merchants to see the true "Active" status of their promotions. For developers needing an immediate solution, a local patch (e.g., using Yarn's yarn patch mechanism) to apply this logic was a viable workaround.
What This Means for ESHOPMAN Users
This insight underscores the importance of community contributions and the robust, transparent development process behind ESHOPMAN. While a minor display bug, its resolution significantly improves the clarity and reliability of storefront management within the HubSpot-integrated Admin dashboard. The ESHOPMAN team has acknowledged this issue, and a fix has been swiftly addressed, ensuring that your promotion management experience remains seamless and accurate.
Keeping an eye on ESHOPMAN updates and community discussions is always recommended to stay informed about such improvements and best practices for your headless commerce operations.