package org.beesden.shop.view; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.beesden.shop.model.Address; import org.beesden.shop.model.Basket; import org.beesden.shop.model.Customer; import org.beesden.shop.model.DeliveryCharge; import org.beesden.shop.model.Tender; import org.beesden.shop.service.BasketService; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/checkout/") public class CheckoutView extends ViewUpdate { @RequestMapping(value = "/submit", method = RequestMethod.POST) public String placeOrder(HttpServletRequest request, ModelMap model) { logger.info("Placing order"); Long start = System.currentTimeMillis(); Map<String, Object> config = getConfig(request); // Don't process if the basket is empty if (basket.getItems() == null || basket.getItems().size() < 1) { return "redirect:/checkout/basket"; } List<String> errors = updateBasket(request); errors = validateOrder(request, errors); if (errors.size() > 0) { request.getSession().setAttribute("messages", errors); return "redirect:/checkout/summary"; } // Finalise the order attributes Basket order = basketService.assembleOrder(basket, fetchCustomer()); order = basketService.objectCreate(order); model.addAttribute("order", order); basket.setOrderPlaced(new Date()); return isAjax(model, request, "checkout.confirmation", config, start); } @RequestMapping(value = "/delivery", method = RequestMethod.GET) public String showDeliveryOptions(HttpServletRequest request, ModelMap model) { logger.info("Delivery options page requested"); return isCheckout(model, request, "checkout.delivery"); } @RequestMapping(value = "/confirmation", method = RequestMethod.GET) public String showOrderConfirmation(HttpServletRequest request, ModelMap model) { logger.info("Order confirmation page requested"); return "redirect:/checkout/basket"; } @RequestMapping(value = "/payment", method = RequestMethod.GET) public String showPayment(ModelMap model, HttpServletRequest request) { logger.info("Received request to show checkout summary"); return isCheckout(model, request, "checkout.payment"); } @RequestMapping(value = "/shipping", method = RequestMethod.GET) public String showShipping(HttpServletRequest request, ModelMap model) { logger.info("Shipping address page requested"); return isCheckout(model, request, "checkout.shipping"); } @RequestMapping(value = "/summary", method = RequestMethod.GET) public String showSummary(ModelMap model, HttpServletRequest request) { logger.info("Received request to show checkout summary"); return isCheckout(model, request, "checkout.summary"); } public List<String> updateBasket(HttpServletRequest request) { logger.info("Updating checkout details"); List<String> errors = new ArrayList<String>(); Customer customer = fetchCustomer(); // Check for terms and conditions acceptance Boolean termsAgree = Boolean.parseBoolean(request.getParameter("termsAgree")); basket.setTermsAgree(termsAgree); // Select a delivery option String deliveryChargeId = request.getParameter("deliveryCharge"); if (deliveryChargeId != null) { logger.info("Updating delivery charge"); String dbQuery = deliveryChargeService.getQuery(deliveryChargeId, null, 1, null); DeliveryCharge charge = deliveryChargeService.findOne(dbQuery); if (charge != null) { basket.setDeliveryCharge(charge); } } // Generate initial address variables Address address = new Address(); String selectAddress = request.getParameter("selectAddress"); String addressId = request.getParameter("selectAddressId"); String addressType = request.getParameter("addressType"); // Create / update an address if (selectAddress != null) { if (selectAddress.equals("existingAddress")) { logger.info("Select a saved " + addressType + " address: " + addressId); String dbQuery = addressService.getQueryCustomer(addressId, customer.getId().toString(), 1); address = addressService.findOne(dbQuery); if (address == null) { errors = addError(errors, "invalid.address.id"); } } else { logger.info("Create a new " + addressType + "address"); address = createAddress(request, address, true); address.setCreatedBy(customer.getName()); address.setDateCreated(new Date()); address.setLastEditedBy(customer.getName()); address.setLastEdited(new Date()); // Link the address to the customer address.setCustomer(customer); addressService.objectUpdate(address); } // Attach address to basket if delivery if (addressType.equals("delivery")) { logger.info("Set delivery address"); basket.setDeliveryAddress(address); } } // Generate initial payment details variables Tender paymentDetails = new Tender(); if (basket.getPaymentDetails() != null) { paymentDetails = basket.getPaymentDetails(); } String updatePayment = request.getParameter("updatePayment"); String tenderId = request.getParameter("paymentId"); if (updatePayment != null) { if (updatePayment.equals("savedTender") && tenderId != null) { logger.info("Select a saved payment card: " + tenderId); String dbQuery = tenderService.getQueryCustomer(tenderId, customer.getId().toString(), 1); paymentDetails = tenderService.findOne(dbQuery); if (paymentDetails == null) { errors = addError(errors, "invalid.tender.id"); } } else if (updatePayment.equals("newTender")) { logger.info("Create a new payment card"); paymentDetails = setPaymentDetails(request, paymentDetails); paymentDetails.setCustomer(customer); paymentDetails.setCreatedBy(customer.getName()); paymentDetails.setDateCreated(new Date()); tenderService.objectUpdate(paymentDetails); } // Attach address to order tender if payment if (addressType.equals("payment") && !updatePayment.equals("savedTender")) { logger.info("Set payment address"); paymentDetails.setAddress(address); } ; basket.setPaymentDetails(paymentDetails); } // Update the basket totals basket = BasketService.setTotals(basket); return errors; } @RequestMapping(value = "/delivery", method = RequestMethod.POST) public String updateDelivery(HttpServletRequest request, ModelMap model) { logger.info("Updating shipping address"); List<String> errors = updateBasket(request); if (errors.size() > 0) { request.getSession().setAttribute("messages", errors); return "redirect:/checkout/delivery"; } return "redirect:/checkout/payment"; } @RequestMapping(value = "/payment", method = RequestMethod.POST) public String updatePayment(HttpServletRequest request, ModelMap model) { logger.info("Updating payment details"); List<String> errors = updateBasket(request); if (errors.size() > 0) { request.getSession().setAttribute("messages", errors); return "redirect:/checkout/payment"; } return "redirect:/checkout/summary"; } @RequestMapping(value = "/shipping", method = RequestMethod.POST) public String updateShipping(HttpServletRequest request, ModelMap model) { logger.info("Updating shipping address"); List<String> errors = updateBasket(request); if (errors.size() > 0) { request.getSession().setAttribute("messages", errors); return "redirect:/checkout/shipping"; } return "redirect:/checkout/delivery"; } public List<String> validateOrder(HttpServletRequest request, List<String> errors) { if (!basket.getTermsAgree()) { errors = addError(errors, "order.terms.agree"); } if (basket.getDeliveryCharge() == null) { errors = addError(errors, "order.delivery.charge"); } return errors; } }