Broadleaf Microservices
  • v1.0.0-latest-prod

Pricing Release Notes for 2.2.0-GA

Tip
The 2.x versions are Spring Boot 3 compatible.

Important Updates

Spring Boot Upgrade

  • As of Broadleaf Release Train 2.3.0-GA, all microservices have been upgraded to support Spring Boot 3.3 & 3.5.

New Features & Notable Changes

Fees

Tip
Since Pricing Service 2.2.0, Release Train 2.3.0

This release includes support for Fees, which is a new domain addition to Pricing Services. For more information on this new domain and feature, such as how it is used and how fees are calculated, see the Pricing Services Fees documentation.

  • Added FeeMetadataAutoConfiguration to configure Fee metadata for the Fee Browse grid and Fee create and update pages

    • The Fee metadata is controlled by setting broadleaf.pricing.metadata.fee.enable-fee-metadata to either enable or disable the Fee feature being accessible via the Admin Portal.

  • Added new domains and enum types

    • Added Fee domain to represent the fees to be applied onto a Cart

    • Added JpaFee domain to persist Fee objects

    • Added enum types FeeCalculationMethod which represents the calculation method to be used when applying the fee to a cart and FeeCalculationOperation which represents the operation to be used when calculating the fee to be applied to a cart

  • Updated PricingCacheProperties and PricingCacheAutoConfiguration to be able to cache Fees by Application

  • Added FeeService for Fee-related operations and methods

    • Fees can be fetched by Application and are cached by Application to facilitate easier retrieval and eliminate redundant calls to the data store

  • Added FeeEndpoint for CRUD (create, read, update, and delete) operations

  • Added FeeValidator to apply custom validations for Fees

  • Added Broadleaf Translation Common library dependency and implemented an endpoint to be able to update translations for Fee labels === Updated PriceInfos Retrieval Logic for Recurring Prices Prior to this release, the DefaultPriceInfoService logic for recurring prices (prices with frequency and term) would only check if the PriceData term matches the given PriceableTarget’s term.

In this release, the check against frequency was added to ensure consistent matching behavior. This affects the CatalogBrowse pricing logic for PDP and PLP, as CatalogBrowse needs to know the frequency to pass when doing the initial pricing for products.

Added support to show/hide recurring pricing fields by properties

Instead of always showing the recurring pricing metadata fields (e.g. terms and frequency), the metadata is now controlled by a different property:

broadleaf:
  pricing:
    metadata:
      display-recurring-pricing-fields: true
Note
Enabling subscription via broadleaf.subscription.enabled implicitly enables the recurring pricing fields too

Two-Tier Pricing

This feature allows configuration of a new "tier" pricing strategy that involves consideration of a specific target attribute and its quantity to determine the applicable price tier. By using this "two-factor" approach, we are able to handle more complex pricing scenarios where the tier adjustment amount can further vary depending on the quantity of the specified attribute. In practice, the attribute needs to match either an attribute or characteristic assigned to the PriceableTarget (e.g., Product) for the tier to apply.

  • Updated PriceData domain to include tierPricingStrategy and tierAttributeName fields.

  • Updated PriceDataTier domain to include attributeMinValue field.

  • Added TierPricingStrategyOptionEnum to represent the available tier pricing strategy options:

    • NONE

    • SIMPLE

    • TWO_FACTOR

  • Updated the DefaultPriceInfoService to handle two-tier pricing logic when calculating prices based on the defined strategy.

    • When using the TWO_FACTOR strategy, the service will filter for any price data tiers linked to the PriceableTarget’s attribute or characteristic matching the tierAttributeName, leveraging newly introduced filterPriceDataTiers and filterTiersByAttributeQuantity method

    • Updates were also made to ensure price list modifications and adjustments are also applied to the tiered pricing related to a price detail, by calculating adjustments and applying formulas to tiered prices.

  • Updated the metadata for the Price Data Form to replace the pricing strategy fields to support the new pricing strategy.

    • Replaced the tiers control group for a tierPricingStrategy dropdown.

    • When TWO_FACTOR is selected, a new tierAttributeName text field will appear to allow specifying the attribute name to be used for tier filtering.

    • When TWO_FACTOR is selected, the Price Data Tiers grid will allow defining and attributeMinValue for each row.

Example Use Case

When configuring pricing tiers for a product with an attribute or characteristic of variable quantity (e.g., "Storage Size"), the two-tier pricing strategy can be used to define price adjustments based on both the quantity purchased and the characteristic/attribute value.

For example, a product may have the following tiers defined:

  1. $50 per item with quantity ≤10 and 64 GB memory

  2. $45 per item with quantity from 11-20 and 64 GB memory

  3. $40 per item with quantity >20 and 64 GB memory

  4. $80 per item with quantity ≤10 and 128 GB memory

  5. $75 per item with quantity from 11-20 and 128 GB memory

  6. $70 per item with quantity >20 and 128 GB memory

New Price List Types

Added new Price List types: Costs Price List and Adjustment Price List, in addition to the existing Price List types.

  • Cost Price Lists are used to define alternate cost prices for products, which can then be referenced to calculate "markup" prices based on the defined cost for the SKU.

  • Adjustment Price Lists are used to define price adjustments for existing price data, allowing for modifications to be applied to prices without having to modify the original price data, which can be useful for temporary promotions or discounts.

Introduced Pricing Categories

Iin addition to the Price Modifiers concept, Pricing Categories can be used to override the cost or amount specified in a Price Modifier by referencing a Pricing Category that has a different cost or amount defined, allowing for more flexible and dynamic pricing configurations.

Miscellaneous Enhancements

  • Added new Price Modifiers: Percent Markup and Target Margin - these modifiers can be used in Price Lists to calculate prices based on a percentage markup or target margin, respectively, instead of a fixed amount.

    • For Percent Markup, the price is calculated by applying a percentage increase to the base price (e.g., a 20% markup on a $100 base price would result in a final price of $120).

    • For Target Margin, the price is calculated to achieve a specific profit margin based on the cost price (e.g., if the cost price is $80 and the target margin is 25%, the final price would be calculated as $80 / (1 - 0.25) = $106.67).

  • To complement an enhancement in Catalog Services 2.3.0, the JpaCustomizedPriceDataRepository#findByPriceListIdAndTarget has been updated to separate the targetType predicate from the targetIds predicate in its query.

    • This solves an issue where querying for multiple target IDs of different types (SKUs and Pricing Keys) would fail as the previous implementation only supported querying by target IDs when a type was also specified.

  • Added caching to newly introduced PriceList and PriceData related queries.

  • Added the ability to prefer contract prices even when they are higher — this can be enabled by setting broadleaf.pricing.price-info.prefer-contract-prices to true, as the property is false by default. This can be for use cases where the contract price is more relevant to show than comparable lower standard or sales prices, even if it is higher, such as when a contract price reflects a negotiated price that the customer has agreed to pay.

Bug Fixes

  • Fixed a bug where the Admin UI would allow adding augmentations on the PriceList Views despite the PriceList domain not supporting them by default.

  • Updated the FulfillmentStatusChange listeners to read Order and OrderFulfillment by ids, to accommodate the new message payload that only contains IDs to avoid RecordTooLargeException for large fulfillments

    • The listeners will still check for the full Order and OrderFulfillment payload in the message for the sake of backward compatibility, but the logic is subject to removal in a future release

  • Fixed a bug where Price Lists could be augmented in the admin. Added @NonAugmentable to the Price List domain to prevent illegal augmentation.

  • Fixed a bug where DefaultPriceDataService.populatePriceListCurrencyMap would only populate the result with one entry instead of all different price lists

  • Fixed a performance issue where DefaultPriceDataService.fixCurrency was not considering priceListCurrencyMap when mapping from the persisted domain, causing individual price list queries for each item in the result

  • Refactored all string literal definitions of "priceListCurrencyMap" to use a shared String constant DefaultPriceDataService.CURRENCY_BY_PRICE_LIST_ID_MAP

  • Fixed a bug where the PricingCatalogCurrencyContextInfoCustomizer could throw an IllegalStateException when not in a request context. A check was added to prevent interacting with the CurrencyHolder outside of a request context.

Configuration Properties

Added Properties

  • broadleaf.pricing.orderprovider.url

  • broadleaf.pricing.orderprovider.order-uri

    • Description: The URI path for basic singular order retrieval

    • Default value: /orders

  • broadleaf.pricing.orderprovider.fulfillment-uri

    • Description: The URI path for basic singular fulfillment retrieval

    • Default value: /order-fulfillments