edu.byu.softwareDistribution.web.controller.shopper.ShoppingCartController.java Source code

Java tutorial

Introduction

Here is the source code for edu.byu.softwareDistribution.web.controller.shopper.ShoppingCartController.java

Source

package edu.byu.softwareDistribution.web.controller.shopper;

import edu.byu.edge.person.basic.BasicPersonLookup;
import edu.byu.security.userdetails.IdentityDetails;
import edu.byu.softwareDist.ces.PersonRepo;
import edu.byu.softwareDist.dao.ProductDao;
import edu.byu.softwareDist.domain.AccountCode;
import edu.byu.softwareDist.domain.LineItem;
import edu.byu.softwareDist.domain.Product;
import edu.byu.softwareDist.domain.PurchaseLineItem;
import edu.byu.softwareDist.helper.LineItemDisplayHelper;
import edu.byu.softwareDist.manager.*;
import edu.byu.softwareDistribution.web.cart.ShoppingCart;
import edu.byu.softwareDistribution.web.cart.ShoppingCartMessage;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.beans.PropertyEditorSupport;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
public class ShoppingCartController {

    private static final Logger LOG = Logger.getLogger(ShoppingCartController.class);

    private final ShoppingCartManager shoppingCartManager;
    private final PurchaseManager purchaseManager;
    private final ProductDao productDao;
    private final ShoppingCart cart;
    private final LicenseManager licenseManager;
    private final PersonRepo personRepo;
    private final BasicPersonLookup basicPersonLookup;

    @Autowired
    public ShoppingCartController(final ShoppingCartManager shoppingCartManager,
            final PurchaseManager purchaseManager, final ProductDao productDao, final ShoppingCart cart,
            LicenseManager licenseManager, final PersonRepo personRepo, final BasicPersonLookup basicPersonLookup) {
        this.cart = cart;
        this.shoppingCartManager = shoppingCartManager;
        this.purchaseManager = purchaseManager;
        this.productDao = productDao;
        this.licenseManager = licenseManager;
        this.personRepo = personRepo;
        this.basicPersonLookup = basicPersonLookup;
    }

    @RequestMapping(value = "/shop/shoppingCart.htm")
    public String displayPage(Model model, @RequestParam(value = "byuId", required = false) String byuId) {
        final List<LineItem> items = new ArrayList<LineItem>(cart.getItems());
        final BigDecimal total = cart.getTotalPrice();
        final List<LineItemDisplayHelper> displayItems = cart.getItemsWithKeys();
        final Map<Integer, Boolean> returnable = new HashMap<Integer, Boolean>();
        model.addAttribute("items", displayItems);
        for (final LineItemDisplayHelper lineItem : displayItems) {
            if (lineItem.getValue().getType() == LineItem.Type.MAINTENANCE_LINE_ITEM) {
                returnable.put(lineItem.getKey(), true);
                continue;
            }
            final PurchaseLineItem pli = (PurchaseLineItem) lineItem.getValue();
            returnable.put(lineItem.getKey(), licenseManager.isReturnable(pli.getProduct().getProductId()));
        }
        model.addAttribute("productReturnable", returnable);
        model.addAttribute("totalPrice", total);
        model.addAttribute("personRepo", personRepo);
        model.addAttribute("needsAccountCode", BigDecimal.ZERO.compareTo(total) != 0);
        model.addAttribute("itemCount", items.size());
        model.addAttribute("cart", cart);
        model.addAttribute("maintType", LineItem.Type.MAINTENANCE_LINE_ITEM);
        final IdentityDetails currentIdentityDetails = IdentityDetails.getCurrentIdentityDetails();
        String personId = "";
        if (byuId != null) {
            personId = basicPersonLookup.getPersonByByuId(byuId).getPersonId();
        } else {
            personId = currentIdentityDetails.getPersonId();
        }
        LOG.debug("Identity Details id: " + personId);
        model.addAttribute("accountCodes", purchaseManager.getUsedAccountCodes(personId));
        model.addAttribute("signedInName", currentIdentityDetails.getName());
        LOG.info("Total Price: " + total);
        return "shop/shoppingCart";
    }

    @RequestMapping(value = "/shop/shoppingCart/addMaintenance")
    public @ResponseBody String addMaintenance(@RequestParam(value = "maintenanceId") Integer maintenanceId,
            @RequestParam(value = "byuId", required = false) String byuId,
            @RequestParam(value = "qty", required = false) Integer qty,
            @RequestParam(value = "note", required = false) String note) {
        try {
            String personId = "";
            if (byuId != null) {
                personId = basicPersonLookup.getPersonByByuId(byuId).getPersonId();
            } else {
                personId = IdentityDetails.getCurrentIdentityDetails().getPersonId();
            }
            final LineItem item = shoppingCartManager.getMaintenanceLineItem(maintenanceId, personId, qty, note);
            cart.addToCart(item);
            return String.format("(%d)%s has been added to your cart.", item.getQty(), item.getDisplayName());
        } catch (Throwable t) {
            LOG.error("Error adding maintenance to cart.", t);
            return "Error adding maintenance to cart.";
        }
    }

    @RequestMapping(value = "/shop/shoppingCart/addProduct")
    public @ResponseBody String addProduct(@RequestParam(value = "productId") int productId,
            @RequestParam(value = "byuId", required = false) String byuId,
            @RequestParam(value = "qty", required = false) Integer qty,
            @RequestParam(value = "note", required = false) String note) {
        LOG.debug("Adding Item: " + productId);
        try {
            String personId = "";
            if (byuId != null) {
                personId = basicPersonLookup.getPersonByByuId(byuId).getPersonId();
            } else {
                personId = IdentityDetails.getCurrentIdentityDetails().getPersonId();
            }
            final LineItem item = shoppingCartManager.getPurchaseLineItem(productId, personId, qty, note);
            cart.addToCart(item);
            return String.format("(%d)%s has been added to your cart.", item.getQty(), item.getDisplayName());
        } catch (Throwable t) {
            LOG.error("Error adding product to cart.", t);
            return "Error adding product to cart.";
        }
    }

    @RequestMapping(value = "/shop/getEULA.htm")
    public String getEULA(Model model, @RequestParam(value = "productId") int productId) {
        final Product p = productDao.findById(productId);
        if (p.getEula() != null) {
            model.addAttribute("eulaText", p.getEula().getTextContent());
        } else {
            model.addAttribute("eulaText", "No EULA");
        }
        return "/shop/shoppingCart";
    }

    @RequestMapping(value = "/shop/shoppingCart/changePurchasedFor")
    public @ResponseBody ShoppingCartMessage changePurchasedFor(@RequestParam(value = "key") int key,
            @RequestParam(value = "purchasedFor") String purchasedFor) {
        LOG.info("Starting change Purchased For...");
        ShoppingCartMessage cartMessage = new ShoppingCartMessage();
        final LineItem item = cart.getItem(key);
        if (item == null) {
            LOG.info("Item is null.");
            cartMessage.setMessage("Item does not exist.");
            cartMessage.setValid(false);
            return cartMessage;
        }
        if (LineItem.Type.PURCHASE_LINE_ITEM.equals(item.getType())
                && !shoppingCartManager.checkEligibilityByProductIdAndPersonId(item.getRecordId(), purchasedFor)) {
            LOG.info("Person is ineligible.");
            cartMessage.setMessage("Cannot change proxy to that person. They are not eligible for this product.");
            cartMessage.setValid(false);
            return cartMessage;
        }
        LOG.info("Changing Purchased For.");
        cart.changePurchasedFor(key, purchasedFor);
        cartMessage.setMessage(String.format("Proxy has been changed for %s.", item.getDisplayName()));
        cartMessage.setValid(true);
        return cartMessage;
    }

    @RequestMapping(value = "/shop/shoppingCart/updateNotes")
    public @ResponseBody String updateNotes(@RequestParam(value = "key") int key,
            @RequestParam(value = "note") String note) {
        final LineItem item = cart.getItem(key);
        if (item == null) {
            return "Item does not exist.";
        }
        cart.changeNote(key, note);
        return String.format("%s notes have been updated.", item.getDisplayName());
    }

    @RequestMapping(value = "/shop/shoppingCart/changeQty")
    public @ResponseBody String changeQty(@RequestParam(value = "key") int key,
            @RequestParam(value = "qty") Integer qty) {
        final LineItem item = cart.getItem(key);
        if (item == null) {
            return "Item does not exist.";
        }
        if (qty == null)
            qty = 1;
        cart.changeQuantity(key, qty);
        return String.format("%s quantity has been updated to %d.", item.getDisplayName(), qty);
    }

    @RequestMapping(value = "/shop/shoppingCart/removeItem")
    public @ResponseBody String removeItem(@RequestParam(value = "key") int key) {
        final LineItem item = cart.getItem(key);
        if (item == null) {
            return "Item does not exist.";
        }
        cart.removeFromCart(key);
        return String.format("%s removed from cart.", item.getDisplayName());
    }

    @RequestMapping(value = "/shop/shoppingCart/updateTotalPrice")
    public @ResponseBody BigDecimal updateTotalPrice() {
        if (cart == null)
            return BigDecimal.ZERO;
        return cart.getTotalPrice();
    }

    @RequestMapping(value = "/shop/shoppingCart/updateLinePrice")
    public @ResponseBody BigDecimal updateLinePrice(@RequestParam(value = "key") int key) {
        final LineItem item = cart.getItem(key);
        if (item == null)
            return BigDecimal.ZERO;
        return item.getTotalPrice();
    }

    @RequestMapping(value = "/shop/shoppingCart/updatePurchasedFor")
    public @ResponseBody String updatePurchasedFor(@RequestParam(value = "key") int key) {
        final LineItem item = cart.getItem(key);
        if (item == null)
            return "";
        return item.getPurchasedFor();
    }

    @RequestMapping(value = "/shop/shoppingCart/clearCart")
    public @ResponseBody String clearCart() {
        if (cart == null)
            return "Cart already empty.";
        cart.clearCart();
        return "Cart emptied.";
    }

    @RequestMapping(value = "/shop/shoppingCart/updateEULAs.htm")
    public String updateEULAs(Model model) {
        if (cart == null) {
            model.addAttribute("items", Collections.<LineItemDisplayHelper>emptyList());
        } else {
            final List<LineItemDisplayHelper> items = cart.getItemsWithKeys();
            if (items == null || items.isEmpty()) {
                model.addAttribute("items", Collections.<LineItemDisplayHelper>emptyList());
            } else {
                model.addAttribute("items", items);
            }
        }
        return "shop/shoppingCart";
    }

    @RequestMapping(value = "/shop/shoppingCart/checkout.htm")
    public String checkout(Model model, @RequestParam(value = "accountCode", required = false) String accountCode,
            @RequestParam(value = "creditCard", required = false) String creditCard) {
        final String netId = IdentityDetails.getCurrentIdentityDetails().getNetId();
        try {
            if (accountCode != null && !accountCode.isEmpty())
                new AccountCode(accountCode);
        } catch (Throwable ignore) {
            return "redirect:/shop/shoppingCart.htm";
        }
        final AccountCode ac = (accountCode == null || accountCode.isEmpty()) ? null : new AccountCode(accountCode);
        if (LOG.isInfoEnabled()) {
            LOG.info(netId + " Checking Out Using Account Code: " + accountCode + " -> " + ac);
        }
        if (cart == null || cart.getItemCount() == 0) {
            LOG.warn("Checking out with a null/empty cart (" + (cart == null ? null : cart.getItemCount()) + ").");
            return "redirect:/shop/shoppingCart.htm";
        }
        final Collection<LineItem> items = cart.getItems();
        PurchaseHelper purchaseHelper = new PurchaseHelper(items, ac, creditCard);
        CheckOutResults results = null;
        String sendUserTo;
        try {
            purchaseHelper = purchaseManager.purchase(purchaseHelper);
            if (purchaseHelper.getCreditCardUrl() != null) {
                cart.clearCart();
                sendUserTo = purchaseHelper.getCreditCardUrl();
            } else {
                sendUserTo = "redirect:/shop/myDownloads.htm";
            }
        } catch (IllegalStateException ise) {
            //this happens when no items were saved. Therefore we need to just redirect as results will be null.
            LOG.warn(netId + " error with purchase", ise);
            cart.setErrorMessage("An error occurred while recording your purchase.");
            return "redirect:/shop/shoppingCart.htm";
        } catch (Throwable t) {
            LOG.error(netId + " other error", t);
            sendUserTo = "redirect:/shop/shoppingCart.htm";
        } finally {
            //TODO: 
            if (LOG.isInfoEnabled()) {
                LOG.info(netId + " finishing call to checkout");
            }
        }
        if (results == null) {
            LOG.warn(netId + " results are null. what does this mean?");
        }
        final String error = (results != null) ? getErrorText(results) : "";

        if (results != null) {
            if (results.getUnpurchasedItems() != null && !results.getUnpurchasedItems().isEmpty()) {
                cart.clearCart();
                for (final CheckOutResults.FailedReason fr : results.getUnpurchasedItems()) {
                    cart.addToCart(fr.getLineItem());
                }
            } else {
                //no unpurchased items, so successful
                cart.clearCart();
                sendUserTo = "redirect:/shop/myDownloads.htm";
            }
        } //else results == null which we checked above
        if (error != null && !"".equals(error)) {
            cart.setErrorMessage(error);
            sendUserTo = "redirect:/shop/myDownloads.htm";
        }
        return sendUserTo;
    }

    @RequestMapping(value = "/shop/shoppingCart/checkAccountCode")
    public @ResponseBody AccountInformation checkAccountCode(
            @RequestParam(value = "accountCode") String accountCode) {
        LOG.info("validating account: " + accountCode);
        return purchaseManager.checkAccountCode(new AccountCode(accountCode));
    }

    @RequestMapping(value = "/shop/shoppingCart/savedAccountCodes")
    public @ResponseBody List<AccountCode> getSavedAccountCodes(
            @RequestParam(value = "effectiveId", required = false) String effectiveId) {
        if (effectiveId == null) {
            effectiveId = IdentityDetails.getCurrentIdentityDetails().getPersonId();
        }
        LOG.debug("identity details effective id: " + effectiveId);
        return purchaseManager.getUsedAccountCodes(effectiveId);
    }

    @InitBinder
    public final void addDateEditor(ServletRequestDataBinder binder) {
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String s) throws IllegalArgumentException {
                if (s == null) {
                    return;
                }
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    setValue(format.parse(s));
                } catch (ParseException e) {
                    LOG.debug("Invalid Date.");
                }
            }
        });

    }

    @ExceptionHandler(IllegalArgumentException.class)
    public void illegalArgument(IllegalArgumentException iae, HttpServletResponse response) {
        LOG.error("illegal argument", iae);
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
    }

    @ExceptionHandler(Throwable.class)
    public void errors(Throwable e, HttpServletResponse response) {
        LOG.error("unknown error", e);
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }

    private String getErrorText(final CheckOutResults results) {
        final StringBuilder sb = new StringBuilder();
        for (final CheckOutResults.FailedReason fr : results.getUnpurchasedItems()) {
            sb.append("<p>Unable to purchase item ");
            sb.append(fr.getLineItem().getDisplayName());
            sb.append(" due to ");
            sb.append(fr.getReason());
            sb.append("</p>\n");
        }
        return sb.toString();
    }
}