Please refer to Flash Sale for more information.
April 16, 2025
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
Tip
|
If coming from a version prior to 2.0.0-GA, then see the 2.0.0 upgrade guide. |
Tip
|
Also see Upgrade 2.1.4-GA upgrade guide. Upgrade 2.2.0 also contains the changes noted in the 2.1.4 Upgrade. |
Feature/Notable Change | Impacted Services | Links |
---|---|---|
Support for Flash Sale |
CartOperationServices, PricingServices, Import, ScheduledJobServices |
Please refer to Flash Sale for more information. |
Support to view Scheduled Job Execution Details |
ScheduledJobServices, MicroMessagingCommon |
Please refer to Scheduled Job Release Notes for 2.1.4-GA for more information. |
AssetServices Storage Provider Path Changes |
AssetServices |
There is an important change made to the storage path new assets will be stored at in AssetServices. Please review the AssetServices 2.0.3 release notes describing the change |
Added new Audit Microservice |
AuditServices, AuditCommon |
|
Added new Workflow Microservice |
WorkflowServices, WorkflowClient |
|
Improved service-to-service calls within a single flex package to skip overhead of external calls. |
MicroExtensionCommon |
See details and configuration in the Micro Extension Common Release Notes for 2.0.5 |
Added support for receiving updated transaction results through the webhook. |
PaymentGatewayCommon, PaymentTransactionServices, Adyen |
|
Remember-Me Login |
AuthenticationServices, AuthSDK, AdminWeb, NextJS Starter |
|
Introduced new Product & Category Membership Bulk Operations |
CatalogServices, BulkOperationsServices, SandboxServices |
|
Updated discriminated properties to be case insensitive |
Across all Microservices that utilize |
See individual release notes for a full list of updated services & classes. |
Mitigation of Sandbox |
SandboxServices |
|
Overriding Manifest Properties via ENV properties |
Project Initializer Manifest |
Additional documentation has been added regarding our manifest environment setup & the ability to override manifest properties. |
Alongside the existing Heat Clinic demo, is now a new Telco Demo starter extension available. See the Broadleaf Initializr for more details.
Broadleaf has joined TMForum as a member and has expanded various framework capabilities in service of achieving TMForum API certification.
Please see the individual project release notes below for more information.
Feature/Notable Change | Impacted Services | Links |
---|---|---|
Introduced Relevancy Rules |
SearchServices, AdminServices, AuthenticationServices, AdminWeb |
|
Added support for recurring/usage prices, recurring discounts, and free trials |
PricingServices, OfferServices, PricingClient, OfferClient |
|
Added support for pre-order and backorder inventory |
InventoryServices, OrderOperationServices, OrderServices |
|
Added support for characteristics and product terms |
CatalogServices, CatalogBrowseServices |
|
Added support for Offer Templates |
OfferServices |
|
Refactored Quote React to split out new |
Commerce Microfrontend |
Common concerns such as icons, the component registrar and renderer, and the client registrar were moved to the |
Tip
|
Nothing is required for adopting Relevancy Rules beyond normal version changes to Release Train, but details may be found in Search Services release notes including required Auth permissions and scopes. There is also no need to perform a full Solr reindex after upgrading since Relevancy Rules are applied at query time. |
To review the security related content, see 2.2.0 notes.
Tip
|
You will need your login credentials originally provided for accessing the Broadleaf nexus. Security fixes often involve dependency updates to remediate issues being tracked in external OSS components. It is worth considering adopting releases with security fixes (even Broadleaf Severity LOW) to avoid any possibility of transitive exposure in your codebase. |
Node 20 supported since 1.6.3.
No migration or code changes required.
Node 14 and Node 16 have reached end of life and Node 18 will reach it in May 2025.
This version includes all changes up to 1.6.4 Release Notes.
Tip
|
This release is compatible with Release Trains starting in the 2.2.x line. |
Important
|
Minimum React version upgraded to React 18. Minimum Node version upgraded to Node 18. |
Added new field DEFAULT_TIME_ZONE
to the BLC_ADMIN_USER
table. The field value is used to format the dates in the Admin panel if specified. It is updated when the user changes the default time zone in the Admin panel.
Added new field DEFAULT_APPLICATION_ID
to the BLC_ADMIN_USER
table. The field value is used to pre-select application on user sign in. It overrides setting of default application on tenant level for a specific user. Makes sense only when user has access to applications and has applications assigned.
Allow an admin to send a reset password email to another admin user *
Note
|
If using liquibase to pull in base Broadleaf changelogs, then it is not necessary to manually run this script. |
ALTER TABLE ADMINUSER.BLC_ADMIN_USER ADD DEFAULT_TIME_ZONE VARCHAR(255);
ALTER TABLE ADMINUSER.BLC_ADMIN_USER ADD DEFAULT_APPLICATION_ID VARCHAR(36);
As of Broadleaf Release Train 2.1.3-GA, all microservices have been upgraded to Spring Boot 3.3
StorageProvider
Path ChangesThis release makes changes to the internal logic used by StorageProvider
implementations such as FilesystemStorageProvider
and GoogleCloudStorageProvider
to determine the 'actual path' used to store asset data.
The primary motivation for this change is to mitigate the possibility of a 'collision', where two assets with distinct URL values could still be assigned the same 'actual path' in the StorageProvider
.
The new approach guarantees uniqueness in the 'actual paths'.
High level takeaways for this change:
All new assets created with 2.0.3+ of AssetServices will use the new path calculation logic and be stored/resolved at the new paths
Existing assets created prior to 2.0.3 will continue to be resolvable from their current locations
This does not require any migration of existing asset data
Detailed changes:
Introduce a new StorageLocationMapping entity and supporting service/repository to map between 'original' and 'actual' storage provider locations
See the Schema Changes section on how to absorb the new table
Add new cache configuration properties for StorageLocationMapping (broadleaf.asset.cache.storage-location-mapping.by-provider-type-and-original-location-enabled
and broadleaf.asset.cache.storage-location-mapping.by-provider-type-and-original-location-ttl
).
This cache is disabled by default.
DefaultContentResolver.readResourceWithMetadata
has been updated to not engage any caching behavior when processing a request with image effects.
This only affects how StorageLocationMapping
records are fetched.
Update FilesystemStorageProvider
Update the storage path calculation logic to use a globally unique filename and leverage StorageLocationMapping
to track the mapping
FilesystemStorageProvider#getHashedResourcePath
is now only used to support resolving existing assets for backward compatibility.
If you have overridden this method in your project to customize the logic, then consider reviewing and adding similar logic to the new FilesystemStorageProvider#calculateHashedStorageLocationDirectory
method, which is used to generate the hashed directory prefix for new assets.
FilesystemStorageProvider#mapGivenPathsToHashedPaths
is deprecated and now no longer called by the framework
If you have overridden this method in your project to customize the logic, you may consider reviewing these replacement methods and potentially add your customizations to them instead: FilesystemStorageProvider.generateActualStorageLocations()
and FilesystemStorageProvider.resolveExistingActualStorageLocations()
Due to the internal filename naming changes, any callers of the already-deprecated FilesystemStorageProvider.readResource()
and FilesystemStorageProvider.readResources()
methods will now see a different filename value in the result.
Callers of the newer FilesystemStorageProvider.readStreamableResourceWithMetadata()
/FilesystemStorageProvider.readStreamableResourcesWithMetadata()
will see the original value.
Update GoogleCloudStorageProvider
Update the storage path calculation logic to use a globally unique filename and leverage StorageLocationMapping
to track the mapping
GoogleCloudStorageProvider.getBlobId
is deprecated and now no longer called by the framework
If you have overridden this method in your project to customize the logic, you may consider reviewing these replacement methods and potentially add your customizations to them instead: GoogleCloudStorageProvider.generateActualStorageLocations()
and GoogleCloudStorageProvider.resolveExistingActualStorageLocations()
GoogleCloudStorageProvider#getHashedResourcePath
is now only used to support resolving existing assets for backward compatibility.
The new approach does not use hashing.
Updated methods DefaultStorageService#mapEligibleProperties
and DefaultStorageService#generateAssetForUploadRequest
to be access-level protected
Allow altText
and title
to be supplied on the asset upload request
Folders and assets now sorted alphabetically by default
Fix issue that prevents assets with string content
in name to be found
GoogleCloudStorageProvider.deleteResource()
now throws the BLC StorageException
when a requested item is not successfully deleted.
This is now consistent with the expectations defined in the StorageProvider
interface.
GoogleCloudStorageProvider.deleteResources()
now throws the BLC BulkStorageException
instead of the BLC StorageException
when it internally encounters com.google.cloud.storage.StorageException
.
This is now consistent with the expectations defined in the StorageProvider
interface.
Fixed an issue where DefaultStorageService
and ImageMagickImageOperationService
did not invoke StorageProvider.addResourceFromStream()
with a try-with-resources for the InputStream
.
The input stream may have been left open in the event of an error.
Updated addResourcesFromStreams()
, deleteResources()
, and addResourcesFromFiles()
implementations in FilesystemStorageProvider
and GoogleCloudStorageProvider
to ensure that the success/failure responses given back to the caller (either in BulkAddResourcesResponse
or in BulkStorageException
) always return by the original path the caller provided rather than any cleaned representation. This ensures the caller can track success/failure purely by the path they gave rather than receiving a path they do not recognize, matching the original intent of the API contract.
Decouple the @EnableConfigurationProperties(AssetCacheProperties.class)
from the registration of the Ignite specific configuration in AssetCacheAutoConfiguration
, increasing flexibility
The database schema has changed as part of this version.
Create/update changes (new tables, new columns, etc) are automatically included in the updated *changelog-master.xml
after you upgrade to the new Asset Services JAR.
The new changesets inside will run automatically to migrate existing data.
Database Platform | Create/Update Changelog File Name |
---|---|
PostgreSQL |
|
MariaDB |
|
MySQL |
|
Oracle |
|
YugabyteDB |
|
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
This version includes all changes up to 2.1.4 Release Notes.
Added permissions/scopes for new entities and concepts introduced in other services for the 2.2.0 Release Train.
These are included in the auth.starter.required.data.changelog.xml
file.
Introduce CHARACTERISTIC
permissions and scopes
Introduce CONSOLIDATED_INVENTORY_AVAILABILITY
permissions and scopes
Grant the inventoryclient
the READ_ORDER
and READ_ORDER_FULFILLMENT
permission/scopes
Grant the orderopsclient
the ALL_INVENTORY_RESERVATION
permission/scopes
Grant the catalogbrowseclient
the READ_INVENTORY_SUMMARY
permission/scopes
Introduce RELEVANCY_RULE_GROUP
and RELEVANCY_RULE
permission/scopes
Added openapi client scope & permission for PRODUCT_BUSINESS_TYPE
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
JDK 17 is required for Broadleaf release trains 2.0.0-GA, and beyond.
Note
|
Includes changes in 2.0.2-GA |
This version includes all changes up to 2.1.4 Release Notes.
Added new fields on CartItem to track recurring and usage pricing.
See Pricing Services Data Model to review new pricing fields.
Added new fields on Adjustment to track the type of discount, free trial length, and recurring discount start and end periods.
See Offer Adjustment for more details.
Both Cart and CartItem received new computed fields and helper methods to handle the new recurring prices to allow more easily working with and display these values in a storefront application.
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
This version includes all changes up to 2.1.4 Release Notes
Allowed more control when selecting which asset to show in the cart for an item from one of the Product’s assets besides simply choosing the primary.
Instead, users can now configure a preferred asset tag to match against.
By default it is cart
.
Added properties to configure whether the Variant’s name is used as the item’s name instead of the Product’s. This will be true by default.
New properties:
broadleaf.cartoperation.service.preferred-asset-tag
with default cart
broadleaf.cartoperation.service.use-variant-name-in-cart
with default true
Introduced support for Product Characteristics and Product Terms.
Introduced support for recurring and usage pricing concepts.
Primarily this looks like being able to include characteristics marked as targetableForPricing
and product terms in PriceableTarget
payloads.
See Cart Services 2.1.0 Release Notes for related domain changes.
Includes support for including characteristics marked as targetableInRuleBuilders
in Offer Engine requests.
Introduced support for new recurring and free trial offers.
This release includes support for the Adyen payment integration.
Added an ability to send the additional data in the CheckoutProcessRequest
, needed to execute payment transactions, esp. properties that should not be persisted to the Payment#paymentMethodProperties
.
See CheckoutProcessRequest#sensitivePaymentMethodData
Resolved a bug where a failed payment transaction causes the PaymentSummary
in the CheckoutResponse
to be out of date
Resolved issue when a failure in DefaultCheckoutService#createOrderNumber method doesn’t create order but still charges a payment
Important
|
This release includes a potentially breaking change if you have an override/implementation of one of the following methods:
If this effects your project, you’ll encounter a compilation issue.
These compilation issues should be simple to resolve - ie look to gather data from the provided In short, these method signature changes within the CartOps were needed to effectively pass the This change was also made to future-proof these method signatures by passing objects, rather than simple params. |
Fix bug where a failed payment transaction causes the PaymentSummary in the CheckoutResponse to be out of date
Fixed issue where the CSR Price override would not be applied by setting the standardRecurringPrice
for order line items with overridePrice
when applying offers.
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
This version includes all changes up to 2.1.4 Release Notes.
Updated BusinessTypeService
and BusinessTypeRepository
to introduce a method that can find BusinessType
by ID as well as additional RSQL filters
Refactored logic that built BusinessType
instances from DefaultProductType
values into its own DefaultProductTypeBusinessTypeBuilder
component.
BusinessTypeEndpoint
now injects and uses this component instead of having the logic inline within itself.
For BusinessType
instances built for DefaultProductType
values, added logic to set a reserved corresponding ID for BusinessType.id
instead of keeping it blank.
The ID mapping is defined in DefaultProductTypeBusinessTypeBuilder
.
Introduced the ability to define available terms for Products.
Introduced support to be able to add Products with a rule-based Category Item Choice Product Option to cart.
Introduced the ability to Sync Characteristics and translations for any missing Characteristics for Product Business Types and default any values as applicable.
Added priceDataViewType
as a property in CatalogMetadataProperties
to dictate changes in the metadata for Products and Option Templates to either display default views or recurring/subscription-specific views.
Introduced a new /product-types/all
endpoint in BusinessTypeEndpoint
to serve the purpose of returning all non-paginated BusinessType
records.
Deprecated the previous conflicting request mapping at /product-types
Updated the BusinessType
metadata configuration to use the new endpoint path instead of the old one.
Updated the BusinessType
metadata configuration to remove the narrowedPaging()
configuration when using the endpoint, since neither the previous nor current implementation of that endpoint support pagination.
CatalogEntityDeletedEventHandler
Failures with Deactivated ApplicationsCatalogEntityDeletedEventHandler
implementations would fail on a security validation when run against data from a deactivated application (see Application.deactivated
).
To address this, each of the out of box implementations have been updated to disable security policy validation before invoking any CRUD methods to find/remove data.
This is a safe change, as the cleanup handlers are always run internally by the system (rather than by any user/client).
Almost all policy validations are skipped in such an environment already, but the Application.deactivated
check is an exception, and the CatalogEntityDeletedEventHandlers
are a rare case which actually attempt to deal with deactivated applications.
Thus, explicitly bypassing security validation in this flow is necessary.
The changes:
Introduce a new doWithoutPolicyValidation()
method in AbstractCatalogEntityDeletedEventHandler
Update all out of box implementations of CatalogEntityDeletedEventHandler
to wrap their CRUD service invocations with the new doWithoutPolicyValidation()
method
Note
|
If you have introduced your own CatalogEntityDeletedEventHandler or customized one of the out of box implementations, you may want to check that your custom code flows also bypass security validation.
|
BusinessType
The BusinessType
domain was always meant to be non-sandboxable, and all operations against this domain from the Broadleaf admin have been 'production' level accordingly.
However, the Trackable
configuration of JpaBusinessType
did not explicitly exclude sandbox behavior.
This meant that theoretically, it was possible to create sandbox-level records for this domain if requests were made by a custom API caller.
With this release, JpaBusinessType
has been explicitly annotated with @TrackableExtension(TrackableBehavior.APPLICATION)
, which excludes it entirely from supporting sandbox behavior.
Clients who have exclusively been managing this domain from the Broadleaf admin will not be impacted by this change, as the Broadleaf admin has always affected this domain at the production (non-sandbox) level.
For clients that believe they may have sandbox-level BusinessType
records, here are some recommended steps:
First, examine the change summaries in the BLC admin’s 'Application Updates' section. From here, you can audit and manage (deploy/reject/etc) any changes to BusinessType
domains until there are no more pending changes.
At this point, all that should be left in the CatalogServices database are production level records and 'obsolete' sandbox level records. The goal now is to find and remove those obsolete records.
Note
|
Technically, this step to remove obsolete sandbox records is optional. However, we include it in case clients find it helpful. |
You can run the following SQL to see the BusinessType records who exist in the datastore with a sandbox-archived state
SELECT id, context_id, name, trk_level, trk_sandbox_archived
FROM catalog.blc_product_business_type
WHERE trk_sandbox_archived = 'Y'
Inspect these results and verify that these obsolete records are indeed okay to remove
You can run the following SQL to see the Notification State records that would become orphaned if those business types were deleted:
SELECT id
from catalog.blc_notification_state
WHERE entity_type = 'com.broadleafcommerce.catalog.provider.jpa.domain.product.type.JpaBusinessType'
AND container IN (SELECT id
FROM catalog.blc_product_business_type
WHERE trk_sandbox_archived = 'Y')
If everything looks fine to remove, then you can first execute a DELETE
on the blc_notification_state
table with the same criteria as above, and then execute a DELETE
on the blc_product_business_type
table, again with the same criteria as above.
Added a new GET endpoint to fetch BusinessType records, replacing a now-deprecated endpoint.
Previously, there were several different GET
operations mapped to the same /product-types
path, distinguished only by request parameters.
While technically functional, the operations deserved to be more clearly disambiguated due to their differing semantics and response schemas.
Thus, this existing mapping has been deprecated:
GET /product-types?includeDefaults=(boolean)&includeTemplates=(boolean)
, returning List<BusinessType>
The replacement endpoint is:
GET /product-types/all?includeDefaults=(boolean)&includeTemplates=(boolean)
, returning List<BusinessType>
The BusinessType
admin metadata configuration has been updated to use the new endpoint path instead of the old one.
Furthermore, the narrowedPaging()
configuration has been removed when calling this endpoint, as neither the previous nor current implementation of the endpoint supports pagination.
Refactored Product Characteristic value handling and updated Characteristic field labels to fix issues with default values and labels.
Fixed issue where translations were allowed on numeric characteristic values.
Path | Description |
---|---|
|
Read a page of Characteristics, accepting RSQL filters and a name ( |
|
Create a new Characteristic. |
|
Read a single Characteristic by ID. |
|
Patch a single Characteristic by ID. |
|
Replace a single Characteristic by ID. |
|
Delete a single Characteristic by ID. |
|
Replace the translations for a single Characteristic by ID for a given locale. |
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
This version includes all changes up to 2.0.6 Release Notes.
Introduced support for Product Characteristics and Product Terms.
Introduced support for recurring and usage pricing concepts.
Primarily this looks like being able to include characteristics marked as targetableForPricing
and product terms in PriceableTarget
payloads.
Includes a number of enhancements around product detail hydration.
Introduced ability to fully hydrate Products in Search Requests—not just pricing, assets, or tags. This behavior is controlled by a parameter on the Catalog Search request: hydrateFully
. False by default.
Introduced ability to minimize the payload size for Assets so that they don’t include the ContextState
, which is not valuable in a commerce scenario. Controlled by broadleaf.catalogbrowse.catalogprovider.asset-minification-enabled
, which is true by default.
Added the ability to pass RSQL filters to filter the assets or tags fetched when hydrating them onto Search Results using the assetFilters
and tagFilters
params.
Introduced support for Recommendation Engine Services via Browse Content.
Introduced CustomContentFields
, enabling the creation of custom fields in the admin application. This feature is useful when a content item requires a field that is not part of the standard ContentFields
metadata type. These custom fields allow users to define a list of Enums or values that can be selected from an external API.
This version includes all changes up to 2.0.6 Release Notes.
This version includes all changes up to 2.0.6 Release Notes.
Introduced support for Recommendation Engine Services via Customer Modified messaging.
The Customer Modified messaging configuration is featured in its own separate class to support the balanced
configuration setup.
Update parsing discriminated properties to be case insensitive by utilizing CaseInsensitiveMap
.
e.g. broadleaf.orderoperation.*
will be parsed the same as broadleaf.ORDEROPERATION.*
Added a new NUMBER_OF_ITEMS
enum option to BandField enum.
This field is not utilized OOB and is added for customization purposes.
This version includes all changes up to 2.0.4 Release Notes.
Support new concepts introduced in Catalog Services 2.2.0
Update CompleteProductImportSpecification
to support 'characteristics' and 'terms' headers
support for new Terms on a Product
support for new Product Characteristics on a Product
Example Expanded Scope of Support:
Business Type | Terms | Product Characteristics |
---|---|---|
PHONE |
name::finance;durationType::MONTHS;durationLength::36 |
"cameraMegapixel::50MP + 5MP + 2MP" |
PHONE |
name::commitment;durationType::MONTHS;durationLength::24 |
"numberTest::12345" |
Introduced the following fields on SkuInventory
(please see the upgrade guide below for DB migration notes)
futureStockEnabled
- drives whether this inventory should allow configuration of future stock
futureStockLimited
- drives whether availability checks will be made when reserving future stock
futureStockType
- describes whether this is a 'preorder' or 'backorder' future stock
expectedFutureRestockDate
- describes the expected date the future stock will become available
The existing SkuInventory.quantityOnOrder
field is now properly leveraged for future stock to indicate the pre-order or back-order quantity, and the SkuInventory.updateQuantityAvailable()
method now incorporates its value.
SkuInventoryAvailabilitySummary
now includes details about future stock
Introduced a new FUTURE_STOCK_RESERVED
transaction type
When an order is placed, any quantity requested that is not immediately available will be reserved as this type instead of as a hard reservation
Various SkuInventory
-managing components (ex: SkuInventoryAdjustmentService
, SkuInventorySummaryService
, StockChangeNotificationService
) have been updated to consider future stock in their behavior
Introduce new OrderCreatedInventoryAdjustmentMessageListener
to supersede the now-deprecated OrderSubmittedInventoryAdjustmentMessageListener
See the broadleaf.inventory.messaging.order-submitted.legacy.enabled
property for controlling the implementation that is used
Introduce a new OrderProvider
to support the new implementation
Introduce new InventoryTransactionChangeNotificationProducer
and FutureStockAvailabilityChangeNotificationProducer
message producers
Update metadata configuration to support the new domain fields
Update /available-quantities
endpoint to support a new availableNow
parameter driving whether this lookup should only find inventory quantities that are available now, and not in the future
The database schema has changed as part of this version.
Create/update changes (new tables, new columns, etc) are automatically included in the updated *changelog-master.xml
after you upgrade to the new Inventory Services JAR.
Database Platform | Create/Update Changelog File Name |
---|---|
PostgreSQL |
|
MariaDB |
|
MySQL |
|
Oracle |
|
YugabyteDB |
|
Added discrete cache invalidation
This new feature allows invalidating the caches when one of the entities is changed/deleted so that the new changes will be immediately available without needing to wait until the cache has expired.
See the Menu configuration docs for details on how to configure this feature and for the full list of configurable properties.
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
Updates were made to usages of the ContextRequest
domain:
Deprecated forceCatalogForFetch
in favor of forceFilterByCatalogIncludeInheritance
.
Introduced forceFilterByCatalogIncludeInheritance
flag that controls the narrowing logic to only filter on the specified catalog within the context rather than the whole catalog hierarchy.
Updated MessageProperties
to use CaseInsensitiveMap
when storing the tenant and application related properties.
ENV properties will be converted to lowercase by Spring — in the case of UUIDs for Applications and Tenants, there can be a mismatch when the casing changes, so CaseInsensitiveMap
addresses this issue.
Broadleaf Release Train 2.2.0 introduced new price types for Recurring (or Subscription) and Usage prices. Previously only upfront prices were supported out of box. Likewise, Offers now can discount recurring prices or provide free trial periods.
Offer
freeTrial
: Whether the offer applies a free trial for the targeted item(s).
freeTrialLength
: How long the free trial lasts
freeTrialLengthUnits
: The units for the free trial.
Default values include: DAYS
, WEEKS
, and MONTHS
.
subscriptionDiscount
: Embedded object.
discountCurrentOrder
: Deprecated as the new price fields make this flag unnecessary.
endPeriod
: Is now nullable.
friendlyOfferType
: Deprecated in favor of new offerTemplate
that supports better localization of labels.
offerTemplate
: A computed field to replace friendlyOfferType
that indicates the template or pattern followed to create the offer.
This primarily drives metadata to show or hide fields applicable to certain combinations of configuration flags.
The following lists the changes to DTOs related to making requests and receiving responses from the Offer Engine.
Added new fields to Adjustment
type
with the following options:
ORDER_DISCOUNT
: Standard adjustment type.
All out of box adjustments prior to 3.1.0 would have this type.
FUTURE_CREDIT
: Indicates the discount should be applied to a future order as a credit.
Future credits could be applied previously and used a separate isFutureCredit
flag, although this feature was and is not fully implemented.
This has been rolled into the new type
field instead of using a separate flag.
RECURRING_DISCOUNT
: Indicates the adjustment should be applied to the recurring (or subscription) price instead of the upfront price and should not affect the order subtotal at time of checkout.
FREE_TRIAL
: Indicates that the subscription item should have its first billing period delayed for a period of time.
freeTrialLength
: Indicates to the billing engine how long a free trial period is.
freeTrialLengthUnits
: Indicates to the billing engine what the units are for freeTrialLength
.
Default options are: DAYS
, WEEKS
, and MONTHS
.
beginPeriod
: For recurring discounts, indicates when the discount should start being applied.
endPeriod
: For recurring discounts, indicates when the discount should stop being applied.
Null indicates never.
Added new fields to LineItem
, LineItemDto
, and EnhancedLineItem
standardRecurringPrice
: Indicates the standard recurring price details including
price
periodFrequency
: How often the price should be billed
periodType
: The type of period.
The default options are MONTHLY
, QUARTERLY
, and ANNUALLY
.
periodLimit
: The number of periods the price should be charged.
Only applicable when the originating Price List was not STANDARD
.
termDurationLength
: If there are terms for the price, this is the length.
termDurationType
: The type of duration.
The Default options are DAYS
, WEEKS
, MONTHS
, YEARS
.
saleRecurringPrice
: Indicates the sale recurring price details.
Same structure as standardRecurringPrice
.
Important since not all offers may be applied to a sale price.
Added new fields to ItemResponse
baseRecurringPricePerItem
: The price from which adjustments were calculated.
This may be the originating LineItem’s standard
or sale
recurring price.
appliedToSalePrice
: Whether the adjustments applied to the item used its sale or standard (non-recurring) price.
appliedToSaleRecurringPrice
: Whether the adjustments applied to the item used its sale or standard recurring price.
This is separate from appliedToSalePrice
to allow mixing discounts for items with both recurring and upfront prices.
recurringAdjustedTotal
: The final total recurring price after adjustments are applied.
recurringSavings
: The total of all recurring price savings.
freeTrialApplied
: Whether any of the adjustments applied were free trials.
Added new fields to ItemResponseDetail
appliedToSalePrice
: Whether the adjustments applied to the item used its sale or standard (non-recurring) price.
appliedToSaleRecurringPrice
: Whether the adjustments applied to the item used its sale or standard recurring price.
recurringSavings
: The total of all recurring price savings.
recurringAdjustedTotal
: The final total recurring price after adjustments are applied.
Deprecated fields on ItemResponseDetail
beginPeriod
: No longer valid since more than one subscription discount may be applied.
Instead each ItemAdjustment
should be consulted by the caller.
endPeriod
: No longer valid since more than one subscription discount may be applied.
Instead each ItemAdjustment
should be consulted by the caller.
Offers already had fields, hidden by default, that allowed configuring subscription discounts.
However, the feature was incomplete and require customization to implement fully—such as setting the #isSubscription
flag on OrderLineItemDto
.
Anyone upgrading who is using the old version of the feature should ensure that subscription OrderLineItemDtos
sent to the Offer engine are updated to include the subscription price as part of the new #standardRecurringPrice
and #saleRecurringPrice
structures as applicable.
Also, expect that ItemResponseDetails
will not populate #beginPeriod
and #endPeriod
since more than one subscription discount may be applied.
Instead use the ItemAdjustments
on the details, which are per discount.
A new computed field has been introduced on the Offer domain to help drive the Admin UI to handle the variety of complex Offer configurations called offerTemplate
.
In the Admin this will be labeled as "Offer Type" and the existing field with that name will be changed to "Offer Target Type" to clarify the intent of each.
See Offer Types for more details.
Added a OfferCachePropertiesEnvironmentPostProcessor to support automatically registering message binding properties if the cache invalidation enabled property is set as a JVM property, and has a value of true.
See Cache Invalidation in the Offer configuration docs for details on how to configure this feature and for the full list of configurable properties.
Additionally, this change removes and updates some of our Beans in the Order Services to better follow configuration patterns and resolve issues that prevented CamelClusterService
from working correctly. The previous configuration pattern negatively affected message retries. See the table in the collapsed block below:
Class | Bean | Change |
---|---|---|
|
|
Removed as it was a supplier bean |
|
|
Removed as it was a supplier bean |
|
|
Removed as it was a supplier bean |
|
|
Removed as it was a supplier bean |
|
|
Update arguments from
|
|
|
Update arguments from
|
|
|
Update arguments from
|
|
|
Update arguments from
|
|
|
Update arguments from
|
|
|
Update arguments from
|
|
|
Update arguments from
|
Added first-class support for allowing third-party APIs to add and return external offers onto orders when they are being processed through the Offer Engine.
See the tutorial on adding a new external offer provider for more detailed documentation around this feature.
Added support for qualifying multiple voucher offers per order if it’s unlimited
Added support for cart subtotal threshold based Free Gift offers without any qualifier criteria
Allow the selection of BUNDLE typed products for Free Gift offers
This is to support a more dynamic setup for Free Gift offers, e.g. a bundle product that consists of 2 itemA and 3 itemB can be used solely for the purpose of being free gifts, while the bundle product itself cannot be individually sold nor searchable
Adds the option of an Offer which has an item associated with it. Unlike a Free Gift, this will have a cost but it should be at a reduced price from the original price.
Improve performance during the generation of offer codes in order to reduce the amount of processing needed to generate large amounts of codes.
This includes updating the ModelMapperMappable
implementation of JpaOfferCode
to perform mappings directly via a 'preconverter' instead of the previous TypeMap
mappings-based approach.
The changes here also bypasses a slower merge()
call for a faster persist()
as the generated codes are always new and would not need any potential updates.
Several currency mismatch issues were addressed where the currency from the LineItem was not used to initialize computed prices, leading to the system default currency being used instead in some cases.
CombinabilityOverrides being incorrectly detected when an Offer was stackable and had no combinability overrides has been addressed.
Fixed an issue where subscription BOGO items would not correctly set dates and have the incorrect value for the applyToFuturePeriods
flag.
Marketing message priority field is now honored(sorted by it) when fetching/showing messages
Fixed bug where 2 Free Gift offers can both be applied in the same order
Exposed the combinability fields for Free Gift offers and default it to OTHER_TYPES
Fixed issues around the usage and messaging for max usages on offers.
Fixed an issue where items with a sale price caused a NPE after attempting to grab information not needed for tiered candidate offers.
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
JDK 17 is required for Broadleaf release trains 2.0.0-GA, and beyond.
This version now requires DataTracking 2.0.3+
Added new fields on OrderItem to track recurring and usage pricing.
See Pricing Services Data Model to review new pricing fields.
Added new GET endpoints around the FulfillmentCaptureClaimSummary
domain which should be used to replace the matching deprecated endpoints.
Previously, there were several different GET
operations mapped to the same /fulfillment-capture-claims
path, distinguished only by request parameters.
While technically functional, the operations deserved to be more clearly disambiguated due to their differing semantics and response schemas.
Thus, these existing mappings have been deprecated:
GET /fulfillment-capture-claims?paymentId
, returning FulfillmentCaptureClaimSummary
GET /fulfillment-capture-claims?paymentIds
, returning List<FulfillmentCaptureClaimSummary>
GET /fulfillment-capture-claims?fulfillmentId
, returning FulfillmentCaptureClaimSummary
The replacement endpoints are:
GET /fulfillment-capture-claims/summaries/by-payment-id?paymentId
, returning FulfillmentCaptureClaimSummary
GET /fulfillment-capture-claims/summaries/by-payment-ids?paymentIds
, returning List<FulfillmentCaptureClaimSummary>
GET /fulfillment-capture-claims/summaries/by-fulfillment-id?fulfillmentId
, returning FulfillmentCaptureClaimSummary
Added the concept of a Preorder and Backorder item.
A Preorder is an order for an item which has never had available stock but will become available at a later date.
A Backorder is an order for an item which has run out of stock but has plans to become available again at a later date.
See the 2.1.0 Inventory Service release notes for more details.
Backend and metadata for order services has been updated so it can be utilized at the Tenant level of the Admin application.
The order view can now be accessed when an application is not selected on the Admin. This results in a combined list of all orders that fall under a Tenant.
Orders at the Tenant level are not read only, allowing a user to update the orders without need to update them at the application level.
The Orders view can also be filtered by Application now, allowing easy access to view specific Application orders from the tenant level.
Note: Backend logic for endpoints has been modified to allow for Tenant only contexts. This may require updates to customized endpoints.
Order items now contain additional pricing information, specifically the concepts of Recurring price and Usage price.
Recurring price will be utilized by an item that requires payment at an interval; e.g. a subscription.
Usage price will be utilized by an item that requires payment per some usage metric e.g. cost per API call for a website or usage of data on a phone plan.
See the 2.1.0 Pricing Service release notes for more details.
RSQLParser bean now has a orderServiceConsolidationRsqlParser
qualifier.
Added a dependency for the cart-services-client onto Order services.
Support new concepts introduced to other services in the 2.2.0 Release Train
Add mechanisms to interact with InventoryServices to support preorder and backorder concepts. See the 2.1.0 Inventory Service release notes for more details.
A Preorder is an order for an item which has never had available stock but will become available at a later date.
A Backorder is an order for an item which has run out of stock but has plans to become available again at a later date.
This includes mechanisms to split the fulfillment if necessary and update the fulfilment for future-stock items to PENDING_INVENTORY
This includes mechanisms to set an inventoryLastUpdated
attribute on fulfillments after inventory services emits a message indicating pending inventory may now be available.
This is surfaced in the admin metadata.
Ensure recurring/usage pricing details are passed between CartItem
and OrderItem
in DefaultCartOrderGenerationService
Updated the GET endpoints for retrieving a FulfillmentCaptureClaimSummary
to utilize a new set of endpoints with discrete uri mapping. See the Order Service release notes for more details.
If you are updating Order Operation Services to version 2.1.0+ (Release Train 2.2.0+) but not Order Services, you will need to manually set the uri path properties of these endpoints to an empty string. This will call the old endpoints in Order Services.
The properties, once updated should look like:
broadleaf:
orderoperation:
orderprovider:
summary-by-payment-id-subpath: ""
summary-by-payment-ids-subpath: ""
summary-by-fulfillment-id-subpath: ""
See the configuration documentation for more details.
Order items are now generated from the cart with additional pricing information, specifically the concepts of Recurring price and Usage price.
Recurring price will be utilized by an item that requires payment at an interval; e.g. a subscription.
Usage price will be utilized by an item that requires payment per some usage metric e.g. cost per API call for a website or usage of data on a phone plan.
See the 2.1.0 Pricing Service release notes for more details.
Update DiscriminatedProperties
to utilize CaseInsensitiveMap
when binding application and tenant ID property key prefixes
This ensures properties supplied via YAML vs environment variables are not treated as separate properties purely due to a case mismatch.
This affects OrderOperationPaymentProperties
(broadleaf.orderoperation.service.payment.*
)
Updated requests to ReturnOperationEndpoint
to utilize application information to allow for Tenant level requests.
Fixed an issue with a null
customer name which prevented billing addresses from being correctly persisted.
Fixed an issue with paged requests and responses not being correctly serialized and deserialized.
Fixed an issue where deeply nested (at least 3 levels) dependent order items were not correctly hydrating information, causing a null
value for the Order Item’s refundAmount
.
Replace property usages of forceCatalogForFetch
for forceFilterByCatalogIncludeInheritance
.
Added failureType
reason to the checkout rollback event.
Reduce log level for Resource Lock exception in payment webhook logging.
Added support for payment transaction result audit & transaction updates.
Add new payment transaction results audit table, BLC_PAYMENT_TX_RESULT_AUDIT
.
On webhook update events, copy previous transaction results to the new results audit domain to store transaction result history. Then update the payment transaction with the updated results from the webhook.
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
Version 2.1.0-GA includes all changes up to 2.0.5 Release Notes
Added a new bulk read PriceData
endpoint to be used by Data Exchange Service.
Introduced Price Data views metadata improvements:
Introduced PricingMetadataProperties
as a properties class available to metadata classes, and used in PricingServicesMetadataAutoConfiguration
to dictate views.
Added a priceDataViewType
property that determines the type of Price Data view to display.
Added a displayFlashSaleFieldsInPriceDataGrid
property that determines whether to include Flash Sale fields in the Price Data grid.
Updated the wording related to Flash Sale pricing.
A single PriceData
can be used to define an upfront price (the normal price
) along with a recurring and usage price.
The recurring price includes defining the billing period frequency and optional terms, e.g., bill monthly for 36 months, bill quarterly indefinitely, bill annually for 10 years.
The usage price includes defining units for what is being used and the amount to charge for, e.g., per minute, per gigabyte, per message.
Supports also targeting a characteristic value in combination with the Product’s SKU to associate pricing.
Supports targeting a Product’s terms in combination with a SKU to associate pricing.
PriceInfo
payload now contains fields for RecurringPriceDetail
and UsagePriceDetail
PriceTypeDetail
payload also contains RecurringPriceDetail
and UsagePriceDetail
for the best price of a particular type to support strike-through pricing display.
PriceableTarget
payload supports specifying Product Terms or Characteristics for which to get pricing for.
Fixed issue where repositories were breaking extensibility by having hard-coded framework entity class names.
Fixed issue where if the PriceList
uses a different currency than the system default, when reading or updating the PriceDataTier
, the currency returned will be the system default instead of the PriceList
currency.
Fixed issue where some Price Data fields would be reset when a linked or parent field would be updated.
Important
|
The changes here are important, please ensure to read through them. |
NotificationState
buildup
Important
|
The changes described here are impactful and all clients are advised to read and follow these instructions. |
Until now, NotificationAwareDomainMapperMember
in SandboxServices was responsible for eagerly creating 'dormant' NotificationState
records.
These dormant records were effectively 'placeholders' that would not be eligible for send, retry, or even the common 'prune' logic in DataTracking.
The expectation was for downstream operations to on-demand initialize these records for send as needed.
However, this led to a large buildup of NotificationState
instances in the datastore, as if a transition operation was never performed, its NotificationState
would never be cleared.
With this release of SandboxServices, a variety of changes have been introduced to mitigate this problem.
While NotificationAwareDomainMapperMember
will still eagerly create 'dormant' notification states, these changes eliminate situations where records were being unnecessarily created.
Updated NotificationAwareDomainMapperMember
to only initialize NotificationStates
on entities where they are relevant rather than on all entities universally.
For example, the various transition message states like PROMOTE
are only relevant to ChangeSummary
, but were being initialized on all the other domains like ChangeSummaryGroup
and Sandbox
.
By being more intentional about when initialization occurs, we can reduce 'dead' bloat.
Note
|
As part of this change, NotificationAwareDomainMapperMember.setupGeneralNotificationContainerStates() is now a no-op since all other state initializations have been moved to other entity-specific methods.
Please review the latest state of the class if you have overridden it.
|
Updated NotificationAwareMapperMember
to only create SCHEDULE_DEPLOY
notification states for ChangeDeploys
that are being created with the SCHEDULING
status.
This reduces the amount of unnecessary bloat being generated.
Previously, SCHEDULE_DEPLOY
messages were being created for all ChangeDeploys
, but only being initialized for send for SCHEDULING
ChangeDeploys
.
With these changes, creation and initialization of the state are both gated on the SCHEDULING
status.
These changes are focused on adding a scheduled mechanism to purge dormant notification states after a certain time period.
Introduced a new SandboxNotificationPruneRepository
that will delete 'dormant' NotificationStates whose ULID timestamps match a value older than a configurable cutoff
Introduced a new SandboxNotificationPruneService
that will engage the repository purge logic on a scheduled basis
Note
|
Please also see the configuration properties documentation. |
Important
|
As there was no previous mechanism to purge 'dormant' |
NotificationState
records must be presentMany existing operations in SandboxServices were assuming the eagerly created NotificationState
records were always present, and would not succeed if they were missing.
These changes update those operations to gracefully handle the case when no eagerly created records exist.
This is particularly important with the introduction of the above-mentioned scheduled purges of dormant states.
Modified JpaCustomizedChangeSummaryRepository#batchUpdateNotificationStates
to insert new NotificationState
records when they are missing instead of assuming they always exist.
This assumption was already failing in certain niche cases, but is even more important to resolve with the new purging logic.
Introduced a new overload of the updateVals()
method in the ChangeSummary
service and repository that can insert a notification state if it does not already exist, and update DefaultIndexNotificationService
to use this new method.
As a result, the flow will still work even if there is no eagerly created BATCH_INDEX_REQUEST
notification state available.
Introduced a new overload of the updateVals()
method in the ChangeDeploy
service and repository that can insert a notification state if it does not already exist, and update DefaultDeploymentRequestHandler
to use this new method.
As a result, the flow will still work even if there is no eagerly created UNSCHEDULE_DEPLOY
notification state available.
We lean into this by updating NotificationAwareDomainMapperMember
to no longer initialize UNSCHEDULE_DEPLOY
notification states in any capacity.
Addressed an issue where Instant to JDBC Timestamp conversion logic specifically in JpaCustomizedChangeSummaryRepository
was using a locally generated timestamp instead of converting the actual input value
Consolidated Instant to JDBC Timestamp conversion logic in various repositories to a new JdbcConversionUtils
class
Fixed a bug where SANDBOX_DELETE
notification states were being created, but never initialized in a way that would make them eligible for message send retry.
If the explicit first-time notificationManager.handle()
call failed, the notification state would never be found by the scheduled retry handler because its fields were insufficiently initialized.
With the latest changes, the SANDBOX_DELETE
state is now created and initialized only in the NotificationAwareDomainMapperMember.deleteMap()
method, which engages at the time someone actually deletes a Sandbox
.
Fixed a bug where sandboxIndexThreadPoolTaskExecutor
bean was not overridable by clients
A new scheduled job that will purge (hard delete) any PriceDataUsageDetails
that are older than 30 days was added, which will run every day at midnight by default.
The usage date threshold can be configured via the purgePriceDataUsageDetailsOlderThan scheduled job detail.
Please refer to Purge PriceDataUsageDetails Scheduled Job for more details.
Users can now view the execution details of any scheduled job similar to that of Import/Export and Reindex jobs.
Execution details like Trigger Time, Start Time, End Time, Execution Status, Notes and Errors can be viewed. This is supported by the new domain ScheduledJobExecutionDetail
.
A new flag trackExecutionDetails
has been added to the ScheduledJob
domain to enable/disable tracking of execution details.
On the Admin UI, a new section Execution Details is displayed when the trackExecutionDetails
flag is enabled. It contains a grid that displays the execution details of the scheduled job as shown in the screenshot below.
This is powered by the new ScheduledJobStartedEvent
and ScheduledJobCompletedEvent
events that are published when a scheduled job starts and completes respectively.
As an example, the PURGE_PRICE_DATA_USAGE_DETAIL
scheduled job has been configured OOB to track its execution details. Any scheduled jobs that you desire to track the execution details of would have to be
explicitly enable and add logic to opt in.
Enable the flag trackExecutionDetails
for the scheduled job.
Add the following spring cloud stream binding in the service where the scheduled job listener is located:
Add ScheduledJobStartedEventProducer
and ScheduledJobCompletedEventProducer
to @EnableBinding
in the
AutoConfiguration class.
Lastly, update the scheduled job listener wire the producers and add the methods for tracking the start and end times of the job.
spring:
cloud:
stream:
bindings:
scheduledJobStartedEventOutput:
destination: scheduledJobStarted
scheduledJobCompletedEventOutput:
destination: scheduledJobCompleted
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
Within Search, the ability to boost documents based on certain field criteria was added. This functionality is supported with the new domain, Relevancy Rules, and is supported per Search Settings. This allows the Relevancy Rules to be configured per Application & settings context (Admin or Storefront).
Additionally, the ability to see boosted scores for Solr documents was added via a parameter on the Search Request.
For further documentation, see:
New Permissions are required for working with the new domain in the Admin.
Note
|
This step is not necessary if running Project Initializer’s data module |
-- Scopes
INSERT INTO BLC_SECURITY_SCOPE (ID, NAME, OPEN) VALUES ('-511', 'RELEVANCY_RULE', 'N');
INSERT INTO BLC_SECURITY_SCOPE (ID, NAME, OPEN) VALUES ('-512', 'RELEVANCY_RULE_GROUP', 'N');
-- Permissions
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-515', 'N', '1970-01-01 00:00:00.000000', 'ALL_RELEVANCY_RULE', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-516', 'N', '1970-01-01 00:00:00.000000', 'READ_RELEVANCY_RULE', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-517', 'N', '1970-01-01 00:00:00.000000', 'ALL_RELEVANCY_RULE_GROUP', 'N', 'Y');
INSERT INTO BLC_USER_PERMISSION (ID, ARCHIVED, LAST_UPDATED, NAME, IS_ACCOUNT_PERM, USER_ASSIGNABLE) VALUES ('-518', 'N', '1970-01-01 00:00:00.000000', 'READ_RELEVANCY_RULE_GROUP', 'N', 'Y');
-- Permissions Scopes
INSERT INTO BLC_PERMISSION_SCOPE (ID, PERMISSION, IS_PERMISSION_ROOT, SCOPE_ID) VALUES ('-511', 'RELEVANCY_RULE', 'Y', '-511');
INSERT INTO BLC_PERMISSION_SCOPE (ID, PERMISSION, IS_PERMISSION_ROOT, SCOPE_ID) VALUES ('-512', 'RELEVANCY_RULE_GROUP', 'Y', '-512');
-- Role Permissions
-- Full Access
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-2', '-515');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-2', '-517');
-- Partial Access
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-1', '-516');
INSERT INTO BLC_ROLE_PERMISSION_XREF (ROLE_ID, PERMISSION_ID) VALUES ('-1', '-518');
-- Client Scopes
INSERT INTO BLC_CLIENT_SCOPES (ID, SCOPE) VALUES ('openapi', 'RELEVANCY_RULE');
INSERT INTO BLC_CLIENT_SCOPES (ID, SCOPE) VALUES ('openapi', 'RELEVANCY_RULE_GROUP');
-- Client Permissions
INSERT INTO BLC_CLIENT_PERMISSIONS (ID, PERMISSION) VALUES ('openapi', 'ALL_RELEVANCY_RULE');
INSERT INTO BLC_CLIENT_PERMISSIONS (ID, PERMISSION) VALUES ('openapi', 'ALL_RELEVANCY_RULE_GROUP');
Add backend support in Search for handling the Recommendation Engine.
This introduces new domains and inter-service calls utilized by the Recommendation Engine to be utilized in search operation e.g. the SearchRecommendation
domain or the ExternalRecommendationProvider
.
See the Recommendation Engine documentation for more details.
Automatically delete Facets and Sort options after deleting a related Field.
The broadleaf.search.auto-delete-related-search-entities=true
property is used to enable or disable this feature. It is enabled by default.
Added a configurable delay between start times of indexer threads to spline CPU spikes during the initial launch of index thread executors
The broadleaf.indexer.pause-between-threads-start
property is introduced, default is 2000 ms
Added additional customizability around Field Sorts.
Field Sorts can now be individually labeled for ascending and descending options and can be restricted to only ascending or only descending.
Added additional event handling for indexing products so they can correctly show up in the back end sorting views before promoting.
Added a delay between the start of indexing threads to reduce overlap of threads occurring at the same time.
See the Indexer Properties Configuration Properties for details and configuration.
Replaced instances of isForceCatalogForFetch
with isForceFilterByCatalogIncludeInheritance
due to deprecation.
This should be updated in any customizations when upgrading to this version.
Added logic and changelogs to allow Search to utilize applicationName
and apply narrowing to it.
This is mainly utilized to help functionality around Tenant level order views.
Updates the BLC_FIELD
table changelog so the entries can correctly be populated.
Added an optimization which determines if microservice interlink requests should be optimized with a direct method call when the targeted service is colocated in the same flexpackage. This saves on expenses related to socket creation, json serialization/deserialization, and SSL encryption and handshake.
Utilizes an optional property broadleaf.indexer.catalog.service.loopbackOptimizationEnabled
which is enabled by default.
This is must be paired with a property outlined in 2.0.5 MicroExtensionCommon.
Fixed an issue where pending marketplace catalogs would not surface products in the Admin application for the parent.
Removed wildcard characters from groupIndexableType
equals filters to prevent the filter from acting as a "like" instead of "equals".
Fixed a bug where a decoder would throw an error when encountering a %
for a Solr filter.
Added the ability to override locale in search requests to fix an issue where translations would not show up for Facets in the Admin list grids.
Fixed a NPE issue in the DefaultDocumentBuilderHelper
where a rootObject
could be null
and unchecked.
Fix search of products from marketplace catalogs with pending status in admin and storefront context
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
Added new field DEFAULT_APPLICATION_ID
to the BLC_TENANT
table. The field value is used to pre-select application on user sign in. This setting can be overridden on user level. Makes sense only when user has access to applications and has applications assigned.
Removed the Content > Profiles view from the admin.
This view is chiefly utilized by Tenant users to configure profiles for Applications and did not make sense to surface to application level admins.
Added null handling on CatalogRef filters to prevent null value issues when reading from the DB.
Important
|
This is only relevant if |
As of TenantServices 1.7.15+, 2.0.1+, and 2.1.0+, when a vendor catalog is assigned as one of an application’s isolated catalogs, the implicit catalog created for the relationship will also have its Catalog.vendorRef
set to match its parent.
With these changes, we also included a migration script, which is responsible for ensuring any existing implicit catalogs in the datastore also have their vendorRef
values correctly initialized.
If you have not already done so at the time you upgraded to one of those previous versions, please ensure to run that migration script now (it should still work on the current release). The changes in the current release rely on the datastore state being correct.
In the current release:
Updated the metadata to automatically filter/include vendor catalogs in the lookup results when assigning catalogs to an application, depending on the value of broadleaf.common.data.application.configuration.allow-vendor-catalog-in-application-isolated-catalogs
If you were previously overriding the metadata for this purpose, you can now remove your customizations as the default lookup should handle both scenarios
Relax the validations around vendor catalog assignments as isolated catalogs
Vendor catalogs can now be 'visible as assigned'
Vendor catalogs no longer have to be 'excluded from add'
Webhook handler changes to support CAPTURE_FAILED, REFUND_FAILED, and REFUND_REVERSED webhook events.
Fixed a bug where Adyen Paypal Express Checkout was using subtotal instead of transaction total to account for discounts.
Fixed Adyen provider URL configuration issues.
Fixed an issue when the "paymentPspReference" value is incorrectly set when using the AUTHORIZE_AND_CAPTURE transactions with 3ds verification or other external interaction.
Use REQUIRES_HOSTED_PAYMENT_PAGE_INTERACTION
failure type instead of REQUIRES_EXTERNAL_INTERACTION
to fix an issue with Klarna payments.
Fixed an issue where the failure type is incorrectly determined for the Klarna payment.
Added fix for webhook handling of Authorize & Capture Transaction type during transaction result updates.
Forward-compatibility to support new concepts from OfferServices 3.1.0 and PricingServices 2.1.0
Updated Cart
and CartItem
to support recurring/usage prices, recurring discounts, and free trials
Update DiscriminatedProperties
to utilize CaseInsensitiveMap
when binding application and tenant ID property key prefixes
This ensures properties supplied via YAML vs environment variables are not treated as separate properties purely due to a case mismatch.
Introduced a new CartItem
type for non-catalog items
The 2.x versions are Spring Boot 3 compatible.
Audit update fields are populated on create. This is controlled by a broadleaf.common.data.application.configuration.populate-audit-update-on-create
property, default false
Added support for a single sort across multiple columns based on select case.
Added support for modernization of Billing Service.
Supports optimized converter based mapping in ModelMapper flows
Supports an explicit mapping pattern with ModelMapper, required to provide better performance
Added support for imported entities with no changes
Added support for conjunction in the JPA RSQL criteria builder.
Updated ModelMapper cache to not cache entities that don’t have a projection domain.
Usages of forceCatalogForFetch
in DefaultTrackableDomainMapperMemberSupport
were updated to use forceFilterByCatalogIncludeInheritance
.
Fixed FilterAndSort
issue causing Catalog Access Policies targeting the Product#brand
to not apply.
Fixed issue where LinkedField
cannot be found if "rootType" is an extended entity.
Fixed export and other operations to include catalogs with "PENDING" status, since they are called from the admin context.
Added a new PendingCatalogInclusionContext to dictate when to include pending catalogs.
Additionally, added a utility proxy contract to check if in an Admin context from Data Tracking, since Data Tracking does not rely on Broadleaf’s Security library.
Improved the randomness of IDs generated by UlidIdentifierGenerator
Improved NotificationState to be consistent and deterministic during resolution, by applying a sort on the id when there are multiple matches for a given message type.
Added handling for null catalog inclusion and exclusion filters.
Added serialization to emit JSON for the amount field and ignores the currency, to avoid currency mismatch errors.
Provides a relaxed field comparison pass in ContextStateBuilder should the normal first pass fail.
Fixed an issue where extremely large queries could be built through the narrowing process, causing performance issues in some cases.
Archived items are excluded from being utilized in the JpaNarrowExecutor
in order to reduce the query size.
Fixed a bug that occurred when importing a product update with no changes, the product didn’t show up in the list grid.
Updated AbstractImportBatchHandler
to replace usages of the deprecated property userSandboxPersistenceNotificationEnabled
with the new property persistenceNotificationEnabled
.
Introduce support for sorting on multiple columns.
This changes the behavior to no longer throw an exception if the Order object encountered is not a JpaPath instance and instead ignores instances of SqmCaseSearched
Also adds a specific InvalidSortOrderException
to throw if the order is invalid, as the IllegalStateException previously thrown is logged at the debug level by default
Added support for shortening of index names by introducing annotation for index aliasing.
Updated our custom hibernate set-based UserType, AbstractSetType
, to correctly escape single quotes and wrap the string literal in single quotes when toSqlLiteral
is called.
Added entity utils to aid partitioning requests and prevent overflowing database in-clause size limits.
Introduce rowMessage
concept to Grid
.
Introduce support for a 'notification' message type in Messages
/MessageTypes
.
Introduce SlideOverFormAction
concept.
Update ResidentGridField
to have CREATE_VIEW
and UPDATE_VIEW
action types.
Update PropertyConditional
to support empty
, notEmpty
, and blank
conditions.
Introduce maxRows
concept to FieldArrayGridField
.
Introduce Orderable interface to FieldArrayGridField
.
Introduce new enums, properties, and form fields to support new PriceData concepts from PricingServices 2.1.0.
Added first class support for allowCustomFields
attribute for rule and query builders.
Introduce new metadata dsl for EntityAssetCollections to make use of new drag-and-drop sorting in the admin.
Added custom CSS support to grids.
Added metadata changes to allow hints and help texts on select grids.
Introduce support for InlineGridSelectAction
that will display a list of options to select from.
Added conditional price data view types to split subscription and non-subscription price data metadata components.
Updated pricing metadata to support various pricing strategies.
Added auditable
behavior attribute flags for metadata components.
Fix behavior of orderable, selectable, and sortable grid options
A bug in this behavior caused some grids to not be disabled when set as disabled in the metadata.
Add explicit support for EnumSwitchField.
This is a special field used to display enumerated values in a boolean-like toggle switch.
Added support to MoneyColumn
to display simple values.
This makes it comparable with MoneyField
to allow displaying decimal fields that inherit currency from the parent entity.
Introduced AddAdjustmentModalFormAction
as secondary action for the UpdateEntityView
.
Added a secondary action to display a basic modal form with submit support.
Registered a new FORM
secondary action for entity views that simply renders a form configured via metadata and allows submitting to an endpoint.
Enhanced the default ComponentRegistry to register components with case-insensitive keys.
Fix a bug where an infinite loop can occur in ProjectionManager
at startup if a projection class is more than 2 levels descended from Object
Added support for modernization of Billing Service.
Add billing & subscription operations data routes
Support ordering of spring cloud stream consumers
Add diagnostic logging for message send failures
Improved the environment report to skip any unresolvable properties.
Improved service-to-service calls within a single flex package to skip overhead of external calls.
Added support for optional direct method call in loopback interlink scenarios
Disabled by default, see com.broadleafcommerce.common.extension.intercommunication.ExternalClientProperties
for details on enabling.
(not a code change) Updated Javadocs in JpaCustomizedResourceLockRepository
to clarify the motivation behind the custom Instant
to JDBC-compatible Timestamp
conversion.
Added support to track execution details of scheduled jobs.
Added new domains (ScheduledJobCompletedEvent, ScheduledJobExecutionDetailRef, ScheduledJobStartedEvent) and updates to ScheduledJobRef
Added the message producers and a utility class to help facilitate opting into this feature for any scheduled job listeners
Improved NotificationState to be consistent and deterministic during resolution, by applying a sort on the id when there are multiple matches for a given message type.
Update the SuppressNotificationContext
to inherit previous context state if it exists.
Forward-compatibility to support new concepts from OfferServices 3.1.0 and PricingServices 2.1.0.
Introduce support for recurring prices
Introduce support for free trial and recurring adjustments
Added offer code reference to the Voucher
so its usage will be audited for max usage.
Added ItemProrationDetail
for gift items to support items that are automatically added but have a fixed price "gift fee".
Forward-compatibility to support new concepts from OfferServices 3.1.0, PricingServices 2.1.0, and Inventory Services 2.1.0.
Introduce new PENDING_INVENTORY
value to OrderFulfillmentStatus
Introduce recurring and usage price concepts to OrderItem
Forward-compatibility to support concepts from OfferServices 3.1.0 and PricingServices 2.1.0.
Introduce 'adjustment type' concept to Adjustment
to drive when the adjustment applies
Add fields to support 'free trial' concept in Adjustment
Add fields to support recurring discount begin/end periods in Adjustment
Introduce RecurringPriceDetail
and UsagePriceDetail
Added offer code reference to the Voucher
so its usage will be audited for max usage.
Added @JsonAlias to the "amount" field on Adjustment
to also consider "adjustmentAmount" for deserialization.
Changes to support modernization of Billing Service.
Added currentBillingAttemptNumber
to the payment request
Introduced ADD_TO_BILL
payment type
Update DiscriminatedProperties
to utilize CaseInsensitiveMap
when binding application and tenant ID property key prefixes
This ensures properties supplied via YAML vs environment variables are not treated as separate properties purely due to a case mismatch.
Added support for receiving updated transaction results through the webhook.
Introduced UPDATED_TRANSACTION_RESULTS
as a supported webhook notification type
Added isSupportedTransactionUpdateType
method to the PaymentGatewayWebhookHandler
interface
Forward-compatibility to support new concepts from PricingServices 2.1.0.
Added domain support for recurring and usage composite price details
Added support for Flash Sale. (PriceList price limited quantity)
Please refer to the Flash Sale Documentation for more information.
Add new domains and enums to support price data limited by quantity
Add enums and request/response DTOs used for recording price data usages
Update DiscriminatedProperties
to utilize CaseInsensitiveMap
when binding application and tenant ID property key prefixes
This ensures properties supplied via YAML vs environment variables are not treated as separate properties purely due to a case mismatch.
Fixed SimpleTaxProvider
calculation of tax total amount, taxable amount, and tax exemption.
(New!) TMForum Extensions Module 1.0.0
Please review the overview page for this module for more information