com.epam.cme.storefront.controllers.pages.TelcoCartPageController.java Source code

Java tutorial

Introduction

Here is the source code for com.epam.cme.storefront.controllers.pages.TelcoCartPageController.java

Source

/*
 * [y] hybris Platform
 *
 * Copyright (c) 2000-2013 hybris AG
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of hybris
 * ("Confidential Information"). You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with hybris.
 * 
 *  
 */
package com.epam.cme.storefront.controllers.pages;

import de.hybris.platform.acceleratorservices.config.SiteConfigService;
import de.hybris.platform.cms2.exceptions.CMSItemNotFoundException;
import de.hybris.platform.commercefacades.order.data.CartData;
import de.hybris.platform.commercefacades.order.data.CartModificationData;
import de.hybris.platform.commercefacades.order.data.OrderEntryData;
import de.hybris.platform.commerceservices.order.CommerceCartModificationException;
import de.hybris.platform.servicelayer.session.SessionService;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.epam.cme.facades.order.BundleCartFacade;
import com.epam.cme.storefront.breadcrumb.ResourceBreadcrumbBuilder;
import com.epam.cme.storefront.constants.WebConstants;
import com.epam.cme.storefront.controllers.ControllerConstants;
import com.epam.cme.storefront.controllers.util.GlobalMessages;
import com.epam.cme.storefront.forms.DeleteBundleForm;
import com.epam.cme.storefront.forms.UpdateQuantityForm;

/**
 * Controller for cart page
 */
@Controller
@RequestMapping(value = "/cart")
public class TelcoCartPageController extends AbstractPageController {
    protected static final Logger LOG = Logger.getLogger(TelcoCartPageController.class);

    public static final String SHOW_CHECKOUT_STRATEGY_OPTIONS = "storefront.show.checkout.flows";

    private static final String CART_CMS_PAGE_LABEL = "cart";
    private static final String CONTINUE_URL = "continueUrl";

    @Resource(name = "cartFacade")
    private BundleCartFacade cartFacade;

    @Resource(name = "siteConfigService")
    private SiteConfigService siteConfigService;

    @Resource(name = "sessionService")
    private SessionService sessionService;

    @Resource(name = "simpleBreadcrumbBuilder")
    private ResourceBreadcrumbBuilder resourceBreadcrumbBuilder;

    // Public getter used in a test
    @Override
    public SiteConfigService getSiteConfigService() {
        return siteConfigService;
    }

    @ModelAttribute("showCheckoutStrategies")
    public boolean isCheckoutStrategyVisible() {
        final String property = getSiteConfigService().getProperty(SHOW_CHECKOUT_STRATEGY_OPTIONS);
        return !StringUtils.isBlank(property) && Boolean.parseBoolean(property);
    }

    /*
     * Display the cart page
     */
    @RequestMapping(method = RequestMethod.GET)
    public String showCart(final Model model) throws CMSItemNotFoundException {
        prepareDataForPage(model);
        return ControllerConstants.Views.Pages.Cart.CartPage;
    }

    /**
     * Handle the '/cart/checkout' request url. This method checks to see if the cart is valid
     * before allowing the checkout to begin. Note that this method does not require the user to be
     * authenticated and therefore allows us to validate that the cart is valid without first
     * forcing the user to login. The cart will be checked again once the user has logged in.
     * 
     * @return The page to redirect to
     */
    @RequestMapping(value = "/checkout", method = RequestMethod.GET)
    public String cartCheck() {
        if (!cartFacade.hasSessionCart() || cartFacade.getSessionCart().getEntries().isEmpty()) {
            LOG.info("Missing or empty cart");

            // No session cart or empty session cart. Bounce back to the cart page.
            return REDIRECT_PREFIX + "/cart";
        }

        if (!cartFacade.isCartValid()) {
            LOG.info("Cart contains invalid component(s)");
            return REDIRECT_PREFIX + "/cart";
        }

        // Redirect to the start of the checkout flow to begin the checkout process
        // We just redirect to the generic '/checkout' page which will actually select the checkout
        // flow
        // to use. The customer is not necessarily logged in on this request, but will be forced to
        // login
        // when they arrive on the '/checkout' page.
        return REDIRECT_PREFIX + "/checkout";
    }

    // This controller method is used to allow the site to force the visitor through a specified
    // checkout flow.
    // If you only have a static configured checkout flow then you can remove this method.
    @RequestMapping(value = "/checkout/select-flow", method = RequestMethod.GET)
    public String initCheck() {
        if (!cartFacade.hasSessionCart() || cartFacade.getSessionCart().getEntries().isEmpty()) {
            LOG.info("Missing or empty cart");

            // No session cart or empty session cart. Bounce back to the cart page.
            return REDIRECT_PREFIX + "/cart";
        }

        // Redirect to the start of the checkout flow to begin the checkout process
        // We just redirect to the generic '/checkout' page which will actually select the checkout
        // flow
        // to use. The customer is not necessarily logged in on this request, but will be forced to
        // login
        // when they arrive on the '/checkout' page.
        return REDIRECT_PREFIX + "/checkout";
    }

    /**
     * Handle the delete of a bundle
     * 
     * @param form
     *            bundle delete form, indicating the bundle No
     * @param model
     * @param bindingResult
     * @param redirectModel
     * @return redirect url
     * @throws CMSItemNotFoundException
     */
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public String deleteCartBundle(@Valid final DeleteBundleForm form, final Model model,
            final BindingResult bindingResult, final RedirectAttributes redirectModel)
            throws CMSItemNotFoundException {
        if (bindingResult.hasErrors()) {
            for (final ObjectError error : bindingResult.getAllErrors()) {
                GlobalMessages.addErrorMessage(model, error.getDefaultMessage());

            }
        }

        try {
            cartFacade.deleteCartBundle(form.getBundleNo());

            // Success in removing entry
            redirectModel.addFlashAttribute(GlobalMessages.CONF_MESSAGES_HOLDER,
                    Collections.singletonList("basket.page.bundle.message.remove"));

        } catch (final CommerceCartModificationException e) {

            LOG.info("Could not delete bundle No" + form.getBundleNo());
            redirectModel.addFlashAttribute(GlobalMessages.CONF_MESSAGES_HOLDER,
                    Collections.singletonList("basket.page.bundle.message.remove.error"));
        }

        prepareDataForPage(model);
        return REDIRECT_PREFIX + "/cart";

    }

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String updateCartQuantities(@RequestParam("entryNumber") final long entryNumber, final Model model,
            @Valid final UpdateQuantityForm form, final BindingResult bindingResult,
            final RedirectAttributes redirectModel) throws CMSItemNotFoundException {
        if (bindingResult.hasErrors()) {
            for (final ObjectError error : bindingResult.getAllErrors()) {
                if (error.getCode().equals("typeMismatch")) {
                    GlobalMessages.addErrorMessage(model, "basket.error.quantity.invalid");
                } else {
                    GlobalMessages.addErrorMessage(model, error.getDefaultMessage());
                }
            }
        } else if (cartFacade.getSessionCart().getEntries() != null) {
            try {
                final CartModificationData cartModification = cartFacade.updateCartEntry(entryNumber,
                        form.getQuantity().longValue());
                if (cartModification.getQuantity() == form.getQuantity().longValue()) {
                    // Success

                    if (cartModification.getQuantity() == 0) {
                        // Success in removing entry
                        redirectModel.addFlashAttribute(GlobalMessages.CONF_MESSAGES_HOLDER,
                                Collections.singletonList("basket.page.message.remove"));
                    } else {
                        // Success in update quantity
                        redirectModel.addFlashAttribute(GlobalMessages.CONF_MESSAGES_HOLDER,
                                Collections.singletonList("basket.page.message.update"));
                    }
                } else {
                    // Less than successful

                    if (form.getQuantity().longValue() == 0) {
                        // Failed to remove entry
                        redirectModel.addFlashAttribute(GlobalMessages.ERROR_MESSAGES_HOLDER,
                                Collections.singletonList("basket.information.quantity.reducedNumberOfItemsAdded."
                                        + cartModification.getStatusCode()));
                    } else {
                        // Failed to update quantity
                        redirectModel.addFlashAttribute(GlobalMessages.ERROR_MESSAGES_HOLDER,
                                Collections.singletonList("basket.information.quantity.reducedNumberOfItemsAdded."
                                        + cartModification.getStatusCode()));
                    }
                }

                // Redirect to the cart page on update success so that the browser doesn't re-post
                // again
                return REDIRECT_PREFIX + "/cart";
            } catch (final CommerceCartModificationException ex) {
                redirectModel.addFlashAttribute(GlobalMessages.ERROR_MESSAGES_HOLDER,
                        Collections.singletonList(ex.getMessage()));
                LOG.warn("Couldn't update product with the entry number: " + entryNumber + ".", ex);
            } finally {
                return REDIRECT_PREFIX + "/cart";
            }
        }

        prepareDataForPage(model);
        return ControllerConstants.Views.Pages.Cart.CartPage;
    }

    protected void createProductList(final Model model) throws CMSItemNotFoundException {
        final CartData cartData = cartFacade.getSessionCart();

        if (cartData.getEntries() != null && !cartData.getEntries().isEmpty()) {
            for (final OrderEntryData entry : cartData.getEntries()) {
                if (entry.getProduct() != null) { // this is not an empty cart entry
                    final UpdateQuantityForm uqf = new UpdateQuantityForm();
                    uqf.setQuantity(entry.getQuantity());
                    model.addAttribute("updateQuantityForm" + entry.getEntryNumber(), uqf);
                    model.addAttribute("quantities", getNumberRange(0, 10));
                }
            }
        }

        model.addAttribute("cartData", cartData);

        storeCmsPageInModel(model, getContentPageForLabelOrId(CART_CMS_PAGE_LABEL));
        setUpMetaDataForContentPage(model, getContentPageForLabelOrId(CART_CMS_PAGE_LABEL));
    }

    protected void prepareDataForPage(final Model model) throws CMSItemNotFoundException {
        final String continueUrl = (String) sessionService.getAttribute(WebConstants.CONTINUE_URL);
        model.addAttribute(CONTINUE_URL, (continueUrl != null && !continueUrl.isEmpty()) ? continueUrl : ROOT);

        createProductList(model);
        model.addAttribute(WebConstants.BREADCRUMBS_KEY,
                resourceBreadcrumbBuilder.getBreadcrumbs("breadcrumb.cart"));
        model.addAttribute("pageType", PageType.Cart);
    }

    /**
     * TODO:Need to move out of controller and place in facade with business logic to populate max
     * number
     * 
     */
    protected List<String> getNumberRange(final int startNumber, final int endNumber) {
        final List<String> numbers = new ArrayList<String>();
        for (int number = startNumber; number <= endNumber; number++) {
            numbers.add(String.valueOf(number));
        }
        return numbers;
    }
}