Broadleaf Microservices
  • v1.0.0-latest-prod

Status Transitions

We have a list of out of box quote statuses that dictates who and when a quote can be read, updated, or transitioned to the next status. The flow diagram below shows how a quote can progress at each stage of the quote process:

Quote Status Flow Chart

Key Components

  • DefaultCartStatusManager

    • A component that facilitates the status change and validations on if/when a cart can transition, read, or updated by the currently authenticated user

  • CartStatusHandler

    • There is an implementation of CartStatusHandler and AbstractQuoteCartStatusHandler for each quote status to handle its transition and validation on whether the quote can be read or updated by the user

  • DefaultQuoteService

    • The service that facilitates quote-related operations such as changing the quote status or retrieving quotes

    • Every time a quote’s status is changed, a CartActionAudit is created to keep track of the user’s action. For example, when a sales rep publishes a quote, a cart action audit is created with the PUBLISH_QUOTE action type, see DefaultQuoteService#buildCartActionAudit and #determineQuoteActionType for more details

Default Statuses

DRAFTING

The quote initiation process starts with a quote being in a DRAFTING status, which can be from converting an IN_PROCESS cart into a quote or simply creating a quote from the start.

Status change is handled by:

QuoteDraftingStatusHandler

Quotes can flow to this status from:
  • IN_PROCESS cart

  • EXPIRED quote

    • When an EXPIRED quote is moved to this status, the EXPIRED quote is cloned into a new quote with the DRAFTING status. The price overrides previously made by the sales rep are removed, and the CartActionAudits are cloned into the new quote as well

Quotes in this status can be read by:
  • The owner of the quote

Quotes in this status can be updated by:
  • The owner of the quote

Quotes can be transitioned to this status by:
  • The owner of the quote

QUOTE_REQUESTED

Indicates that the quote has been requested to the seller.

Status change is handled by:

QuoteQuoteRequestedStatusHandler

Quotes can flow to this status from:
  • DRAFTING

  • ASSIGNED

  • PUBLISHED

  • EDITING

  • REJECTED

Quotes in this status can be read by:
  • The owner of the quote

  • Sales reps

Quotes in this status can be updated by:
  • The owner of the quote

    • The buyer can also recalls a requested quote for editing, which will shift the quote to the EDITING status

  • Sales rep with ALL_PUBLISH_QUOTE permission if quotes are not required to be assigned first based on configuration defined in Sales Rep Assignment Configuration

Quotes can be transitioned to this status by:
  • The owner of the quote

  • Sales rep with ALL_PUBLISH_QUOTE permission

ASSIGNED

Indicates that the quote is assigned to a sales rep.

Status change is handled by:

QuoteAssignedStatusHandler

Quotes can flow to this status from:
  • QUOTE_REQUESTED

Quotes in this status can be read by:
  • The owner of the quote

  • Sales reps

Quotes in this status can be updated by:
  • The assigned sales rep with ALL_PUBLISH_QUOTE permission

    • In this status, the assigned sales rep can modify the quote such as add/remove/update items and override item prices. The assigned sales can also swap or add prices for any custom quote items (e.g. requested items or services that weren’t on the catalog)

    • Sales reps cannot modify quotes that are not assigned to them

Quotes can be transitioned to this status by:
  • Sales rep with ALL_PUBLISH_QUOTE permission

PUBLISHED

Indicates that the quote has been published back to the requester with the quoted prices.

Status change is handled by:

QuoteAssignedStatusHandler

Quotes can flow to this status from:
Quotes in this status can be read by:
  • The owner of the quote

  • Sales reps

Quotes in this status can be updated by:
  • The owner of the quote for only the following workflows:

    • PROCESS_CHECKOUT

    • UPDATE_CONTACT_INFO

    • UPDATE_FULFILLMENT_GROUP

    • PRICE_CART

    • RECALCULATE_TAXES

    • These workflows are to support buyer checking out with a PUBLISHED quote while preventing them from making modifications to the quote

  • No one can update a PUBLISHED quote directly. If the buyer would like to modify the quote, it must be shifted to EDITING first

    • This is to ensure that quotes must be reviewed & published by the seller before it can be checked out

    • The seller can also recall a published quote, which will shift it back to the QUOTE_REQUESTED status

Quotes can be transitioned to this status by:
  • Sales rep with ALL_PUBLISH_QUOTE permission assigned to this quote

SUBMITTED

Indicates that the quote has been checked out.

Note
Note that this status resides in DefaultCartStatuses instead of DefaultQuoteStatuses
Status change is handled by:

QuoteSubmittedStatusHandler

Quotes can flow to this status from:
  • PUBLISHED

Quotes in this status can be read by:
  • The owner of the quote

  • Sales reps

Quotes in this status can be updated by:
  • No one

Quotes can be transitioned to this status by:
  • The owner of the quote

EDITING

Indicates that the quote is being edited by the buyer after the seller’s response.

Status change is handled by:

QuoteEditingStatusHandler

Quotes can flow to this status from:
  • PUBLISHED

  • QUOTE_REQUESTED

    • The buyer can recall the quote after being requested for further modification

Quotes in this status can be read by:
  • The owner of the quote

Quotes in this status can be updated by:
  • The owner of the quote

Quotes can be transitioned to this status by:
  • The owner of the quote

EXPIRED

Indicates that the quote is expired.

After a sales rep publishes a quote, an expiration date is typically set on the quote itself.

After a quote is expired, it cannot be checked out by the buyer. The buyer would instead need to clone the expired quote into a quote, which the associated CartActionAudits would be cloned as well to preserve the history.

For more details on the component that marks quotes as EXPIRED, see Mark Quotes as Expired Scheduled Job.

Status change is handled by:

QuoteExpiredStatusHandler

Quotes can flow to this status from:
  • QUOTE_REQUESTED

  • ASSIGNED

  • PUBLISHED

  • EDITING

Quotes in this status can be read by:
  • The owner of the quote

  • Sales reps

Quotes in this status can be updated by:
  • No one

Quotes can be transitioned to this status by:
  • No one

    • Quotes can only be set to this status by the MarkQuotesExpiredJobListener

REJECTED

Indicates that the quote is rejected.

Status change is handled by:

QuoteRejectedStatusHandler

Quotes can flow to this status from:
Quotes in this status can be read by:
  • The owner of the quote

  • Sales reps

Quotes in this status can be updated by:
  • No one

Quotes can be transitioned to this status by:
  • Sales rep with ALL_PUBLISH_QUOTE permission assigned to this quote

CANCELED

Indicates that the quote is canceled.

Status change is handled by:

QuoteCanceledStatusHandler

Quotes can flow to this status from:
  • DRAFTING

  • QUOTE_REQUESTED

  • ASSIGNED

  • PUBLISHED

  • EDITING

Quotes in this status can be read by:
  • The owner of the quote

  • Sales reps

Quotes in this status can be updated by:
  • Sales rep for only the following workflows:

    • DELETE_CANCELED_QUOTE

    • This allows sales rep to delete any canceled quotes

    • No one can update a CANCELED quote otherwise

Quotes can be transitioned to this status by:
  • Sales rep with ALL_PUBLISH_QUOTE permission assigned to this quote

Notifications

With each quote status transitions, a notification is sent via CartService along with updating the cart.

Each status transition has its own message producer and binding:

  • QUOTE_REQUESTED

    • Producer: QuoteRequestedProducer

    • Binding:

      spring:
        cloud:
          stream:
            bindings:
              quoteRequestedOutput:
                destination: quoteRequested
  • REJECTED

    • Producer: QuoteRejectedProducer

    • Binding:

      spring:
        cloud:
          stream:
            bindings:
              quoteRejectedOutput:
                destination: quoteRejected
  • CANCELED

    • Producer: QuoteCanceledProducer

    • Binding:

      spring:
        cloud:
          stream:
            bindings:
              quoteCanceledOutput:
                destination: quoteCanceled
  • PUBLISHED

    • Producer: QuotePublishedProducer

    • Binding:

      spring:
        cloud:
          stream:
            bindings:
              quotePublishedOutput:
                destination: quotePublished
  • EXPIRED

    • Producer: QuoteExpiredProducer

    • Binding:

      spring:
        cloud:
          stream:
            bindings:
              quoteExpiredOutput:
                destination: quoteExpired

See Quote Notification Listeners for more details on the message consumers.