2 - Extending the Storefront
2 - Extending the Storefront
In the Storefront, Form Bean classes represent the forms a customer fills out. Form Bean classes store the information a user provides before passing the information into the Elastic Path Core.
In this section, you will extend the Storefront and create a T-shirt form bean to store the personalized T-shirt's text.
Creating the personalized T-shirt form bean
To create the T-shirt form bean:
- Navigate to the ext-storefront project, found in the extensions/storefront directory.
- In the ext-storefront project's src/main/java directory (create java folder if it does not exist), create a new package named com.extensions.tshirt.sfweb.formbean
- In com.extensions.tshirt.sfweb.formbean, create an interface named TshirtFormBean and add the following code:
package com.extensions.tshirt.sfweb.formbean; import java.util.Map; import com.elasticpath.common.dto.ShoppingItemDto; import com.elasticpath.sfweb.formbean.EpFormBean; /** * Defines the form shoppers fill out to personalize their T-shirts. */ public interface TshirtFormBean extends EpFormBean { /** * Returns a T-shirt's front text. * * @return The T-shirt's front text */ String getFrontText(); /** * Sets the T-Shirt's front text. * * @param frontText - a String to set to this property */ void setFrontText(String frontText); /** * Returns a T-shirt's back text. * * @return The T-shirt's back text */ String getBackText(); /** * Sets the T-Shirt's back text. * * @param backText - a String to set to this property */ void setBackText(String backText); /** * Returns a map of T-shirt fields. * * @return The fields */ Map<String, String> getAsItemFields(); /** * Initializes all T-shirt fields from the fields in the {@code ShoppingItem}. * * @param shoppingItem - The item's ShoppingItemDto */ void initFromShoppingItemDto(ShoppingItemDto shoppingItem); }
- In com.extensions.tshirt.sfweb.formbean, create a package named impl
- In com.extensions.tshirt.sfweb.formbean.impl, create a new class named TshirtFormBeanImpl and add the following code:
package com.extensions.tshirt.sfweb.formbean.impl; import java.util.HashMap; import java.util.Map; import com.extensions.tshirt.sfweb.formbean.TshirtFormBean; import com.elasticpath.common.dto.ShoppingItemDto; import com.elasticpath.sfweb.formbean.impl.EpFormBeanImpl; /** * Implements {@link TshirtFormBean}. */ public class TshirtFormBeanImpl extends EpFormBeanImpl implements TshirtFormBean { private static final long serialVersionUID = 1L; /** * Key for getting a Tshirt's front text. */ public static final String TSHIRT_FRONT_TEXT_KEY = "Front text"; /** * Key for getting a Tshirt's back text. */ public static final String TSHIRT_BACK_TEXT_KEY = "Back text"; private String frontText; private String backText; @Override public String getBackText() { return backText; } @Override public String getFrontText() { return frontText; } @Override public void setBackText(final String backText) { this.backText = backText; } @Override public void setFrontText(final String frontText) { this.frontText = frontText; } @Override public Map<String, String> getAsItemFields() { HashMap<String, String> map = new HashMap<String, String>(); map.put(TSHIRT_BACK_TEXT_KEY, this.backText); map.put(TSHIRT_FRONT_TEXT_KEY, this.frontText); return map; } @Override public void initFromShoppingItemDto(final ShoppingItemDto shoppingItem) { if (shoppingItem == null) { return; } Map<String, String> itemFields = shoppingItem.getItemFields(); this.frontText = itemFields.get(TSHIRT_FRONT_TEXT_KEY); this.backText = itemFields.get(TSHIRT_BACK_TEXT_KEY); } }
Extending Storefront Classes
You need to extend a few Storefront classes to include the t-shirt form bean in the checkout process:
ShoppingItemFormBean
The ShoppingItemFormBean is the top level form bean for storing product information.
To include the personalized text fields from the t-shirt form bean:
- In com.extensions.tshirt.sfweb.formbean, create an interface named ExtShoppingItemFormBean and add the following code:
package com.extensions.tshirt.sfweb.formbean; import com.elasticpath.sfweb.formbean.ShoppingItemFormBean; /** * Adds getTshirtFields() method to the ShoppingItemFormBean. */ public interface ExtShoppingItemFormBean extends ShoppingItemFormBean { /** * Returns the special fields for a T-shirt. * * @return a TshirtFormBean with the T-shirt's fields. */ TshirtFormBean getTshirtFields(); }
- In com.extensions.tshirt.sfweb.formbean.impl create a class named ExtShoppingItemFormBeanImpl and add the following code:
package com.extensions.tshirt.sfweb.formbean.impl; import com.extensions.tshirt.sfweb.formbean.ExtShoppingItemFormBean; import com.extensions.tshirt.sfweb.formbean.TshirtFormBean; import com.elasticpath.sfweb.formbean.impl.ShoppingItemFormBeanImpl; /** * Implements {@link ExtShoppingItemFormBean}. */ public class ExtShoppingItemFormBeanImpl extends ShoppingItemFormBeanImpl implements ExtShoppingItemFormBean { private static final long serialVersionUID = 1L; private final TshirtFormBean tshirtFormBean = new TshirtFormBeanImpl(); @Override public TshirtFormBean getTshirtFields() { return tshirtFormBean; } }
ShoppingItemFormBeanContainerFactoryImpl
The ShoppingItemFormBeanContainerFactoryImpl class builds cart update form beans from the ShoppingItemFormBean.
To create cart update form beans from ExtShoppingItemFormBean:
- In the ext-storefront project's src/main/java directory, create a new package named com.extensions.tshirt.sfweb.controller.impl
- In com.extensions.tshirt.sfweb.controller.impl, create a class named ExtShoppingItemFormBeanContainerFactoryImpl and add the following code:
package com.extensions.tshirt.sfweb.controller.impl; import java.util.Collections; import java.util.Map; import com.extensions.tshirt.sfweb.formbean.ExtShoppingItemFormBean; import com.elasticpath.common.dto.ShoppingItemDto; import com.elasticpath.domain.catalog.Price; import com.elasticpath.domain.catalog.Product; import com.elasticpath.domain.catalog.ProductBundle; import com.elasticpath.domain.catalogview.StoreProduct; import com.elasticpath.domain.pricing.PriceAdjustment; import com.elasticpath.domain.shoppingcart.ShoppingCart; import com.elasticpath.sfweb.controller.ShoppingItemFormBeanContainerFactory; import com.elasticpath.sfweb.controller.impl.ShoppingItemFormBeanContainerFactoryImpl; import com.elasticpath.sfweb.formbean.ShoppingItemFormBean; import com.elasticpath.sfweb.formbean.ShoppingItemFormBeanContainer; import com.elasticpath.sfweb.formbean.impl.CartFormBeanImpl; /** * Extended ShoppingItemFormBeanContainerFactoryImpl that utilizes the {@link ExtShoppingItemFormBean}. */ public class ExtShoppingItemFormBeanContainerFactoryImpl extends ShoppingItemFormBeanContainerFactoryImpl implements ShoppingItemFormBeanContainerFactory { @Override public ShoppingItemFormBeanContainer createCartFormBean(final StoreProduct storeProduct, final int quantity, final ShoppingCart shoppingCart) { String defaultSkuCode = storeProduct.getDefaultSku().getSkuCode(); // BEGIN OVERRIDE ------------------------------------------------------------ ExtShoppingItemFormBean rootFormBean = (ExtShoppingItemFormBean) createShoppingItemFormBean(shoppingCart.getStore(), storeProduct, defaultSkuCode, quantity, "", 0, 0); rootFormBean.getTshirtFields().initFromShoppingItemDto(null); // END OVERRIDE ------------------------------------------------------------ // by default, the root form bean should always be set to be selected rootFormBean.setSelected(true); Product product = storeProduct.getWrappedProduct(); Map<String, PriceAdjustment> priceAdjustmentsForBundle = Collections.emptyMap(); if (product instanceof ProductBundle) { ProductBundle bundle = (ProductBundle) product; priceAdjustmentsForBundle = getPriceLookupFacade().getPriceAdjustmentsForBundle(bundle, shoppingCart.getStore().getCatalog().getCode(), shoppingCart.getShopper()); if (bundle.getSelectionRule() != null) { rootFormBean.setSelectionRule(bundle.getSelectionRule().getParameter()); } if (bundle.isCalculated()) { setPriceAndQuantityForCalculatedBundle(rootFormBean, product, shoppingCart); } } addConstituentShoppingItemFormBeansFromProduct(shoppingCart, rootFormBean, storeProduct, "", 1, priceAdjustmentsForBundle); ShoppingItemFormBeanContainer cartFormBean = new CartFormBeanImpl(); cartFormBean.addShoppingItemFormBean(rootFormBean); rootFormBean.setMinQty(calculateMinQty(shoppingCart, rootFormBean)); return cartFormBean; } private void setPriceAndQuantityForCalculatedBundle( final ShoppingItemFormBean rootFormBean, final Product product, final ShoppingCart shoppingCart) { rootFormBean.setCalculatedBundle(true); Price promotedPriceForSku = this.getPriceLookupFacade().getPromotedPriceForSku( product.getDefaultSku(), shoppingCart.getStore(), shoppingCart.getShopper(), shoppingCart.getAppliedRules()); if (promotedPriceForSku != null) { int firstPriceTierMinQty = promotedPriceForSku.getFirstPriceTierMinQty(); rootFormBean.setPrice(promotedPriceForSku); rootFormBean.setQuantity(firstPriceTierMinQty); } } @Override public ShoppingItemFormBeanContainer createCartFormBean(final ShoppingItemDto existingShoppingItemDto, final ShoppingCart shoppingCart, final boolean dependent) { final StoreProduct storeProduct = findProductByGuid(existingShoppingItemDto.getProductCode(), shoppingCart.getStore()); // BEGIN OVERRIDE ------------------------------------------------------------ ExtShoppingItemFormBean rootFormBean = (ExtShoppingItemFormBean) createShoppingItemFormBean( shoppingCart.getStore(), storeProduct, existingShoppingItemDto.getSkuCode(), existingShoppingItemDto.getQuantity(), "", 0, existingShoppingItemDto.getShoppingItemUidPk()); rootFormBean.setDependent(dependent); rootFormBean.setPrice(existingShoppingItemDto.getPrice()); rootFormBean.setTotal(existingShoppingItemDto.getTotal()); rootFormBean.setSelected(existingShoppingItemDto.isSelected()); rootFormBean.getGiftCertificateFields().initFromShoppingItemDto(existingShoppingItemDto); rootFormBean.getTshirtFields().initFromShoppingItemDto(existingShoppingItemDto); // END OVERRIDE ------------------------------------------------------------ Product product = storeProduct.getWrappedProduct(); Map<String, PriceAdjustment> priceAdjustmentsForBundle = Collections.emptyMap(); if (product instanceof ProductBundle) { ProductBundle bundle = (ProductBundle) product; priceAdjustmentsForBundle = getPriceLookupFacade().getPriceAdjustmentsForBundle(bundle, shoppingCart.getStore().getCatalog().getCode(), shoppingCart.getShopper()); if (bundle.isCalculated()) { rootFormBean.setCalculatedBundle(true); rootFormBean.setPrice(existingShoppingItemDto.getPrice()); } } addConstituentShoppingItemFormBeansFromShoppingItemDto(shoppingCart, rootFormBean, existingShoppingItemDto, storeProduct, "", 1, priceAdjustmentsForBundle); ShoppingItemFormBeanContainer cartUpdateFormBean = new CartFormBeanImpl(); cartUpdateFormBean.addShoppingItemFormBean(rootFormBean); rootFormBean.setMinQty(calculateMinQty(shoppingCart, rootFormBean)); return cartUpdateFormBean; } }
ShoppingItemDtoMapper
The ShoppingItemDtoMapper transfers data between the Storefront's ShoppingItemFormBean and the Elastic Path Core's ShoppingItemDto.
To transfer data from ExtShoppingItemFormBean to the ShoppingItemDto:
- In com.extensions.tshirt.sfweb.controller.impl, create a class
named ExtShoppingItemDtoMapperImpl and add the following
code:
package com.extensions.tshirt.sfweb.controller.impl; import com.extensions.tshirt.sfweb.formbean.ExtShoppingItemFormBean; import com.elasticpath.common.dto.ShoppingItemDto; import com.elasticpath.sfweb.controller.impl.ShoppingItemDtoMapperImpl; import com.elasticpath.sfweb.formbean.ShoppingItemFormBean; /** * Extended Dto mapper that includes mapping for Tshirt fields. */ public class ExtShoppingItemDtoMapperImpl extends ShoppingItemDtoMapperImpl { @Override protected void doItemFieldsMapping(final ShoppingItemDto parentDto, final ShoppingItemFormBean parentBean) { parentDto.setItemFields(parentBean.getGiftCertificateFields().getAsItemFields()); if (parentBean instanceof ExtShoppingItemFormBean) { ExtShoppingItemFormBean formBean = (ExtShoppingItemFormBean) parentBean; parentDto.setItemFields(formBean.getTshirtFields().getAsItemFields()); } } }