developing a b2b quoting system in demandware

advertisement
DEVELOPING A
B2B QUOTING
SYSTEM IN
DEMANDWARE
Ana C. Rodriguez
November, 2015
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
1
DEVELOPING A B2B QUOTING SYSTEM
Forrester Research expects B2B eCommerce sales to reach $780 billion and represent 9.3 percent of all B2B
sales by the end of 2015. So, it’s no wonder more B2B companies are creating an online experience – one
that reflects the customer expectations set by B2C eCommerce.
B2B companies understand they can realize many of the same benefits consumer brands and retailers enjoy.
Providing wholesalers, purchasing agents, clients and other vendors with an online store can enhance supply
chain efficiencies, reduce customer service costs, eliminate order errors, and free up a sales force to focus on
expanding market share.
However, the nature of B2B creates some special needs when it comes to developing an online store. One of
those is that not all customers are alike. B2B must deal with the fact that prices fluctuate often with
customer-specific pricing and volume-based discounts. And so, a quoting system is required.
Automating the quoting process to provide a rapid response can make the all the difference when it comes to
increasing order conversions. At the same time, it can sometimes require custom development to create a
system that meets a company’s specific needs.
LYONSCG recently developed a quoting solution for a Demandware client that’s very scalable and easy to
maintain. Let’s take a look at how we went about it.
DESIGN OF B2B QUOTATION SYSTEM IN DEMANDWARE
The use case below represents the solution divided in three steps: 1) create quote, 2) place order (based on a
quote) and 3) cancel quote.
Figure 1: Quoting System Use Case
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
2
Create quote will have as final result a quote, built through the Storefront checkout process and stored in a
Product List with specific quoting custom attributes set.
Place order is the process of creating an actual order based on a quote. All the discounts and price adjustments
set in a quote should be honored when the order is placed.
Finally, cancel quote is the process to delete a quote permanently.
User could be a storefront user or a CSR (Customer Service Representative), depending on business
requirements. The original implementation uses CSSuite (Customer Service Suite) to support the solution and
allows quotes to be handled exclusively by CSRs.
IMPLEMENTATION
Create Quote
Figure 2: Quoting System  Create Quote Use Case
Business requirements:

Quotes must be created from Storefront

Products can be added to or removed from shopping cart

Product quantities can be adjusted

Coupons and promotions can be applied

Shipping address and shipping method are mandatory

Billing step must be skipped (billing address & payment info will be provided when order is placed)

Review quote page is displayed prior to saving the quote

Saving a quote displays a quote confirmation page

Quotes are stored in a Product List
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
3
Create quote is implemented as an alternative flow on Storefront checkout.
Figure 3: Create Quote Detailed Use Case
Step:
Action:
Create Shopping Cart
Shipping
Add Products to Cart
Shipping Address
Remove Products from Cart
Shipping Method
Change Product Quantities
Apply Coupons
Apply Promotions
Billing
Review Quote
Quote Confirmation
SKIP
Confirm Quote
Quote is created!
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
4
Implementation steps:
1)
User access storefront
2)
User creates shopping cart (same process as checkout)
3)
User fills out shipping address (same process as checkout)
4)
User selects shipping method (same process as checkout)
5)
System skips billing step
To create an alternate flow on checkout and skip the billing step an action must be added to the
shipping pipeline (COShipping).
Figure 4: createQuote Action on Shipping Pipeline
The new action will be triggered by a button on shipping page (something like “Continue Create
Quote”) and invoke a call on COShipping pipeline.
-
New action on singleshipping form:
<action formid="save" valid-form="true"/>
<action formid="selectAddress" valid-form="false"/>
<action formid="createQuote" valid-form="true"/>
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
-
5
“Continue Create Quote” button on singleshipping template:
<button class="button-fancy-large" type="submit" name=
"${pdict.CurrentForms.singleshipping.shippingAddress.createQuote.htmlName}"
value="Create Quote">
<span>Continue Create Quote <</span>
</button>
Figure 5: Continue Create Quote button on Storefront Checkout
-
New action call and jump node on COShipping pipeline (as seen on Figure 4)
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
6)
6
System displays review quote page:
Review quote page displays pretty much the same information as review order page, minus billing
address and billing info sections.
A specific pipeline for quoting was created (COCreateQuote) to hold all the pipeline calls.
Note below the pipeline COCreateQuote-Summary looks like COSummary-Start, except validate
payment call was removed.
Figure 6: COCreateQuote-Summary Pipeline
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
7)
7
User confirms create quote:
Clicking on Save Quote on review quote page will save the quote and redirect the user to confirmation
quote page. Create quote process consists of:
-
Validate quote (basket)
Validation prior to create a quote is much simpler than the validation performed before placing
an actual order: make sure the basket has products and validate cart for checkout. What is NOT
validated nor processed: payments (validation and handling) and personal information.
Figure 7: Validation on COCreateQuote-Start Pipeline
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
-
8
Create product list
Figure 8: Create Product List on COCreateQuote-Start Pipeline
Create product list, simply put, replaces create order on the pipeline. Once a product list is
created, the custom attributes values are set manually using a transactional script
(CreateProductListFromBasket). Below is the representation of custom attributes for product
list and product list item when creating quotes.
Figure 9: ProductList Custom Attributes
Object Representation
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
9
Figure 10: ProductListItem Custom Attributes
Object Representation
Notice on the representations above the function GetPriceAdjustments. This function
iterates through each price adjustment (basket and product) and returns a JSON string that
will be assigned to the custom attribute (quotePriceAdjustments on ProductList,
quoteProductPriceAdjustments on ProductListItem). These attributes will be retrieved later
(during place order) so all discounts and price adjustments applied to the quote can be
honored when an order is placed.
function getPriceAdjustments(priceAdjustments : Collection) {
var priceAdjustmentList = [];
var it : Iterator = priceAdjustments.iterator();
while (it.hasNext()) {
var priceAdjustment : PriceAdjustment = it.next();
var priceAdjustmentDescription =
(priceAdjustment.basedOnCoupon ? "Coupon: " : "") +
priceAdjustment.lineItemText;
var priceAdjustmentObject =
JSON.stringify({
description : priceAdjustmentDescription
,amount: priceAdjustment.priceValue
});
priceAdjustmentList.push(priceAdjustmentObject);
}
return priceAdjustmentList;
}
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
-
10
Clear basket
When an actual order is placed, the basket is destroyed automatically. Without order
placement – which is the case in quoting – while it’s not possible to destroy the basket, it must
be cleared manually.
The script ClearBasket is the last transactional call made before finalizing the creation of a
quote. It will not only clear the basket, but it will also return two objects: one containing quote
totals and a second one with shipment details (shipping address and shipping method).
Figure 11: QuoteTotals Object Representation
Figure 12: Shipment Object Representation
The basket is finally cleared when all the products are removed.
…
var it : Iterator = basket.allProductLineItems.iterator();
while (it.hasNext()) {
var pli = it.next();
basket.removeProductLineItem(pli);
}
…
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
8)
11
System displays confirmation quote page:
The confirmation quote page looks like the confirmation order page, minus billing address and
payment information. The data displayed it’s loaded from Quote Totals and Shipment objects (see
step 7 for implementation details).
Figure 13: Confirmation Quote Page
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
12
Place Order
Figure 14: Quoting System  Place Order Use Case
Business requirements:

No changes can be made to quotes

Price adjustments and coupons applied to a quote must be honored

Billing address must be entered

Payment method must be entered

Placing an order will create an order based on the quote

Quote will be deleted permanently from the system
Implementation:
Place order consists of loading the quote into a basket and adding billing address and payment info for order
placement.
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
13
Figure 15: Place Order Detailed Use Case
Step:
Select Quote
Billing
Order Confirmation
Action:
Set Product List Items
Billing Address
Order is created!
Set Price Adjustments
Payment Method
Quote is deleted!
Set Customer
Set Shipping Address
Set Shipping Method
Implementation Steps:
1)
User selects quote
There are many ways to implement the selection of a quote. The implementation served as
reference for this document used CSSuite (Customer Service Suite) to list customers’ quotes and
allow a CSR (Customer Service Representative) to select one. Implementing a list of customers’
quotes on Storefront would be another doable option.
Once a quote is selected, it must be loaded into a basket so order placement can get started. All the
data contained in the quote must be loaded into the basket: products, price adjustments, customer
info, shipping address and shipping method.
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
-
14
Loading products from quote into basket
To load products from a quote into the basket, simply iterate through the quote (product list)
items and use the appropriate method to add each product to the basket.
//iterate through the quote items and add each one of them to the
basket
var it : Iterator = quote.getProductItems().iterator();
while (it.hasNext()) {
var pli : ProductListItem = it.next();
//add product to basket
var productLineItem : ProductLineItem =
basket.createProductLineItem(pli.getProductID(),
defaultShipment);
productLineItem.setQuantityValue(pli.getQuantityValue());
//adjust product price on basket
productLineItem.custom.quoteProductPrice =
pli.custom.quoteProductPrice;
//set product price adjustment
if ("quoteProductPriceAdjustments" in pli.custom) {
createPriceAdjustments(productLineItem,
pli.custom.quoteProductPriceAdjustments);
}
}
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
15
Product price adjustments persisted in the custom attribute quoteProductPriceAdjustments in
ProductListItem object will be iterated (see createPriceAdjustments function below) so the
adjustments can be set on the basket.
function createPriceAdjustments(lineItemCtnr : LineItemCtnr,
priceAdjustmentList : List) {
for (var i=0; i < priceAdjustmentList.length; i++) {
var priceAdjustmentObject = JSON.parse(priceAdjustmentList[i]);
var adjustment : PriceAdjustment =
lineItemCtnr.createPriceAdjustment(UUIDUtils.createUUID());
try {
adjustment.setLineItemText(priceAdjustmentObject.description);
adjustment.setPriceValue(priceAdjustmentObject.amount);
} catch (e) {
lineItemCtnr.removePriceAdjustment(adjustment);
return PIPELET_ERROR;
}
}
}
-
Set price adjustments
Price adjustments applied to the quote will be processed the same way the product price
adjustments described above.
if ("quotePriceAdjustments" in quote.custom) {
createPriceAdjustments(basket,
quote.custom.quotePriceAdjustments);
}
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
-
16
Set customer
Figure 16: Basket Customer
Attributes Representation
-
Set shipping address
Figure 17: Basket Shipping Address
Attributes Representation
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
-
17
Set shipping method
To set the shipping method, iterate through all the shipping methods to find the one that matches
what’s set on the quote and should be set on the basket.
var shippingMethod = null;
if ('quoteShippingMethodID' in quote.custom) {
var itShippingMethods : Iterator =
ShippingMgr.getAllShippingMethods().iterator();
while (itShippingMethods.hasNext()) {
var
shippingMethod
:
ShippingMethod
=
itShippingMethods.next();
if (shippingMethod.ID == quote.custom.quoteShippingMethodID)
{
defaultShipment.setShippingMethod(shippingMethod);
break;
}
}
}
Using the code below, it’s possible to override the shipping price, honoring any shipping
promotion that was applied at the time the quote was created.
defaultShipment.getStandardShippingLineItem().setPriceValue(
quote.custom.quoteShippingTotalPrice);
2)
User fills out billing address (same process as checkout)
3)
User selects payment method (same process as checkout)
4)
User confirm place order
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
When user confirms place an order, two things happen:
-
An actual order is created (same process as checkout)
The basket will go through all the necessary validations to place an order.
-
Quote is deleted
Once order is placed, the quote is deleted permanently from the system.
Cancel Quote
Figure 18: Quoting System  Cancel Quote Use Case
18
LYONSCG White Paper: Developing a B2B Quoting System in Demandware
19
Business requirements:

A quote can be cancelled at any time

Quote will be deleted permanently from the system
Implementation:
The solution this document was based on used CSSuite to implement this last part. The process consists of
offering the user a list of quotes where any of them can actually be deleted. To delete a quote (product list)
without writing any code, simply use pipelets (see Figure 18 for reference).
CONCLUSION
Although quoting is a large implementation, breaking the requirements into small parts and implementing
each one as an independent module simplified the process. Also, leveraging the Storefront code was definitely
key to reducing coding complexity and avoiding having to “reinvent the wheel”. Using this document as base
reference, new functionalities can be added easily, depending on the customers’ requirements.
LYONSCG White Paper: Implementing a Quoting System in Demandware
1
Thank You
About LYONSCG
LYONSCG is the industry’s premier eCommerce digital agency, serving brand, retail, and B2B organizations with
tailored eCommerce solutions that maximize online potential. Headquartered in Chicago, the firm offers a full range
of services beginning with digital strategy and digital marketing and extending through experience design, platform
implementation, application development, hosting and support. The approach is holistic—to provide every client with
a creative, robust and increasingly profitable eCommerce website. LYONSCG is eCommerce Realized!
LYONSCG
20 N. Wacker Drive, Suite 1750
Chicago, IL 60606
P: 312.506.2020
F: 312.506.2022
W: www.lyonscg.com
All information contained within this document is proprietary and confidential
© Lyons Consulting Group 2015
Download