Java tutorial
/* * [y] hybris Platform * * Copyright (c) 2000-2015 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.nagarro.core.v2.controller; import de.hybris.platform.basecommerce.enums.StockLevelStatus; import de.hybris.platform.commercefacades.customer.CustomerFacade; import de.hybris.platform.commercefacades.order.SaveCartFacade; import de.hybris.platform.commercefacades.order.data.CCPaymentInfoData; import de.hybris.platform.commercefacades.order.data.CartData; import de.hybris.platform.commercefacades.order.data.CartModificationData; import de.hybris.platform.commercefacades.order.data.DeliveryModesData; import de.hybris.platform.commercefacades.order.data.OrderEntryData; import de.hybris.platform.commercefacades.product.data.PromotionResultData; import de.hybris.platform.commercefacades.product.data.StockData; import de.hybris.platform.commercefacades.promotion.CommercePromotionRestrictionFacade; import de.hybris.platform.commercefacades.storelocator.data.PointOfServiceData; import de.hybris.platform.commercefacades.user.data.AddressData; import de.hybris.platform.commercefacades.voucher.exceptions.VoucherOperationException; import de.hybris.platform.commerceservices.customer.DuplicateUidException; import de.hybris.platform.commerceservices.order.CommerceCartMergingException; import de.hybris.platform.commerceservices.order.CommerceCartModificationException; import de.hybris.platform.commerceservices.order.CommerceCartRestorationException; import de.hybris.platform.commerceservices.promotion.CommercePromotionRestrictionException; import de.hybris.platform.commerceservices.search.pagedata.PageableData; import de.hybris.platform.commerceservices.search.pagedata.PaginationData; import de.hybris.platform.commercewebservicescommons.cache.CacheControl; import de.hybris.platform.commercewebservicescommons.cache.CacheControlDirective; import de.hybris.platform.commercewebservicescommons.dto.order.CartListWsDTO; import de.hybris.platform.commercewebservicescommons.dto.order.CartModificationWsDTO; import de.hybris.platform.commercewebservicescommons.dto.order.CartWsDTO; import de.hybris.platform.commercewebservicescommons.dto.order.DeliveryModeListWsDTO; import de.hybris.platform.commercewebservicescommons.dto.order.DeliveryModeWsDTO; import de.hybris.platform.commercewebservicescommons.dto.order.OrderEntryListWsDTO; import de.hybris.platform.commercewebservicescommons.dto.order.OrderEntryWsDTO; import de.hybris.platform.commercewebservicescommons.dto.order.PaymentDetailsWsDTO; import de.hybris.platform.commercewebservicescommons.dto.product.PromotionResultListWsDTO; import de.hybris.platform.commercewebservicescommons.dto.user.AddressWsDTO; import de.hybris.platform.commercewebservicescommons.dto.voucher.VoucherListWsDTO; import de.hybris.platform.commercewebservicescommons.errors.exceptions.CartAddressException; import de.hybris.platform.commercewebservicescommons.errors.exceptions.CartEntryException; import de.hybris.platform.commercewebservicescommons.errors.exceptions.CartException; import de.hybris.platform.commercewebservicescommons.errors.exceptions.LowStockException; import de.hybris.platform.commercewebservicescommons.errors.exceptions.ProductLowStockException; import de.hybris.platform.commercewebservicescommons.errors.exceptions.RequestParameterException; import de.hybris.platform.commercewebservicescommons.errors.exceptions.StockSystemException; import de.hybris.platform.commercewebservicescommons.errors.exceptions.WebserviceValidationException; import com.nagarro.core.cart.impl.CommerceWebServicesCartFacade; import com.nagarro.core.exceptions.InvalidPaymentInfoException; import com.nagarro.core.exceptions.NoCheckoutCartException; import com.nagarro.core.exceptions.UnsupportedDeliveryModeException; import com.nagarro.core.exceptions.UnsupportedRequestException; import com.nagarro.core.order.data.CartDataList; import com.nagarro.core.order.data.OrderEntryDataList; import com.nagarro.core.product.data.PromotionResultDataList; import com.nagarro.core.request.support.impl.PaymentProviderRequestSupportedStrategy; import com.nagarro.core.stock.CommerceStockFacade; import com.nagarro.core.voucher.data.VoucherDataList; import java.util.ArrayList; import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.apache.commons.validator.EmailValidator; import org.apache.log4j.Logger; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.annotation.Secured; import org.springframework.stereotype.Controller; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.Errors; import org.springframework.validation.Validator; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; 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.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; /** * * @pathparam userId User identifier or one of the literals below : * <ul> * <li>'current' for currently authenticated user</li> * <li>'anonymous' for anonymous user</li> * </ul> * @pathparam cartId Cart identifier * <ul> * <li>cart code for logged in user</li> * <li>cart guid for anonymous user</li> * <li>'current' for the last modified cart</li> * </ul> * @pathparam entryNumber Entry number. Zero-based numbering. * @pathparam promotionId Promotion identifier (code) * @pathparam voucherId Voucher identifier (code) */ @Controller @RequestMapping(value = "/{baseSiteId}/users/{userId}/carts") @CacheControl(directive = CacheControlDirective.NO_CACHE) public class CartsController extends BaseCommerceController { private final static Logger LOG = Logger.getLogger(BaseCommerceController.class); private final static long DEFAULT_PRODUCT_QUANTITY = 1; @Resource(name = "commercePromotionRestrictionFacade") private CommercePromotionRestrictionFacade commercePromotionRestrictionFacade; @Resource(name = "commerceStockFacade") private CommerceStockFacade commerceStockFacade; @Resource(name = "customerFacade") private CustomerFacade customerFacade; @Resource(name = "pointOfServiceValidator") private Validator pointOfServiceValidator; @Resource(name = "orderEntryCreateValidator") private Validator orderEntryCreateValidator; @Resource(name = "orderEntryUpdateValidator") private Validator orderEntryUpdateValidator; @Resource(name = "orderEntryReplaceValidator") private Validator orderEntryReplaceValidator; @Resource(name = "greaterThanZeroValidator") private Validator greaterThanZeroValidator; @Resource(name = "paymentProviderRequestSupportedStrategy") private PaymentProviderRequestSupportedStrategy paymentProviderRequestSupportedStrategy; @Resource(name = "saveCartFacade") private SaveCartFacade saveCartFacade; private static CartModificationData mergeCartModificationData(final CartModificationData cmd1, final CartModificationData cmd2) { if ((cmd1 == null) && (cmd2 == null)) { return new CartModificationData(); } if (cmd1 == null) { return cmd2; } if (cmd2 == null) { return cmd1; } final CartModificationData cmd = new CartModificationData(); cmd.setDeliveryModeChanged(Boolean.valueOf(Boolean.TRUE.equals(cmd1.getDeliveryModeChanged()) || Boolean.TRUE.equals(cmd2.getDeliveryModeChanged()))); cmd.setEntry(cmd2.getEntry()); cmd.setQuantity(cmd2.getQuantity()); cmd.setQuantityAdded(cmd1.getQuantityAdded() + cmd2.getQuantityAdded()); cmd.setStatusCode(cmd2.getStatusCode()); return cmd; } private static OrderEntryData getCartEntryForNumber(final CartData cart, final long number) throws CartEntryException { final List<OrderEntryData> entries = cart.getEntries(); if (entries != null && !entries.isEmpty()) { final Integer requestedEntryNumber = Integer.valueOf((int) number); for (final OrderEntryData entry : entries) { if (entry != null && requestedEntryNumber.equals(entry.getEntryNumber())) { return entry; } } } throw new CartEntryException("Entry not found", CartEntryException.NOT_FOUND, String.valueOf(number)); } private static OrderEntryData getCartEntry(final CartData cart, final String productCode, final String pickupStore) { for (final OrderEntryData oed : cart.getEntries()) { if (oed.getProduct().getCode().equals(productCode)) { if (pickupStore == null && oed.getDeliveryPointOfService() == null) { return oed; } else if (pickupStore != null && oed.getDeliveryPointOfService() != null && oed.getDeliveryPointOfService().getName().equals(pickupStore)) { return oed; } } } return null; } private static void validateForAmbiguousPositions(final CartData currentCart, final OrderEntryData currentEntry, final String newPickupStore) throws CommerceCartModificationException { final OrderEntryData entryToBeModified = getCartEntry(currentCart, currentEntry.getProduct().getCode(), newPickupStore); if (entryToBeModified != null && !entryToBeModified.equals(currentEntry)) { throw new CartEntryException( "Ambiguous cart entries! Entry number " + currentEntry.getEntryNumber() + " after change would be the same as entry " + entryToBeModified.getEntryNumber(), CartEntryException.AMBIGIOUS_ENTRY, entryToBeModified.getEntryNumber().toString()); } } /** * Lists all customer carts. Allowed only for non-anonymous users. * * @formparam savedCartsOnly optional parameter. If the parameter is provided and its value is true only saved carts * are returned. * @formparam currentPage optional pagination parameter in case of savedCartsOnly == true. Default value 0. * @formparam pageSize optional {@link PaginationData} parameter in case of savedCartsOnly == true. Default value 20. * @formparam sort optional sort criterion in case of savedCartsOnly == true. No default value. * @queryparam fields Response configuration (list of fields, which should be returned in response). * @return All customer carts */ @RequestMapping(method = RequestMethod.GET) @ResponseBody public CartListWsDTO getCarts( @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields, @RequestParam(required = false, defaultValue = "false") final boolean savedCartsOnly, @RequestParam(required = false, defaultValue = DEFAULT_CURRENT_PAGE) final int currentPage, @RequestParam(required = false, defaultValue = DEFAULT_PAGE_SIZE) final int pageSize, @RequestParam(required = false) final String sort) { if (userFacade.isAnonymousUser()) { throw new AccessDeniedException("Access is denied"); } final CartDataList cartDataList = new CartDataList(); if (savedCartsOnly) { final PageableData pageableData = new PageableData(); pageableData.setCurrentPage(currentPage); pageableData.setPageSize(pageSize); pageableData.setSort(sort); cartDataList.setCarts(saveCartFacade.getSavedCartsForCurrentUser(pageableData, null).getResults()); } else { cartDataList.setCarts(cartFacade.getCartsForCurrentUser()); } return dataMapper.map(cartDataList, CartListWsDTO.class, fields); } /** * Returns the cart with a given identifier. * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Details of cart and it's entries */ @RequestMapping(value = "/{cartId}", method = RequestMethod.GET) @ResponseBody public CartWsDTO getCart( @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) { // CartMatchingFilter sets current cart based on cartId, so we can return cart from the session return dataMapper.map(getSessionCart(), CartWsDTO.class, fields); } /** * Creates a new cart or restores an anonymous cart as a user's cart (if an old Cart Id is given in the request) * * @formparam oldCartId Anonymous cart GUID * @formparam toMergeCartGuid User's cart GUID to merge anonymous cart to * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Created cart data */ @RequestMapping(method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) @ResponseBody public CartWsDTO createCart(@RequestParam(required = false) final String oldCartId, @RequestParam(required = false) String toMergeCartGuid, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) { if (LOG.isDebugEnabled()) { LOG.debug("createCart"); } if (StringUtils.isNotEmpty(oldCartId)) { if (userFacade.isAnonymousUser()) { throw new RuntimeException("Anonymous user is not allowed to copy cart!"); } if (!isCartAnonymous(oldCartId)) { throw new CartException("Cart is not anonymous", CartException.CANNOT_RESTORE, oldCartId); } if (StringUtils.isEmpty(toMergeCartGuid)) { toMergeCartGuid = getSessionCart().getGuid(); } else { if (!isUserCart(toMergeCartGuid)) { throw new CartException("Cart is not current user's cart", CartException.CANNOT_RESTORE, toMergeCartGuid); } } try { cartFacade.restoreAnonymousCartAndMerge(oldCartId, toMergeCartGuid); return dataMapper.map(getSessionCart(), CartWsDTO.class, fields); } catch (final CommerceCartMergingException e) { throw new CartException("Couldn't merge carts", CartException.CANNOT_MERGE, e); } catch (final CommerceCartRestorationException e) { throw new CartException("Couldn't restore cart", CartException.CANNOT_RESTORE, e); } } else { if (StringUtils.isNotEmpty(toMergeCartGuid)) { if (!isUserCart(toMergeCartGuid)) { throw new CartException("Cart is not current user's cart", CartException.CANNOT_RESTORE, toMergeCartGuid); } try { cartFacade.restoreSavedCart(toMergeCartGuid); return dataMapper.map(getSessionCart(), CartWsDTO.class, fields); } catch (final CommerceCartRestorationException e) { throw new CartException("Couldn't restore cart", CartException.CANNOT_RESTORE, oldCartId, e); } } return dataMapper.map(getSessionCart(), CartWsDTO.class, fields); } } private boolean isUserCart(final String toMergeCartGuid) { if (cartFacade instanceof CommerceWebServicesCartFacade) { final CommerceWebServicesCartFacade commerceWebServicesCartFacade = (CommerceWebServicesCartFacade) cartFacade; return commerceWebServicesCartFacade.isCurrentUserCart(toMergeCartGuid); } return true; } private boolean isCartAnonymous(final String cartGuid) { if (cartFacade instanceof CommerceWebServicesCartFacade) { final CommerceWebServicesCartFacade commerceWebServicesCartFacade = (CommerceWebServicesCartFacade) cartFacade; return commerceWebServicesCartFacade.isAnonymousUserCart(cartGuid); } return true; } /** * Deletes a cart with a given cart id. */ @RequestMapping(value = "/{cartId}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.OK) public void deleteCart() { cartFacade.removeSessionCart(); } /** * Assigns an email to the cart. This step is required to make a guest checkout. * * @formparam email Email of the guest user. It will be used during checkout process * @throws de.hybris.platform.commerceservices.customer.DuplicateUidException */ @Secured({ "ROLE_CLIENT", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/email", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.OK) public void guestLogin(@RequestParam final String email) throws DuplicateUidException { if (LOG.isDebugEnabled()) { LOG.debug("createGuestUserForAnonymousCheckout: email=" + sanitize(email)); } if (!EmailValidator.getInstance().isValid(email)) { throw new RequestParameterException("Email [" + sanitize(email) + "] is not a valid e-mail address!", RequestParameterException.INVALID, "login"); } customerFacade.createGuestUserForAnonymousCheckout(email, "guest"); } /** * Returns cart entries. * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Cart entries list */ @RequestMapping(value = "/{cartId}/entries", method = RequestMethod.GET) @ResponseBody public OrderEntryListWsDTO getCartEntries( @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) { if (LOG.isDebugEnabled()) { LOG.debug("getCartEntries"); } final OrderEntryDataList dataList = new OrderEntryDataList(); dataList.setOrderEntries(getSessionCart().getEntries()); return dataMapper.map(dataList, OrderEntryListWsDTO.class, fields); } /** * Adds a product to the cart. * * @formparam code Code of the product to be added to cart. Product look-up is performed for the current product * catalog version. * @formparam qty Quantity of product. * @formparam pickupStore Name of the store where product will be picked. Set only if want to pick up from a store. * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Information about cart modification. * @throws CommerceCartModificationException * When there are some problems with cart modification * @throws WebserviceValidationException * When store given in pickupStore parameter doesn't exist * @throws ProductLowStockException * When product is out of stock in store (when pickupStore parameter is filled) * @throws StockSystemException * When there is no information about stock for stores (when pickupStore parameter is filled). */ @RequestMapping(value = "/{cartId}/entries", method = RequestMethod.POST) @ResponseBody public CartModificationWsDTO addCartEntry(@PathVariable final String baseSiteId, @RequestParam(required = true) final String code, @RequestParam(required = false, defaultValue = "1") final long qty, @RequestParam(required = false) final String pickupStore, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws CommerceCartModificationException, WebserviceValidationException, ProductLowStockException, StockSystemException { if (LOG.isDebugEnabled()) { LOG.debug("addCartEntry: " + logParam("code", code) + ", " + logParam("qty", qty) + ", " + logParam("pickupStore", pickupStore)); } if (StringUtils.isNotEmpty(pickupStore)) { validate(pickupStore, "pickupStore", pointOfServiceValidator); } return addCartEntryInternal(baseSiteId, code, qty, pickupStore, fields); } private CartModificationWsDTO addCartEntryInternal(final String baseSiteId, final String code, final long qty, final String pickupStore, final String fields) throws CommerceCartModificationException { final CartModificationData cartModificationData; if (StringUtils.isNotEmpty(pickupStore)) { validateIfProductIsInStockInPOS(baseSiteId, code, pickupStore, null); cartModificationData = cartFacade.addToCart(code, qty, pickupStore); } else { validateIfProductIsInStockOnline(baseSiteId, code, null); cartModificationData = cartFacade.addToCart(code, qty); } return dataMapper.map(cartModificationData, CartModificationWsDTO.class, fields); } /** * Adds a product to the cart. * * @param entry * Request body parameter (DTO in xml or json format) which contains details like : product code * (product.code), quantity of product (quantity), pickup store name (deliveryPointOfService.name) * @queryparam fields Response configuration (list of fields, which should be returned in response) * @bodyparams entry,quantity,deliveryPointOfService.name,product.code * @return Information about cart modification. * @throws CommerceCartModificationException * When there are some problems with cart modification * @throws WebserviceValidationException * When there is no product code value When store given in pickupStore parameter doesn't exist * @throws ProductLowStockException * When product is out of stock in store (when pickupStore parameter is filled) * @throws StockSystemException * When there is no information about stock for stores (when pickupStore parameter is filled). */ @RequestMapping(value = "/{cartId}/entries", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }) @ResponseBody public CartModificationWsDTO addCartEntry(@PathVariable final String baseSiteId, @RequestBody final OrderEntryWsDTO entry, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws CommerceCartModificationException, WebserviceValidationException, ProductLowStockException, StockSystemException { if (entry.getQuantity() == null) { entry.setQuantity(Long.valueOf(DEFAULT_PRODUCT_QUANTITY)); } validate(entry, "entry", orderEntryCreateValidator); final String pickupStore = entry.getDeliveryPointOfService() == null ? null : entry.getDeliveryPointOfService().getName(); return addCartEntryInternal(baseSiteId, entry.getProduct().getCode(), entry.getQuantity().longValue(), pickupStore, fields); } /** * Returns the details of the cart entries. * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Cart entry data * @throws CartEntryException * When entry with given number doesn't exist */ @RequestMapping(value = "/{cartId}/entries/{entryNumber}", method = RequestMethod.GET) @ResponseBody public OrderEntryWsDTO getCartEntry(@PathVariable final long entryNumber, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) { if (LOG.isDebugEnabled()) { LOG.debug("getCartEntry: " + logParam("entryNumber", entryNumber)); } final OrderEntryData orderEntry = getCartEntryForNumber(getSessionCart(), entryNumber); return dataMapper.map(orderEntry, OrderEntryWsDTO.class, fields); } /** * Updates the quantity of a single cart entry and details of the store where the cart entry will be picked. * Attributes not provided in request will be defined again (set to null or default) * * @formparam qty Quantity of product. * @formparam pickupStore Name of the store where product will be picked. Set only if want to pick up from a store. * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Information about cart modification * @throws CartEntryException * When entry with given number doesn't exist or in case of ambiguity of cart entries * @throws WebserviceValidationException * When store given in pickupStore parameter doesn't exist * @throws CommerceCartModificationException * When there are some problems with cart modification * @throws ProductLowStockException * When product is out of stock in store (when pickupStore parameter is filled) * @throws StockSystemException * When there is no information about stock for stores (when pickupStore parameter is filled). */ @RequestMapping(value = "/{cartId}/entries/{entryNumber}", method = RequestMethod.PUT) @ResponseBody public CartModificationWsDTO setCartEntry(@PathVariable final String baseSiteId, @PathVariable final long entryNumber, @RequestParam(required = true) final Long qty, @RequestParam(required = false) final String pickupStore, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws CommerceCartModificationException { if (LOG.isDebugEnabled()) { LOG.debug("setCartEntry: " + logParam("entryNumber", entryNumber) + ", " + logParam("qty", qty) + ", " + logParam("pickupStore", pickupStore)); } final CartData cart = getSessionCart(); final OrderEntryData orderEntry = getCartEntryForNumber(cart, entryNumber); if (!StringUtils.isEmpty(pickupStore)) { validate(pickupStore, "pickupStore", pointOfServiceValidator); } return updateCartEntryInternal(baseSiteId, cart, orderEntry, qty, pickupStore, fields, true); } private CartModificationWsDTO updateCartEntryInternal(final String baseSiteId, final CartData cart, final OrderEntryData orderEntry, final Long qty, final String pickupStore, final String fields, final boolean putMode) throws CommerceCartModificationException { final long entryNumber = orderEntry.getEntryNumber().longValue(); final String productCode = orderEntry.getProduct().getCode(); final PointOfServiceData currentPointOfService = orderEntry.getDeliveryPointOfService(); CartModificationData cartModificationData1 = null; CartModificationData cartModificationData2 = null; if (!StringUtils.isEmpty(pickupStore)) { if (currentPointOfService == null || !currentPointOfService.getName().equals(pickupStore)) { //was 'shipping mode' or store is changed validateForAmbiguousPositions(cart, orderEntry, pickupStore); validateIfProductIsInStockInPOS(baseSiteId, productCode, pickupStore, Long.valueOf(entryNumber)); cartModificationData1 = cartFacade.updateCartEntry(entryNumber, pickupStore); } } else if (putMode && currentPointOfService != null) { //was 'pickup in store', now switch to 'shipping mode' validateForAmbiguousPositions(cart, orderEntry, pickupStore); validateIfProductIsInStockOnline(baseSiteId, productCode, Long.valueOf(entryNumber)); cartModificationData1 = cartFacade.updateCartEntry(entryNumber, pickupStore); } if (qty != null) { cartModificationData2 = cartFacade.updateCartEntry(entryNumber, qty.longValue()); } return dataMapper.map(mergeCartModificationData(cartModificationData1, cartModificationData2), CartModificationWsDTO.class, fields); } /** * Updates the quantity of a single cart entry and details of the store where the cart entry will be picked. * Attributes not provided in request will be defined again (set to null or default) * * @param entry * Request body parameter (DTO in xml or json format) which contains details like : quantity of product * (quantity), pickup store name (deliveryPointOfService.name) * @queryparam fields Response configuration (list of fields, which should be returned in response) * @bodyparams entry,quantity,deliveryPointOfService.name,product.code * @return Information about cart modification * @throws CartEntryException * When entry with given number doesn't exist or in case of ambiguity of cart entries * @throws WebserviceValidationException * When store given in pickupStore parameter doesn't exist * @throws CommerceCartModificationException * When there are some problems with cart modification * @throws ProductLowStockException * When product is out of stock in store (when pickupStore parameter is filled) * @throws StockSystemException * When there is no information about stock for stores (when pickupStore parameter is filled). */ @RequestMapping(value = "/{cartId}/entries/{entryNumber}", method = RequestMethod.PUT, consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }) @ResponseBody public CartModificationWsDTO setCartEntry(@PathVariable final String baseSiteId, @PathVariable final long entryNumber, @RequestBody final OrderEntryWsDTO entry, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws CommerceCartModificationException { final CartData cart = getSessionCart(); final OrderEntryData orderEntry = getCartEntryForNumber(cart, entryNumber); final String pickupStore = entry.getDeliveryPointOfService() == null ? null : entry.getDeliveryPointOfService().getName(); validateCartEntryForReplace(orderEntry, entry); return updateCartEntryInternal(baseSiteId, cart, orderEntry, entry.getQuantity(), pickupStore, fields, true); } private void validateCartEntryForReplace(final OrderEntryData oryginalEntry, final OrderEntryWsDTO entry) { final String productCode = oryginalEntry.getProduct().getCode(); final Errors errors = new BeanPropertyBindingResult(entry, "entry"); if (entry.getProduct() != null && entry.getProduct().getCode() != null && !entry.getProduct().getCode().equals(productCode)) { errors.reject("cartEntry.productCodeNotMatch"); throw new WebserviceValidationException(errors); } validate(entry, "entry", orderEntryReplaceValidator); } /** * Updates the quantity of a single cart entry and details of the store where the cart entry will be picked. * * @formparam qty Quantity of product. * @formparam pickupStore Name of the store where product will be picked. Set only if want to pick up from a store. * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Information about cart modification * @throws CartEntryException * When entry with given number doesn't exist or in case of ambiguity of cart entries * @throws WebserviceValidationException * When store given in pickupStore parameter doesn't exist * @throws CommerceCartModificationException * When there are some problems with cart modification * @throws ProductLowStockException * When product is out of stock in store (when pickupStore parameter is filled) * @throws StockSystemException * When there is no information about stock for stores (when pickupStore parameter is filled). */ @RequestMapping(value = "/{cartId}/entries/{entryNumber}", method = RequestMethod.PATCH) @ResponseBody public CartModificationWsDTO updateCartEntry(@PathVariable final String baseSiteId, @PathVariable final long entryNumber, @RequestParam(required = false) final Long qty, @RequestParam(required = false) final String pickupStore, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws CommerceCartModificationException { if (LOG.isDebugEnabled()) { LOG.debug("updateCartEntry: " + logParam("entryNumber", entryNumber) + ", " + logParam("qty", qty) + ", " + logParam("pickupStore", pickupStore)); } final CartData cart = getSessionCart(); final OrderEntryData orderEntry = getCartEntryForNumber(cart, entryNumber); if (qty == null && StringUtils.isEmpty(pickupStore)) { throw new RequestParameterException("At least one parameter (qty,pickupStore) should be set!", RequestParameterException.MISSING); } if (qty != null) { validate(qty, "quantity", greaterThanZeroValidator); } if (pickupStore != null) { validate(pickupStore, "pickupStore", pointOfServiceValidator); } return updateCartEntryInternal(baseSiteId, cart, orderEntry, qty, pickupStore, fields, false); } /** * Updates the quantity of a single cart entry and details of the store where the cart entry will be picked. * * @param entry * Request body parameter (DTO in xml or json format) which contains details like : quantity of product * (quantity), pickup store name (deliveryPointOfService.name) * @queryparam fields Response configuration (list of fields, which should be returned in response) * @bodyparams entry,quantity,deliveryPointOfService.name,product.code * @return Information about cart modification * @throws CartEntryException * When entry with given number doesn't exist or in case of ambiguity of cart entries * @throws WebserviceValidationException * When store given in pickupStore parameter doesn't exist * @throws CommerceCartModificationException * When there are some problems with cart modification * @throws ProductLowStockException * When product is out of stock in store (when pickupStore parameter is filled) * @throws StockSystemException * When there is no information about stock for stores (when pickupStore parameter is filled). */ @RequestMapping(value = "/{cartId}/entries/{entryNumber}", method = RequestMethod.PATCH, consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }) @ResponseBody public CartModificationWsDTO updateCartEntry(@PathVariable final String baseSiteId, @PathVariable final long entryNumber, @RequestBody final OrderEntryWsDTO entry, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws CommerceCartModificationException { final CartData cart = getSessionCart(); final OrderEntryData orderEntry = getCartEntryForNumber(cart, entryNumber); final String productCode = orderEntry.getProduct().getCode(); final Errors errors = new BeanPropertyBindingResult(entry, "entry"); if (entry.getProduct() != null && entry.getProduct().getCode() != null && !entry.getProduct().getCode().equals(productCode)) { errors.reject("cartEntry.productCodeNotMatch"); throw new WebserviceValidationException(errors); } if (entry.getQuantity() == null) { entry.setQuantity(orderEntry.getQuantity()); } validate(entry, "entry", orderEntryUpdateValidator); final String pickupStore = entry.getDeliveryPointOfService() == null ? null : entry.getDeliveryPointOfService().getName(); return updateCartEntryInternal(baseSiteId, cart, orderEntry, entry.getQuantity(), pickupStore, fields, false); } /** * Deletes cart entry. * * @throws CartEntryException * When entry with given number doesn't exist * @throws CommerceCartModificationException * When there are some problems with cart modification */ @RequestMapping(value = "/{cartId}/entries/{entryNumber}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.OK) public void removeCartEntry(@PathVariable final long entryNumber) throws CommerceCartModificationException { if (LOG.isDebugEnabled()) { LOG.debug("removeCartEntry: " + logParam("entryNumber", entryNumber)); } final CartData cart = getSessionCart(); getCartEntryForNumber(cart, entryNumber); cartFacade.updateCartEntry(entryNumber, 0); } /** * Creates an address and assigns it to the cart as the delivery address. * * @formparam firstName Customer's first name. This parameter is required. * @formparam lastName Customer's last name. This parameter is required. * @formparam titleCode Customer's title code. This parameter is required. For a list of codes, see * /{baseSiteId}/titles resource * @formparam country.isocode Country isocode. This parameter is required and have influence on how rest of * parameters are validated (e.g. if parameters are required : line1,line2,town,postalCode,region.isocode) * @formparam line1 First part of address. If this parameter is required depends on country (usually it is required). * @formparam line2 Second part of address. If this parameter is required depends on country (usually it is not * required) * @formparam town Town name. If this parameter is required depends on country (usually it is required) * @formparam postalCode Postal code. If this parameter is required depends on country (usually it is required) * @formparam region.isocode Isocode for region. If this parameter is required depends on country. * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Created address * @throws WebserviceValidationException * When address parameters are incorrect */ @Secured({ "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/addresses/delivery", method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) @ResponseBody public AddressWsDTO createAndSetAddress(final HttpServletRequest request, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws WebserviceValidationException, NoCheckoutCartException { if (LOG.isDebugEnabled()) { LOG.debug("createAddress"); } final AddressData addressData = super.createAddressInternal(request); final String addressId = addressData.getId(); super.setCartDeliveryAddressInternal(addressId); return dataMapper.map(addressData, AddressWsDTO.class, fields); } /** * Creates an address and assigns it to the cart as the delivery address. * * @param address * Request body parameter (DTO in xml or json format) which contains details like : Customer's first * name(firstName), Customer's last name(lastName), Customer's title code(titleCode), * country(country.isocode), first part of address(line1) , second part of address(line2), town (town), * postal code(postalCode), region (region.isocode) * @queryparam fields Response configuration (list of fields, which should be returned in response) * @bodyparams * titleCode,firstName,lastName,line1,line2,town,postalCode,country(isocode),region(isocode),defaultAddress * @return Created address * @throws WebserviceValidationException * When address parameters are incorrect */ @Secured({ "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/addresses/delivery", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }) @ResponseStatus(HttpStatus.CREATED) @ResponseBody public AddressWsDTO createAndSetAddress(@RequestBody final AddressWsDTO address, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws WebserviceValidationException, NoCheckoutCartException { if (LOG.isDebugEnabled()) { LOG.debug("createAddress"); } validate(address, "address", addressDTOValidator); AddressData addressData = dataMapper.map(address, AddressData.class, "titleCode,firstName,lastName,line1,line2,town,postalCode,country(isocode),region(isocode),defaultAddress"); addressData = createAddressInternal(addressData); setCartDeliveryAddressInternal(addressData.getId()); return dataMapper.map(addressData, AddressWsDTO.class, fields); } /** * Sets a delivery address for the cart. The address country must be placed among the delivery countries of the * current base store. * * @formparam addressId Address identifier * @throws CartAddressException * When address with given id is not valid or doesn't exists */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/addresses/delivery", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.OK) public void setCartDeliveryAddress(@RequestParam(required = true) final String addressId) throws NoCheckoutCartException { super.setCartDeliveryAddressInternal(addressId); } /** * Removes the delivery address from the cart. * * @throws CartException * When removing delivery address failed */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/addresses/delivery", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.OK) public void removeCartDeliveryAddress() { if (LOG.isDebugEnabled()) { LOG.debug("removeDeliveryAddress"); } if (!checkoutFacade.removeDeliveryAddress()) { throw new CartException("Cannot reset address!", CartException.CANNOT_RESET_ADDRESS); } } /** * Returns the delivery mode selected for the cart. * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Delivery mode selected for the cart */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/deliverymode", method = RequestMethod.GET) @ResponseBody public DeliveryModeWsDTO getCartDeliveryMode( @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) { if (LOG.isDebugEnabled()) { LOG.debug("getCartDeliveryMode"); } return dataMapper.map(getSessionCart().getDeliveryMode(), DeliveryModeWsDTO.class, fields); } /** * Sets the delivery mode with a given identifier for the cart. * * @formparam deliveryModeId Delivery mode identifier (code) * @throws UnsupportedDeliveryModeException * When the delivery mode does not exist or when the delivery address is not set for the cart */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/deliverymode", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.OK) public void setCartDeliveryMode(@RequestParam(required = true) final String deliveryModeId) throws UnsupportedDeliveryModeException { super.setCartDeliveryModeInternal(deliveryModeId); } /** * Removes the delivery mode from the cart. */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/deliverymode", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.OK) public void removeDeliveryMode() { if (LOG.isDebugEnabled()) { LOG.debug("removeDeliveryMode"); } if (!checkoutFacade.removeDeliveryMode()) { throw new CartException("Cannot reset delivery mode!", CartException.CANNOT_RESET_DELIVERYMODE); } } /** * Returns all delivery modes supported for the current base store and cart delivery address. A delivery address must * be set for the cart, otherwise an empty list will be returned. * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return All supported delivery modes */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/deliverymodes", method = RequestMethod.GET) @ResponseBody public DeliveryModeListWsDTO getSupportedDeliveryModes( @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) { if (LOG.isDebugEnabled()) { LOG.debug("getSupportedDeliveryModes"); } final DeliveryModesData deliveryModesData = new DeliveryModesData(); deliveryModesData.setDeliveryModes(checkoutFacade.getSupportedDeliveryModes()); final DeliveryModeListWsDTO dto = dataMapper.map(deliveryModesData, DeliveryModeListWsDTO.class, fields); return dto; } /** * Defines details of a new credit card payment details and assigns the payment to the cart. * * @formparam accountHolderName Name on card. This parameter is required. * @formparam cardNumber Card number. This parameter is required. * @formparam cardType Card type. This parameter is required. Call GET /{baseSiteId}/cardtypes beforehand to see what * card types are supported * @formparam expiryMonth Month of expiry date. This parameter is required. * @formparam expiryYear Year of expiry date. This parameter is required. * @formparam issueNumber * @formparam startMonth * @formparam startYear * @formparam subscriptionId * @formparam saved Parameter defines if the payment details should be saved for the customer and than could be * reused for future orders. * @formparam defaultPaymentInfo Parameter defines if the payment details should be used as default for customer. * @formparam billingAddress.firstName Customer's first name. This parameter is required. * @formparam billingAddress.lastName Customer's last name. This parameter is required. * @formparam billingAddress.titleCode Customer's title code. This parameter is required. For a list of codes, see * /{baseSiteId}/titles resource * @formparam billingAddress.country.isocode Country isocode. This parameter is required and have influence on how * rest of address parameters are validated (e.g. if parameters are required : * line1,line2,town,postalCode,region.isocode) * @formparam billingAddress.line1 First part of address. If this parameter is required depends on country (usually * it is required). * @formparam billingAddress.line2 Second part of address. If this parameter is required depends on country (usually * it is not required) * @formparam billingAddress.town Town name. If this parameter is required depends on country (usually it is * required) * @formparam billingAddress.postalCode Postal code. If this parameter is required depends on country (usually it is * required) * @formparam billingAddress.region.isocode Isocode for region. If this parameter is required depends on country. * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Created payment details * @throws WebserviceValidationException * @throws InvalidPaymentInfoException * @throws NoCheckoutCartException * @throws UnsupportedRequestException */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/paymentdetails", method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) @ResponseBody public PaymentDetailsWsDTO addPaymentDetails(final HttpServletRequest request, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws WebserviceValidationException, InvalidPaymentInfoException, NoCheckoutCartException, UnsupportedRequestException { paymentProviderRequestSupportedStrategy.checkIfRequestSupported("addPaymentDetails"); final CCPaymentInfoData paymentInfoData = super.addPaymentDetailsInternal(request).getPaymentInfo(); return dataMapper.map(paymentInfoData, PaymentDetailsWsDTO.class, fields); } /** * Defines details of a new credit card payment details and assigns the payment to the cart. * * @param paymentDetails * Request body parameter (DTO in xml or json format) which contains details like : Name on card * (accountHolderName), card number(cardNumber), card type (cardType.code), Month of expiry date * (expiryMonth), Year of expiry date (expiryYear), if payment details should be saved (saved), if if the * payment details should be used as default (defaultPaymentInfo), billing address ( * billingAddress.firstName,billingAddress.lastName, billingAddress.titleCode, * billingAddress.country.isocode, billingAddress.line1, billingAddress.line2, billingAddress.town, * billingAddress.postalCode, billingAddress.region.isocode) * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @bodyparams * accountHolderName,cardNumber,cardType,cardTypeData(code),expiryMonth,expiryYear,issueNumber,startMonth, * startYear * ,subscriptionId,defaultPaymentInfo,saved,billingAddress(titleCode,firstName,lastName,line1,line2 * ,town,postalCode,country(isocode),region(isocode),defaultAddress) * @return Created payment details * @throws WebserviceValidationException * @throws InvalidPaymentInfoException * @throws NoCheckoutCartException * @throws UnsupportedRequestException */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/paymentdetails", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }) @ResponseStatus(HttpStatus.CREATED) @ResponseBody public PaymentDetailsWsDTO addPaymentDetails(@RequestBody final PaymentDetailsWsDTO paymentDetails, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) throws WebserviceValidationException, InvalidPaymentInfoException, NoCheckoutCartException, UnsupportedRequestException { paymentProviderRequestSupportedStrategy.checkIfRequestSupported("addPaymentDetails"); validatePayment(paymentDetails); final String copiedfields = "accountHolderName,cardNumber,cardType,cardTypeData(code),expiryMonth,expiryYear,issueNumber,startMonth,startYear,subscriptionId,defaultPaymentInfo,saved," + "billingAddress(titleCode,firstName,lastName,line1,line2,town,postalCode,country(isocode),region(isocode),defaultAddress)"; CCPaymentInfoData paymentInfoData = dataMapper.map(paymentDetails, CCPaymentInfoData.class, copiedfields); paymentInfoData = addPaymentDetailsInternal(paymentInfoData).getPaymentInfo(); return dataMapper.map(paymentInfoData, PaymentDetailsWsDTO.class, fields); } private void validatePayment(final PaymentDetailsWsDTO paymentDetails) throws NoCheckoutCartException { if (!checkoutFacade.hasCheckoutCart()) { throw new NoCheckoutCartException("Cannot add PaymentInfo. There was no checkout cart created yet!"); } validate(paymentDetails, "paymentDetails", paymentDetailsDTOValidator); } /** * Sets credit card payment details for the cart. * * @formparam paymentDetailsId Payment details identifier * @throws InvalidPaymentInfoException * When payment details with given id doesn't exists or belong to another user */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/paymentdetails", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.OK) public void setPaymentDetails(@RequestParam(required = true) final String paymentDetailsId) throws InvalidPaymentInfoException { super.setPaymentDetailsInternal(paymentDetailsId); } /** * Return information about promotions applied on cart * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Information about promotions applied on cart */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_CLIENT", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/promotions", method = RequestMethod.GET) @ResponseBody public PromotionResultListWsDTO getPromotions( @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) { if (LOG.isDebugEnabled()) { LOG.debug("getPromotions"); } final List<PromotionResultData> appliedPromotions = new ArrayList<>(); final List<PromotionResultData> orderPromotions = getSessionCart().getAppliedOrderPromotions(); final List<PromotionResultData> productPromotions = getSessionCart().getAppliedProductPromotions(); appliedPromotions.addAll(orderPromotions); appliedPromotions.addAll(productPromotions); final PromotionResultDataList dataList = new PromotionResultDataList(); dataList.setPromotions(appliedPromotions); return dataMapper.map(dataList, PromotionResultListWsDTO.class, fields); } /** * Return information about promotion with given id, applied on cart. * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return Information about promotion with given id, applied on cart */ @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_CLIENT", "ROLE_GUEST", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/promotions/{promotionId}", method = RequestMethod.GET) @ResponseBody public PromotionResultListWsDTO getPromotion(@PathVariable final String promotionId, @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) { if (LOG.isDebugEnabled()) { LOG.debug("getPromotion: promotionId = " + sanitize(promotionId)); } final List<PromotionResultData> appliedPromotions = new ArrayList<PromotionResultData>(); final List<PromotionResultData> orderPromotions = getSessionCart().getAppliedOrderPromotions(); final List<PromotionResultData> productPromotions = getSessionCart().getAppliedProductPromotions(); for (final PromotionResultData prd : orderPromotions) { if (prd.getPromotionData().getCode().equals(promotionId)) { appliedPromotions.add(prd); } } for (final PromotionResultData prd : productPromotions) { if (prd.getPromotionData().getCode().equals(promotionId)) { appliedPromotions.add(prd); } } final PromotionResultDataList dataList = new PromotionResultDataList(); dataList.setPromotions(appliedPromotions); return dataMapper.map(dataList, PromotionResultListWsDTO.class, fields); } /** * Enables the promotion for the order based on the promotionId defined for the cart. * * @formparam promotionId Promotion identifier * @throws CommercePromotionRestrictionException * When there is no PromotionOrderRestriction for the promotion */ @Secured({ "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/promotions", method = RequestMethod.POST) @ResponseStatus(HttpStatus.OK) public void applyPromotion(@RequestParam(required = true) final String promotionId) throws CommercePromotionRestrictionException { if (LOG.isDebugEnabled()) { LOG.debug("applyPromotion: promotionId = " + sanitize(promotionId)); } commercePromotionRestrictionFacade.enablePromotionForCurrentCart(promotionId); } /** * Disables the promotion for the order based on the promotionId defined for the cart. * * @throws CommercePromotionRestrictionException * When there is no PromotionOrderRestriction for the promotion */ @Secured({ "ROLE_TRUSTED_CLIENT" }) @RequestMapping(value = "/{cartId}/promotions/{promotionId}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.OK) public void removePromotion(@PathVariable final String promotionId) throws CommercePromotionRestrictionException, NoCheckoutCartException { if (LOG.isDebugEnabled()) { LOG.debug("removePromotion: promotionId = " + sanitize(promotionId)); } commercePromotionRestrictionFacade.disablePromotionForCurrentCart(promotionId); } /** * Returns list of vouchers applied to the cart. * * @queryparam fields Response configuration (list of fields, which should be returned in response) * @return List of vouchers applied to the cart. */ @Secured({ "ROLE_CLIENT", "ROLE_CUSTOMERGROUP", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT", "ROLE_GUEST" }) @RequestMapping(value = "/{cartId}/vouchers", method = RequestMethod.GET) @ResponseBody public VoucherListWsDTO getVouchers( @RequestParam(required = false, defaultValue = DEFAULT_FIELD_SET) final String fields) { if (LOG.isDebugEnabled()) { LOG.debug("getVouchers"); } final VoucherDataList dataList = new VoucherDataList(); dataList.setVouchers(getSessionCart().getAppliedVouchers()); return dataMapper.map(dataList, VoucherListWsDTO.class, fields); } /** * Applies a voucher based on the voucherId defined for the cart. * * @formparam voucherId Voucher identifier * @throws VoucherOperationException * When trying to apply a non-existent voucher or other error occurs during the voucher-application * process. */ @Secured({ "ROLE_CLIENT", "ROLE_CUSTOMERGROUP", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT", "ROLE_GUEST" }) @RequestMapping(value = "/{cartId}/vouchers", method = RequestMethod.POST) @ResponseStatus(HttpStatus.OK) public void applyVoucherForCart(@RequestParam(required = true) final String voucherId) throws NoCheckoutCartException, VoucherOperationException { super.applyVoucherForCartInternal(voucherId); } /** * Removes a voucher based on the voucherId defined for the current cart. * * @throws VoucherOperationException * When an error occurs during the release voucher process. */ @Secured({ "ROLE_CLIENT", "ROLE_CUSTOMERGROUP", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT", "ROLE_GUEST" }) @RequestMapping(value = "/{cartId}/vouchers/{voucherId}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.OK) public void releaseVoucherFromCart(@PathVariable final String voucherId) throws NoCheckoutCartException, VoucherOperationException { if (LOG.isDebugEnabled()) { LOG.debug("release voucher : voucherCode = " + sanitize(voucherId)); } if (!checkoutFacade.hasCheckoutCart()) { throw new NoCheckoutCartException("Cannot realese voucher. There was no checkout cart created yet!"); } voucherFacade.releaseVoucher(voucherId); } protected void validateIfProductIsInStockInPOS(final String baseSiteId, final String productCode, final String storeName, final Long entryNumber) { if (!commerceStockFacade.isStockSystemEnabled(baseSiteId)) { throw new StockSystemException("Stock system is not enabled on this site", StockSystemException.NOT_ENABLED, baseSiteId); } final StockData stock = commerceStockFacade.getStockDataForProductAndPointOfService(productCode, storeName); if (stock != null && stock.getStockLevelStatus().equals(StockLevelStatus.OUTOFSTOCK)) { if (entryNumber != null) { throw new LowStockException("Product [" + sanitize(productCode) + "] is currently out of stock", LowStockException.NO_STOCK, String.valueOf(entryNumber)); } else { throw new ProductLowStockException( "Product [" + sanitize(productCode) + "] is currently out of stock", LowStockException.NO_STOCK, productCode); } } else if (stock != null && stock.getStockLevelStatus().equals(StockLevelStatus.LOWSTOCK)) { if (entryNumber != null) { throw new LowStockException("Not enough product in stock", LowStockException.LOW_STOCK, String.valueOf(entryNumber)); } else { throw new ProductLowStockException("Not enough product in stock", LowStockException.LOW_STOCK, productCode); } } } protected void validateIfProductIsInStockOnline(final String baseSiteId, final String productCode, final Long entryNumber) { if (!commerceStockFacade.isStockSystemEnabled(baseSiteId)) { throw new StockSystemException("Stock system is not enabled on this site", StockSystemException.NOT_ENABLED, baseSiteId); } final StockData stock = commerceStockFacade.getStockDataForProductAndBaseSite(productCode, baseSiteId); if (stock != null && stock.getStockLevelStatus().equals(StockLevelStatus.OUTOFSTOCK)) { if (entryNumber != null) { throw new LowStockException( "Product [" + sanitize(productCode) + "] cannot be shipped - out of stock online", LowStockException.NO_STOCK, String.valueOf(entryNumber)); } else { throw new ProductLowStockException( "Product [" + sanitize(productCode) + "] cannot be shipped - out of stock online", LowStockException.NO_STOCK, productCode); } } } }