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. |
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. |
To review the security related content, see 2.1.4 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. |
Introduced a new drag-and-drop component for Product Assets. Note: This feature is disabled by default, as assets need a predefined sort order to display correctly. For more information, see CatalogServices Release Notes.
Introduced new components for managing characteristics on products. See: CatalogServices Release Notes.
Added support for slide-over update and create forms:
* UPDATE_VIEW
as a row action
* CREATE_VIEW
as a grid action
SELECT_LIST
Added a SELECT_LIST
field type to allow users to choose from a list of options (e.g., variants when creating a product).
The Content Item form now includes a Base URI
field, displaying the model’s URI if accessible.
When cloning a content item, the cloned item now automatically opens for editing (unless marked as embedded).
Added a modal for selecting the content model when creating a new nested content item, replacing the previous dropdown selection.
The create/edit form now includes a default application field, used for pre-selecting an application on user sign-in. Note: This is only relevant if the user has assigned applications.
A new "My Profile" option was added to the user drop-down menu, allowing users to update their email, phone, and default application.
Support for the new Remember-Me Login feature:
* useKeepSessionAlive
now silently extends the session when a remember-me cookie is available.
* If the maximum session expiry date is reached, a modal prompts the user to log out or restart the session.
* If no action is taken, the user is logged back in automatically.
* New configurable settings:
- VITE_AUTH_PROVIDER_OAUTH_REMEMBERMEURL
(default: /auth/remember-me-continuation
)
- VITE_AUTH_PROVIDER_OAUTH_HEADERS_REMEMBERMEAVAILABLE
(default: X-Remember-Me-Available
)
Added "Data Driven Enums" as a field type for entity creation.
Enhancements to FieldArrayGrid
:
Introduced drag-and-drop reordering.
Improved UX for adding new items.
Added a save/discard prompt before promoting changes.
Enhanced pagination details for admin grids.
Added custom CSS support for admin grids.
Introduced a new action type (INLINE_GRID_SELECT
) that renders a select box and fires an endpoint when the value changes.
All field components now save their label from metadata as the custom field label.
TextAreas in the admin are now resizable.
Updated ActionListGridFormRowAction
initial value mapping to allow row data to be used as the root for the initial values object used in the context request and the ModalFormAction
for the row.
This is enabled by adding the useRowAsRootInitialValues
attribute via metadata and having its value be true
.
Tracking info is also added to the context request when the useRowAsRootInitialValues
attribute is true
.
Registered a new FORM
secondary action component for entity views named EntityModalFormAction
that simply renders a form configured via metadata and allows submitting to an endpoint.
Add changes to allow helptext and hints on select grids and pass along filtering information which should be used when determining inclusions/exclusions.
Fixed ListGridRow
so selected rows can correctly be highlighted in a grid, improving visibility of user’s actions.
Introduced dirty state tracking for form fields in FieldDecorations
and CollectionField
components. This includes determining if a field’s current value differs from its initial value and providing a method to revert changes.
* Fields that are changed from their initial value are immediately highlighted and marked as "Unsaved"
* Each field highlight has a Revert icon that allows users to click it to revert the change
Implemented exponential polling for metadata changes when loading BusinessTypeFields component.
Exponential polling increases the delay between poll requests at an exponential rate — after each failed request, the next request delays by a multiple of the previous attempt time, and so increases with each failure.
Implemented Workflow sub-views for Order Fulillment
Registered existing blFulfillmentViewBody
as FULFILLMENT_SUMMARY
view to allow it to be used as a view in metadata
Use new blFulfillmentViewSection
component to render sub-views for FulfillmentView
like blOrderViewSection
does for OrderView
.
Enabled via an attribute on FulfillmentView
, supportViewsForBody
, or else the old behavior with no sub-views is used
Added blFulfillmentViewNav
sub-component of blFulfillmentViewHeader
to allow navigating between FulfillmentViewSections
Added new FulfillmentWorkflowViewSection
, registered as FULFILLMENT_WORKFLOW
, to support viewing and managing an external Workflow for a Fulfillment.
Supports polling and form components
Establishes form state with following shape (reference Workflow documentation for detailed properties)
interface FormState extends Workflow {
history?: WorkflowHistory;
orchestrationMap?: SimpleOrchestrationMap;
tracking: Tracking;
}
Introduced actions to issue commands to the workflow update endpoint that are expected to be rendered on the RESIDENT_GRID
representing the SimpleOrchestrationMap
:
WORKFLOW_COMMAND
as a ROW
positioned action
WORKFLOW_COMMAND
as a GRID
positioned action
These actions will have access to:
the React.Dispatch
for managing the Workflow’s state with the following state actions:
queueFetch
to queue fetching the full workflow, fetching history and the orchestration map will happen automatically after fetching the workflow.
startFetch
to indicate the fetch for the Workflow is taking place
startFetchHistory
for History
startFetchOrchestrationMap
for the SimpleOrchestrationMap
successFetch
to indicate the Workflow was successfully fetched, the Workflow is passed as an argument
successFetchHistory
for History
successFetchOrchestrationMap
for the SimpleOrchestrationMap
failureFetch
to indicate the Workflow was not successfully fetched, the Error
is passed as an argument
failureFetchHistory
for History
failureFetchOrchestrationMap
for the SimpleOrchestrationMap
ContextParams
with the following shape, users can use this to determine what template variables are available, e.g., ${workflowId}
in /workflows/${workflowId}
interface IFulfillmentContextParams {
tracking: Tracking;
id?: string;
parent?: OrderFulfillment;
fulfillment?: OrderFulfillment;
fulfillmentId?: string;
orderId?: string;
workflowId?: string;
workflow?: Workflow;
}
Each takes the following attributes via metadata
iconColor
: The color of the icon, primary, secondary, danger, and default
iconName
: The name of the icon to render for the command if any. See new reference in Developer Settings modal for options.
commandType
: The command to issue against the Workflow such as GOTO
, PAUSE
, RESUME
, or CANCEL
EnumSwitchField
is undeprecated
Added displaySingle
attribute to allow a better read-only experience. In this case, only the current value is rendered. This allows the configured color for the value to render instead of being greyed-out.
Fixed warning about formik state missing for TimeZoneSelector
field in Admin header.
Added support for rendering GRID
positioned actions on all list grids conditionally
Added section to Developer Settings modal to show the list of all icons supported by the SVG component. This renders a collapsible group with the icon displayed next to its key. The key is used to actually render the icon. This supports users who want to create their own components that use icons as well as as a reference for existing components that support setting the icon name as an attribute like the new WORKFLOW_COMMAND
actions.
<SVG name="dots-horizontal-triple" />
Improved rendering of JSON_PAYLOAD
fields so that their label styles match other Field type components'. Before they were always extra large and bold, which is only appropriate when the JSON_PAYLOAD
field is used to represent the payload for the entire entity not just a single field.
To render with the bold style requires that the field name is jsonPayload
. This is generally only applicable when EntityForm#showPayload
attribute is true
Enabled overrides for the following OMS components to make extending easier:
OrderViewLayout
: blOrderViewLayout
OrderViewHeader
: blOrderViewHeader
Implemented Workflow sub-views for Subscription.
Registered new component WorkflowDetailView
as WORKFLOW_ENTITY_FORM
view to allow it to be used as a view in metadata
Use new WorkflowDetailView
component to render generic Workflow sub-views for any view or entity.
This component is leveraged to display Workflow details in a slide-over component for Subscription Workflows, and are displayed when the details button is clicked for an entry in the Subscription Workflow grid in the Subscription Update form.
Updates were made to EntityView
components such as Entity
, Content
, Layout
, Header
, and TitleBar
in order to pass in nested
, nestedCallback
, and nestedCancelCallback
props in order to display the proper type of exit button in the TitleBar
when the Entity
is nested or not.
By default, nested
is false
and will have a BackButton
displayed in the TitleBar
which when clicked will signal to the React Router to go back to the indicated location in the state. If the Entity
is nested, a CloseButton
is displayed in the TitleBar
that when clicked will merely close the nested view component that is overlaid over the main view component.
Fixed how collections are handled in the entity creation flow.
Fixed reordering on grids when implicitFilters
are absent.
Grids now determine their initial state correctly.
Fixed dropdown field display within nested content items.
Fixed an issue where conditionally hidden list grid columns still occupied space.
Fixed an issue where cloning content with an empty URI field set the value to undefined-copied
.
Fixed deeply nested content items not being tied to the correct parent in sandboxing.
Fixed an issue where changing a content model’s field to a collection could break existing content.
Fixed styling for help texts.
Fixed z-index issues with select dropdowns and HTML editor tools.
Fixed display issues with the settings dropdown.
Fixed 403 Unauthorized
errors caused by incorrect cache values.
The page now fully reloads when changing the admin’s time zone.
The Deploy button is now hidden when the user lacks deployment permissions.
Fixed an issue where the Promote action was not visible after product option generation.
Fixed an issue where Product Types appeared editable when they were not.
Fixed a crash on the order details page due to an undefined total.
Inventory checks in the fulfillment status change modal now only run when the status is PENDING_INVENTORY
.
Fixed an issue where filtering by a boolean field did not apply correctly.
Fixed an issue with product faceting when facet values contained a %
character.
Fixed issues with exports when grid filters were applied.
Fixed an error when using the filtering with Non-Latin script, such as Arabic.
Fixed an issue where translations were allowed to be made for characteristics with no values and numeric or boolean type characteristics, which causes an exception
Fixed integer fields not being cleared when a default value was set.
Fixed issues with the ToggleSwitch
component’s tab index, improving keyboard navigation.
Fixed case sensitivity in admin routes.
Fixed an issue in ExternalAssetCollection
to inform the component to use the asset’s contentUrl
instead of its url
when viewing an asset’s details.
Fixed an issue where Business Type Modify and Create forms were being fetched before they were created.
Fixed an issue where the Quantity Selector in Fulfillment Workflow modals was being styled incorrectly due to undefined
class names being passed into the component.
Fixed issue where Subscriptions were being marked as non-mutable by removing application data from context parameters when the applicationDiscriminated
attribute is explicitly false for EntityGrid
and EntityLongView
components.
Changes to support the new Remember-Me Login feature. Visit the Auth React documentation for more details on this feature.
Add a new redirectToRememberMeUrl
method accessible through the useAuth
hook.
Updated the SessionExpiry
type to include a rememberMeAvailable
boolean denoting whether a remember-me cookie is available.
Introduced new handling for invalid_grant
errors coming from requests to get new access tokens. Visit the cross-origin support section for more details on this flow.
Upgraded Axios dependency.
Updated type documentations.
Tip
|
This release is compatible with Release Trains in the 2.1.x line. |
Increased the supported Node.js version to include Node 20.
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.
Increased the supported React version to include Node 18.
No migration or code changes required.
Improved null
safety by adding optional chaining to various parts of the storefront, specifically for when Fulfillment Groups are undefined or when Select
fields have no options.
Changes to support new Remember-Me Login feature.
Added a modal to prompt the user to log out or stay signed in when the end of session is about to be reached. If no action is taken by the end of the session, the user is automatically signed back in. This leverages the new /remember-me-continuation
endpoint. This modal behavior will only engage when all the following conditions are met:
Refresh token rotation is disabled
This is configured via property NEXT_PUBLIC_AUTH_USE_REFRESH_TOKENS
, which has a default value of false
.
Remember-Me is currently enabled by the user
The user’s maximum session expiration is about to be reached
This value can be configured with NEXT_PUBLIC_EXPIRATION_COUNTDOWN_INTERVAL
, which has a default value of 180000 ms
.
Note
|
This implementation relies on a non-cross-origin setup, reason for which it is only engaged when the refresh token rotation is disabled. For more information on how Remember-Me Login works in a cross-origin setup, visit the Auth React documentation |
Anonymous CSR user now treated as a guest customer on site
Added missing fields that were preventing adding billing address for a customer account
Fixed UX issues with the edit Roles selector for Account Members
Expanded the Roles selector component when the list grows to better see the roles
Fixed an issue when the selectors' dropdown does not highlight which roles are already selected once the user has multiple roles
Fixed an issue when a user can’t remove previously added roles because the dropdown does not know which roles are already selected
Fixed stuttered loading behavior on the PDP by fixing the loading procedure of components on the page
Fixed alignment issue of select fields across the storefront
Fixed issue where the CSR price override was throwing a currency mismatch error due to the override request not including the desired currency for the cart and fulfillment prices
Fixed visual bug where the sale price blinks in and out while fetching the contract price
Disabled looping in the Product slideshow by default
Implemented fixes to prevent incorrectly redirecting to sign in when authentication is still loading, and decreased page reloads to trigger when the account has been updated
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. |
Important
|
The Remember-Me implementation requires the Liquibase schema changes defined below. Even if Remember-Me is disabled, these schema changes must be applied - they will just be dormant/unused until the functionality is enabled. |
Important
|
To pair with these changes, clients are recommended to update their frontend projects to the latest versions described in the 2.1.4 Release Notes and Upgrade Guide. These include enhancements to frontend session management that incorporate information about Remember-Me availability for a better user experience. |
With this release, AuthenticationServices now supports Remember-Me when using the Centralized Universal Login approach.
Remember-Me functionality is disabled by default, making it opt-in rather than opt-out.
Please see the full details about the Remember-Me feature.
Fixed recurring issues with Segment ID Persistence.
Updated to store to the user attributes the last time the user was updated for a specific segment, rather than a general last updated date.
Increase JpaUser#attributes
column length to 4000.
Fixed a bug where if the user doesn’t have the ALL_SANDBOX permission, the changes get deployed straight to production.
Added a new endpoint to allow Admins to send out a reset password email for another admin.
Added new pricingclient
with ORDER
and TENANT_CART
scopes.
Added new scopes and permissions to bulkopsclient
to support new category product membership functionality
Add data exchange permissions for comprehensive product and data exchange client
Fixed scope filtering to correctly account for scopes that are not named the same as permissions
Added an extra nonce validation in /consume-token
endpoint to verify the current authentication matches the one specified in the signedJwt
Added support for scopes and permissions in workflow and audit flows
Fixed a bug where the BLSR
cookie was not being cleared properly on requests to OAuth2 protocol endpoints. The RequestCacheAwareFilter
is now ordered higher in the authorization server filter chain to ensure it applies before the protocol filters engage.
Fixed a bug where 'prompt=none' authentication failure redirects were setting the BLSR
cookie, even though they were never actually going to be consumed/cleared.
The OAuth2AuthenticationEntryPoint
now ensures this cookie is cleared in such a case before proceeding.
Added new field DEFAULT_APPLICATION_ID
to the BLC_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.
Note
|
This requires the Liquibase schema changes defined below. |
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 Authentication 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. |
Improved performance of the query to select Carts by adding a new compound index (TRK_TENANT_ID,TRK_ARCHIVED,STATUS,TYPE,EXPIRATION_DATE)
to the BLC_CART
table
Added a new field failureType
on the CheckoutRollbackEvent
that includes a reason for the failure for the step within the checkout workflow
Tip
|
The 2.x versions are Spring Boot 3 compatible. |
Added support for Flash Sales (PriceList price limited by quantity). Please refer to the Flash Sale Documentation for more information.
If the applicable PriceInfo
for a CartItem
is limited by quantity and the quantity of the CartItem
exceeds that limited quantity, the CartItem
will be split into a pair following the logic in this example:
If a sale PriceInfo
only has 2 quantity available and the CartItem
has a quantity of 3, it will be split into a pair of CartItems
with quantity of 2 and 1.
If a sale PriceInfo
only has 2 quantity available and the CartItem
was added to cart 3 separate times, meaning the cart has 3 CartItems
each with a quantity of 1, it will be combined into a pair of CartItems
with quantity of 2 and 1, with 2 of them using the sale PriceInfo
, and 1 using the backup PriceInfo
.
Added a new checkout activity to validate and record the PriceData
usage for PriceData
that are limited by quantity
The PricingService
will check the availability of those limited PriceData
usage, and check the active dates for those applicable PriceData
as well as those of the PriceList
. If any of the PriceData
is unavailable, the entire request is marked as failed. If applying the PriceData
is unsuccessful (e.g. the price data is no longer available or expired), the Cart
is re-priced and a cart alert is shown to notify the customer of the price change.
Added implementation to populate a Variant’s tags onto the Cart to support Offers that are targeting variant-level tags.
Added support to allow a bundle or a non-individually-sold item to be added to cart if it’s a Free Gift item.
Updated the Record Price Data Usages endpoint configured path.
Added a allowPartialQuantityForPriceLimitedByQuantity
property via the CartOperationServiceProperties
for DefaultCartPricingService
to use to control whether partial quantity is allowed for a price limited by quantity.
For example, if a sale price only has the available quantity of 2, and the customer has 5 of the items in the cart, 2 of them will use the sale price and the remaining items will use the backup price if this property is set to true
. If this property is set to false
, then all 5 items will use the backup price.
Updated DiscriminatedProperties
to use CaseInsensitiveMap
when storing the tenant and application identifying 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.
Added support for a generic Non-Catalog Product type
A non-catalog product/cart item represents a product/cart item that does not exist in a catalog. This allows for custom usage of the CartItem
domain and tracking of its instances as line items. These items are included in the cart subtotal and excluded from promotions.
Added a new field failureType
on the CheckoutRollbackEvent
that includes a reason for the failure for the step within the checkout workflow, which will be set when a checkout exception occurs.
Added support for gift items automatically applied to a cart to be allowed to have a set price.
broadleaf.cartoperation.pricingprovider.record-price-data-usage-uri
broadleaf.cartoperation.service.allowPartialQuantityForPriceLimitedByQuantity
See the Cart Operation Property Configurations for more details.
See the Flash Sale Documentation for more information.
Fixed issue where free gift items were not being subtracted from the Cart
subtotal and list of line items used when calculating and applying Offers
.
Fixed issue where Cart
totals were not being recalculated when any free gift items are removed.
Fixed issue where CartItem
dependent items of dependent items were not being priced correctly.
Fixed issue where bundles and their dependent products that were in a catalog and price list with different currencies between them could not be added to the cart by causing a currency mismatch.
Fixed issue where a FulfillmentOption
was being added to VIRTUAL
type fulfillment groups when using FulfillmentServices
with its PricedFulfillmentOption
.
Fixed variant-level sale price currency mismatch issue by updating the pricing info in the cart item’s internal attributes to match the prices during repricing.
Fixed issue where Order Adjustments were not properly prorating.
Fixed issue where voucher offer usage was not being recorded, which caused the maximum uses restriction to be broken.
Fixed issue where if a user removes the "gift" from their cart, the offer can never be re-applied for the lifetime of the cart — now if the user removes all qualifier items from their cart, the offer can be re-applied.
This behavior is controlled by the CartOpsPromotionProperties#giftOfferEligibleIfQualifierRemoved
property, which is true
by default.
Fixed issue where pagination requests were being serialized incorrectly, and page responses were deserialized incorrectly.
Fixed issue where a stale cart check does not take into account and remove deactivated Variant products.
Fixed issue where a failure in DefaultCheckoutService#createOrderNumber
method doesn’t create an order but still charges a payment.
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+
This version requires SearchService 2.1.4+
Added a new readAllDataDrivenEnumTypes
endpoint to retrieve distinct DataDrivenEnum
types with additional service and repository implementations.
Added support for fetching parent Category hierarchies.
Added caching configuration for the DefaultCategoryService#readCategoryParentHierarchy
method, which defaults to 30 minutes.
Added a categoryIdsWithParents
field to ProductDetails
and ProductDetailsContext
to support Offer and Pricing flows with Category restriction targeting a parent Category.
Added native SQL queries to build the Category hierarchy.
Enhanced the Add Product/s feature in the Products tab for a Category to be able to add Category Products via the configured Product Membership Rule.
Updated the Attribute Choice Allowed Values grid entries to be orderable and hid the Display Order field from the Allowed Values grid.
Added caches for efficiency during marketing message retrieval.
Expose the individually sold flag for BUNDLE typed products.
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 created solely for the purpose of being free gifts, and the bundle product itself should not be individually sold nor searchable.
Added the visibility of displayOrder
on the Product Options grid for Products.
Usages of forceCatalogForFetch
were updated to use forceFilterByCatalogIncludeInheritance
.
Introduced support for bulk operations for the new Category membership type of AUTO_INCLUDE
which will add CategoryProducts
automatically when a Product
qualifies according the Product
membership rules.
Updated the Import of Products with assets so that a sorting value is added onto assets upon import.
Introduced support for a new drag-and-drop component for Product Assets.
Introduced a listener and job that will update the sorting on all product assets, as this is required for the drag-and-drop functionality to work as you cannot sort an unsorted asset.
The drag-and-drop functionality is disabled by default, and can be enabled via configuration:
broadleaf:
catalog:
metadata:
drag-and-drop-assets-enabled: true
Introduced three new Bulk Operations:
Set Product(s) as Searchable
Add Product(s) to Category(s)
Remove Product(s) from a Category
Allow for Facet translations to take affect when viewing product list grid by adding the localeOverrideForFacetAndSortLabels
parameter to the Products grid, whose value is expected to be the locale desired to override the default locale.
Updated the BusinessType
domain to contain a new attributes
map to hold custom additional attributes.
Admin metadata has also been updated to introduce this field.
Note
|
See the Schema Changes section below for more information on migration. |
broadleaf.catalog.cache.byCategoryParentHierarchyTtl
Description: Time-to-live for reading categories' parent hierarchy for product-details requests
Default Value: 30 minutes
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.
|
Show a correct change type for bulk operations in the My Changes
view.
Fixed an issue where Products from Catalogs with a PENDING
status could not be exported.
Fix visibility of products from marketplace catalogs with pending status in storefront and admin
Added a PostMapperMember to fix or adjust the currencies on Variants to ensure that they use their parent product’s currency by default, rather than some other currency.
Fixed an issue where some products would be unable to correctly be added to a category.
Fixed issue where custom fields for Business Types were not showing up in Query Builders due to the showInQueryBuilder
field value for custom fields not being persisted.
Fixed issue with Option Template by adding default filtering by selected type for product or variant when configuring Item Choices.
Additionally added a similar fix for Product Options.
Fixed issue where archived Categories were being included when hydrating Category onto a Product being fetched.
Fixed issue where exporting Products with filters applied were not processing correctly — updated the labels and help text of the Product Export grid to explain the Export modal sections and updated the processing to utilize the new information so filtering can be correctly applied.
Fixed issue where cloning a Product causes a validation error due to its minimum and maximum cardinalities to both having default values of 1, because its characteristics are not hydrated prior to the cloning.
Fixed issue where duplicate skus were being displayed for Products with only one variation when creating price data.
Fixed issue where not returning a default SKU for a non-Variant Product leads to the Price Data grid being disabled.
Fixed issue where fetching Data Driven Enums would return archived entries.
Fixed issue where propagating the deletion of a Product through child catalogs includes the implicit catalog of deactivated applications, which causes deployment and indexing failures — updated CatalogEntityDeletedEventHandlers
to skip policy validation in specific cases.
Fixed issue where adding a Single Variation Product Choice to a Standard Product results in an error — added single specific Variant check onto the Variant contributor.
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 Catalog 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. |
Added support for populating parent category hierarchy for Product
Added categoryIdsWithParents
to Product
to support offer and pricing flows with category restriction targeting a parent category
The categoryIds
for the MarketingMessages retrieval flow will now be populated from this field
Updated ContentField#attributes
to be able to persist any object value.
Reduced inter-service HTTPS calls and added support for optional direct method calls for Marketing Messages to enhance performance.
Enable feature for Jackson ObjectMapper
so that query parameters can be converted to DTO when fetching Product Details.
Boolean fields in content model now have a default value option.
Implemented enhancement to display the Content Model Base URI value alongside its own URI when creating and viewing a Content Item.
Updated Content Field Enum options to be orderable.
Added ENUM
type to possible ContentField
types.
Refactored Content cache invalidation to use current standards.
Introduced support for Recommendation Engine Services via Content Item fields.
Added validation to prevent deletion of the content model if it has Content Items.
Fix for content cloning where cloned content promotion can leave some of its parts not promoted
Folders are now sorted alphabetically by default.
Fix for deleted content model fields being saved in deprecated JPA field which causes them to still be displayed.
Fixed issue where a cloned Content Item and its fields are in separate Change Summary groups, and so are promoted separately.
Fixed issue where the tracking data change container ID for an embedded cloned Content Item is not the same change container as the parent Content Item.
Fixed issue where Change Summaries for Content Items embedded in a reusable item were being lost.
Fixed issue where cache was not was being invalidated for updated Content Items when configured to do so.
Fixed issue where cache was not was being invalidated for updated child/embedded Content Items when configured to do so.
Fixed issue where a null
Content Model URI caused a handling exception in displaying the Content Model Base URI value alongside its own URI in the Content Item form.
Fixed issue where Bulk Requests become much slower when previewing because cache is disabled.
Fixed issue where Content Items load slowly due to hydrating when reading Content Items in folders.
Fixed issue where previewing Bulk Requests return inaccurate results due to caching — fixed by accounting for the presence of a preview token in Content Item hydration.
Fixed issue where Content Item hydration is not returned from calling the paged method.
Fixed issue where Content Model ENUM
type fields do not require Labels and cause errors in places of usage where label is expected.
Add support for managing a Customer’s Accounts from the Customer screen via the Accounts tab
Allows the user to update the Customer’s Account Member role, add them to other Customer Accounts, and remove them from Customer Accounts they are members of.
Introduced enhancement to disallow users from editing the User ID attribute field in the Customer form, with validation to prevent updates to the User ID.
Add Query Builder filters to the Customer Browse grid to allow users to filter entries using advanced search features.
Fields that are not indexed in Solr can be searchable in case that Customer Internal Search is enabled.
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.
Added support for startingQuantity
and availableQuantity
for importing PriceData
Please refer to the Flash Sale Documentation for more information.
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.
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.
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
|
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.
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+
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.
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. |
Added support for limiting a PriceList price by quantity (Flash Sale)
Added new domains, services, repositories, and business logic to support Price Data limited by quantity
Added business logic used for recording Price Data usages
Added business logic used for Price Info retrieval
Added new attributes to the PriceData
domain:
startingQuantity
- the initial available quantity that it started out with, only used for informational purposes
availableQuantity
- the real-time quantity that indicates how much is left
Added business logic used for PriceData
rollbacks for checkout failures
Added business logic used for PriceData
rollbacks for order fulfillment cancellation
The newly added 'Purge PriceDataUsageDetails' scheduled job will hard delete any PriceDataUsageDetails
that are older than 30 days. This job will run every day at midnight by default. It is also configured to display its execution details in the Scheduled Jobs Admin UI.
Added special handling for rollbacks for PriceDataUsageDetail
when triggered because of 3DS verification
Please refer to the Flash Sale Documentation for more information.
Added new columns to the blc_price_data
table
STARTING_QUANTITY
AVAILABLE_QUANTITY
Added a new blc_price_data_usage_detail
table
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. |
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.