Class DefaultSubscriptionGenerationService<SWI extends SubscriptionWithItems>

java.lang.Object
com.broadleafcommerce.subscriptionoperation.service.DefaultSubscriptionGenerationService<SWI>
All Implemented Interfaces:
SubscriptionGenerationService<SWI>

public class DefaultSubscriptionGenerationService<SWI extends SubscriptionWithItems> extends Object implements SubscriptionGenerationService<SWI>
  • Field Details

  • Constructor Details

  • Method Details

    • createNewSubscriptions

      public List<SWI> createNewSubscriptions(@NonNull @NonNull CreateSubscriptionFromOrderRequest request, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Description copied from interface: SubscriptionGenerationService
      Given the provided Order and its items, creates one or more Subscription and related items. If the subscription already exists, returns it.
      Specified by:
      createNewSubscriptions in interface SubscriptionGenerationService<SWI extends SubscriptionWithItems>
      Parameters:
      request - Request containing the Order with OrderItems representing Subscriptions to create
      contextInfo - Additional sandbox and multitenant info
      Returns:
      the list of the SubscriptionWithItems created.
    • buildSubscriptionWithItems

      protected List<SWI> buildSubscriptionWithItems(@NonNull @NonNull CreateSubscriptionFromOrderRequest request, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Builds SubscriptionsWithItems to be created based on the given Order.
      Parameters:
      request - Request containing the Order with OrderItems representing Subscriptions to create
      contextInfo - Additional sandbox and multitenant info
      Returns:
      list of subscription creation requests
    • updateAdjustmentQualifierDetailRefs

      protected void updateAdjustmentQualifierDetailRefs(List<SWI> subscriptionWithItemsToCreate, @NonNull @NonNull CreateSubscriptionFromOrderRequest originalCreateSubscriptionRequest, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Updates the SubscriptionItemAdjustment.getQualifierDetails() to map to the actual created SubscriptionItem.getId(). This is necessary because the original Adjustment.getQualifierDetails() will reference the OrderItem.getId().
      Parameters:
      subscriptionWithItemsToCreate - the list of SubscriptionWithItems being created
      originalCreateSubscriptionRequest - the original CreateSubscriptionFromOrderRequest
      contextInfo - additional sandbox and multitenant info
    • identifySubscriptionRootItems

      protected Stream<com.broadleafcommerce.order.client.domain.OrderItem> identifySubscriptionRootItems(@NonNull @NonNull CreateSubscriptionFromOrderRequest request, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Identifies the root OrderItems for which to build separate Subscriptions.
      Parameters:
      request - Request containing the Order with OrderItems representing Subscriptions to create
      contextInfo - Additional sandbox and multitenant info
      Returns:
      The root OrderItems for which to build separate Subscriptions.
    • isSeparateFromPrimaryItem

      protected boolean isSeparateFromPrimaryItem(@NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem)
    • shouldCreateNewSubscription

      protected boolean shouldCreateNewSubscription(@NonNull @NonNull CreateSubscriptionFromOrderRequest request, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Hook point to determine whether a given Order has any items representing a Subscription that should be created. By default, a subscription is only created for items that need to be billed recurringly. This method checks whether OrderItem.getRecurringPrice() is not null to determine that for each item.

      IMPORTANT: By default, this method assumes that if any of the dependent OrderItems are subscriptions, then their parent (i.e., the root items on the Order) are also subscriptions.

      Parameters:
      request - Request containing the Order with OrderItems representing Subscriptions to create
      orderItem - the order item that might require a subscription to be created
      contextInfo - Additional sandbox and multitenant info
      Returns:
      whether a subscription should be created for the given orderItem
    • orderItemRepresentsActionToExistingSubscription

      protected boolean orderItemRepresentsActionToExistingSubscription(@NonNull @NonNull com.broadleafcommerce.order.client.domain.Order order, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem)
    • isSubscriptionItem

      protected boolean isSubscriptionItem(@NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem)
    • buildSubscriptionWithItems

      protected SWI buildSubscriptionWithItems(@NonNull @NonNull CreateSubscriptionFromOrderRequest request, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Builds out a SubscriptionWithItems for a given root OrderItem. The root order item informs both the subscription and its root subscription item.

      NOTE: This method assumes that the provided OrderItem is the parent item for any subscriptions with an item hierarchy.

      Parameters:
      request - Request containing the Order with OrderItems representing Subscriptions to create
      rootOrderItem - the order item representing the subscription to be created
      contextInfo - Additional sandbox and multitenant info
      Returns:
      A SubscriptionWithItems for the given subscription OrderItem and its dependents.
    • getCreatedDate

      protected Date getCreatedDate(@NonNull @NonNull com.broadleafcommerce.order.client.domain.Order order)
    • buildSubscriptionAdjustments

      protected List<SubscriptionAdjustment> buildSubscriptionAdjustments(@NonNull @NonNull CreateSubscriptionFromOrderRequest request, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Hookpoint for building SubscriptionAdjustments from an Order. By default, there are no subscription-level adjustments, only item-level.
      Parameters:
      request - Request containing the Order with OrderItems representing Subscriptions to create
      orderItem - the order item representing the subscription to be created
      contextInfo - Additional sandbox and multitenant info
      Returns:
      The list of SubscriptionAdjustments from an Order
      See Also:
    • determineNextPeriod

      protected Integer determineNextPeriod(@NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem)
      Determines the Subscription.getNextPeriod() for a subscription.
      Parameters:
      rootOrderItem - The originating order item
      Returns:
      The next period for the subscription.
    • determineItemPaymentStrategy

      protected String determineItemPaymentStrategy(@NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem)
      Determines the SubscriptionCreationRequest.getPaymentStrategy() for a subscription.
      Parameters:
      rootOrderItem - The originating order item
      Returns:
      The payment strategy for the subscription.
    • determineStartingSubscriptionStatus

      protected String determineStartingSubscriptionStatus(@NonNull @NonNull CreateSubscriptionFromOrderRequest request, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Hook point to determine the starting status of a subscription. Default is SubscriptionStatuses.ACTIVE.
      Parameters:
      request - Request containing the Order with OrderItems representing Subscriptions to create
      rootOrderItem - the order item representing the subscription to be created
      contextInfo - Additional sandbox and multitenant info
      Returns:
      the starting subscription status
    • determineFulfillmentWorkflow

      protected String determineFulfillmentWorkflow(@NonNull @NonNull CreateSubscriptionFromOrderRequest request, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Identifies the subscription's fulfillment workflow.
      Parameters:
      request - Request containing the Order with OrderItems representing Subscriptions to create
      rootOrderItem - the order item representing the subscription to be created
      contextInfo - Additional sandbox and multitenant info
      Returns:
      the subscription's fulfillment workflow
    • buildSubscriptionItems

      protected List<SubscriptionItem> buildSubscriptionItems(@NonNull @NonNull Subscription subscription, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Builds out subscription item creation requests the root order item for the subscription and potential dependent order items. The root order item informs both the subscription and its root subscription item.
      Parameters:
      subscription - the generated subscription
      rootOrderItem - the root order item
      contextInfo - Additional sandbox and multitenant info
      Returns:
      list of subscription item creation requests
    • buildSubscriptionItem

      protected SubscriptionItem buildSubscriptionItem(@NonNull @NonNull Subscription subscription, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem, @Nullable com.broadleafcommerce.order.client.domain.OrderItem parentItem, @Nullable SubscriptionItem parentSubscriptionItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Builds out a request to create a subscription item. The presence of the parent item guides the logic that differs for dependent items.
      Parameters:
      subscription - the generated subscription
      orderItem - the order item
      parentItem - nullable parent OrderItem. Only present if the orderItem is a dependent order item
      parentSubscriptionItem - nullable parent SubscriptionItem. Only present if the item is a dependent subscription item
      contextInfo - Additional sandbox and multitenant info
      Returns:
      the built creation request DTO
    • getSubscriptionItemQuantity

      protected int getSubscriptionItemQuantity(@NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem, @Nullable SubscriptionItem parentSubscriptionItem)
      Scales the dependent item's quantity based on the parent item.

      Using the parent SubscriptionItem instead of the OrderItem here, since the parent SubscriptionItem.getQuantity() would have already been scaled in a nested dependent items scenario where as the OrderItem.getQuantity() is not.

      Parameters:
      orderItem - the OrderItem to scale the quantity for
      parentSubscriptionItem - the parent SubscriptionItem to scale the quantity with
      Returns:
      the item's quantity scaled based its parent item
    • getAddOnChoiceKey

      protected Optional<String> getAddOnChoiceKey(com.broadleafcommerce.order.client.domain.OrderItem orderItem)
      Determines the value to store at SubscriptionItem.getAddOnKey(). By default, this retrieves the DependentItemDetails.getItemChoiceKey() if present on the OrderItem.
      Parameters:
      orderItem - OrderItem for a SubscriptionItem.
      Returns:
      The value to store at SubscriptionItem.getAddOnKey().
    • buildDependentSubscriptionItems

      protected List<SubscriptionItem> buildDependentSubscriptionItems(@NonNull @NonNull Subscription subscription, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem, @NonNull @NonNull SubscriptionItem parentSubscriptionItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Builds out creation requests for subscription items from dependent order items
      Parameters:
      subscription - the generated subscription
      orderItem - the order item to get the dependent items from
      parentSubscriptionItem - the parent SubscriptionItem
      contextInfo - Additional sandbox and multitenant info
      Returns:
      list of built creation requests
    • setParentItemRef

      protected void setParentItemRef(@NonNull @NonNull SubscriptionItem item, @Nullable com.broadleafcommerce.order.client.domain.OrderItem parentItem)
      Set the SubscriptionItem.getParentItemRef() and SubscriptionItem.getParentItemRefType() given the parentItem. By default, this assumes the parent is a Broadleaf product and the ref should be the product's ID.
      Parameters:
      item - The SubscriptionItem to set the parent ref on
      parentItem - The OrderItem representing the item's parent. If null, indicates no parent, and no parent ref fields will be set.
    • buildSubscriptionItemAdjustments

      protected List<SubscriptionItemAdjustment> buildSubscriptionItemAdjustments(@NonNull @NonNull Subscription subscription, @NonNull @NonNull SubscriptionItem item, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem, @NonNull @NonNull List<com.broadleafcommerce.order.common.domain.Adjustment> itemAdjustments)
      Builds subscription item adjustments for item adjustments of type DefaultAdjustmentType.RECURRING_DISCOUNT.
      Parameters:
      subscription - the generated subscription
      orderItem - the order item receiving the adjustment
      itemAdjustments - adjustments for the order item
      Returns:
      built subscription item adjustments
    • buildSubscriptionItemAdjustment

      protected SubscriptionItemAdjustment buildSubscriptionItemAdjustment(@NonNull @NonNull Subscription subscription, @NonNull @NonNull SubscriptionItem item, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem, @NonNull @NonNull com.broadleafcommerce.order.common.domain.Adjustment adjustment)
      Builds out a subscription item adjustment from an order or order item adjustment
      Parameters:
      subscription - the generated subscription
      item - the SubscriptionItem that this adjustment belongs to
      orderItem - the order item receiving the adjustment
      adjustment - order item adjustment
      Returns:
      subscription item adjustment
    • hasTerms

      protected boolean hasTerms(@NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem)
      Checks the OrderItem for terms. By default, this looks for the presence of OrderItem.getTermDurationType() and OrderItem.getTermDurationLength().
      Parameters:
      orderItem - the order item representing the subscription to be created
      Returns:
      Whether the OrderItem has terms.
    • determineStartOfTermsDate

      @Nullable protected Instant determineStartOfTermsDate(@NonNull @NonNull com.broadleafcommerce.order.client.domain.Order order, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Determines the date the terms start for the subscription if there are terms. By default, this truncates the Order.getSubmitDate() to ChronoUnit.DAYS if the OrderItem has terms.
      Parameters:
      order - the order with subscriptions to create
      rootOrderItem - the order item representing the subscription to be created
      contextInfo - additional sandbox and multitenant info
      Returns:
      The date the terms start for the subscription if there are terms
    • determineEndOfTermsDate

      @Nullable protected Instant determineEndOfTermsDate(@NonNull @NonNull com.broadleafcommerce.order.client.domain.Order order, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem, @Nullable Instant startOfTermsDate, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Determines the end of terms date for a subscription based on the order and order item.

      Note that the ZonedDateTime is used to perform the calculation, since certain term duration types (e.g. months, years) are not supported by Instant.plus(long, TemporalUnit).

      Parameters:
      order - the order with subscriptions to create
      rootOrderItem - the order item representing the subscription to be created
      startOfTermsDate - The date the term starts if there are terms.
      contextInfo - additional sandbox and multitenant info
      Returns:
      the end of terms date, null if not applicable
    • populateTermDetails

      protected void populateTermDetails(@NonNull @NonNull Subscription subscription, @NonNull @NonNull com.broadleafcommerce.order.client.domain.Order order, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Hook point for populating term-based data on the Subscription from the rootOrderItem.
      Parameters:
      subscription - the Subscription to set the free trial details for
      order - the order that led to the creation of the subscription
      rootOrderItem - the order item representing the subscription to be created
      contextInfo - additional sandbox and multitenant info
    • populateFreeTrialDetails

      protected void populateFreeTrialDetails(@NonNull @NonNull Subscription subscription, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem, @NonNull @NonNull CreateSubscriptionFromOrderRequest createRequest, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Sets the details for when a free trial offer is applied, such as and Subscription.getFreeTrialEndDate().

      The Subscription.getNextBillDate() will be calculated and adjusted based on the delay in BillingService upon creation.

      Parameters:
      subscription - the Subscription to set the free trial details for
      rootOrderItem - the order item representing the subscription to be created
      createRequest - the original CreateSubscriptionFromOrderRequest that may contain additional information
      contextInfo - additional sandbox and multitenant info
    • populateAdditionalSubscriptionItemDetails

      protected SubscriptionItem populateAdditionalSubscriptionItemDetails(@NonNull @NonNull Subscription subscription, @NonNull @NonNull SubscriptionItem subscriptionItem, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem orderItem, @Nullable com.broadleafcommerce.order.client.domain.OrderItem parentOrderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Hook point to easily populate additional details on the SubscriptionItem.
      Parameters:
      subscription - the generated subscription
      subscriptionItem - The SubscriptionItem that has been populated so far
      orderItem - the order item representing the subscription to be created
      parentOrderItem - the possibly null parent order item
      contextInfo - Additional sandbox and multitenant info
      Returns:
      the SubscriptionItem that has been further populated
    • populateSubscriptionRoundBillDateAttribute

      protected Subscription populateSubscriptionRoundBillDateAttribute(@NonNull @NonNull Subscription subscription, @NonNull @NonNull CreateSubscriptionFromOrderRequest request, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Populates the SubscriptionAttributeConstants.Internal.ROUND_UP_BILL_DATES_TO_END_OF_MONTH if the order submission day is not available every month, e.g. 29, 30, 31.
      Parameters:
      subscription - The Subscription that has been populated so far
      request - Request containing the Order with OrderItems representing Subscriptions to create
      contextInfo - Additional sandbox and multitenant info
      Returns:
      the Subscription with the populated attribute
    • populateAdditionalSubscriptionDetails

      protected Subscription populateAdditionalSubscriptionDetails(@NonNull @NonNull Subscription subscription, @NonNull @NonNull CreateSubscriptionFromOrderRequest request, @NonNull @NonNull com.broadleafcommerce.order.client.domain.OrderItem rootOrderItem, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo contextInfo)
      Hook point to easily populate additional details on the Subscription.
      Parameters:
      subscription - The Subscription that has been populated so far
      request - Request containing the Order with OrderItems representing Subscriptions to create
      rootOrderItem - the order item representing the subscription to be created
      contextInfo - Additional sandbox and multitenant info
      Returns:
      the Subscription that has been further populated
    • getSubscriptionProvider

      protected SubscriptionProvider<SWI,Subscription,SubscriptionOwnerInfo> getSubscriptionProvider()
    • getSubscriptionOperationUtils

      protected SubscriptionOperationUtils getSubscriptionOperationUtils()
    • getMessageSource

      protected org.springframework.context.MessageSource getMessageSource()
    • getTypeFactory

      protected com.broadleafcommerce.common.extension.TypeFactory getTypeFactory()