package cart; import common.contexts.UserContext; import common.controllers.ControllerDependency; import io.sphere.sdk.carts.Cart; import io.sphere.sdk.carts.commands.CartUpdateCommand; import io.sphere.sdk.carts.commands.updateactions.ChangeLineItemQuantity; import io.sphere.sdk.carts.commands.updateactions.RemoveLineItem; import io.sphere.sdk.models.Base; import play.Logger; import play.data.Form; import play.data.validation.Constraints; import play.libs.F; import play.mvc.Result; import javax.inject.Inject; import static org.apache.commons.lang3.ObjectUtils.firstNonNull; /** * Changes the quantity of a line item in a cart or even removes it. In success case returns to the cart detail page. */ public class LineItemQuantityChangeController extends CartController { private static final String DELETE = "delete"; private static final String EDIT = "edit"; @Inject public LineItemQuantityChangeController(final ControllerDependency controllerDependency) { super(controllerDependency); } public F.Promise<Result> process(final String languageTag) { final Form<LineItemQuantityFormData> filledForm = bindForm(); if (filledForm.hasErrors()) { return F.Promise.pure(redirect(reverseRouter().cart(languageTag))); } else { final UserContext userContext = userContext(languageTag); final F.Promise<Cart> cartPromise = getOrCreateCart(userContext, session()); final LineItemQuantityFormData formData = filledForm.get(); final String subject = formData.getSubject(); if (EDIT.equals(subject)) { return cartPromise.flatMap(cart -> changeQuantity(formData, cart, languageTag)); } else if (DELETE.equals(subject)) { return cartPromise.flatMap(cart -> deleteFromCart(formData, cart, languageTag)); } else { Logger.error("Subject '{}' does not match the requirements.", subject); return F.Promise.pure(redirect(reverseRouter().cart(languageTag))); } } } private F.Promise<Result> deleteFromCart(final LineItemQuantityFormData formData, final Cart cart, final String languageTag) { final String lineItemId = formData.getLineItemId(); return sphere().execute(CartUpdateCommand.of(cart, RemoveLineItem.of(lineItemId))) .map(updatedCart -> { CartSessionUtils.overwriteCartSessionData(cart, session()); return redirect(reverseRouter().cart(languageTag)); }); } private F.Promise<Result> changeQuantity(final LineItemQuantityFormData formData, final Cart cart, final String languageTag) { final String lineItemId = formData.getLineItemId(); final Long newQuantity = firstNonNull(formData.getQuantity(), 0L); return sphere().execute(CartUpdateCommand.of(cart, ChangeLineItemQuantity.of(lineItemId, newQuantity))) .map(updatedCart -> { CartSessionUtils.overwriteCartSessionData(cart, session()); return redirect(reverseRouter().cart(languageTag)); }); } private Form<LineItemQuantityFormData> bindForm() { return Form.form(LineItemQuantityFormData.class).bindFromRequest(); } public static class LineItemQuantityFormData extends Base { @Constraints.Required @Constraints.Pattern(DELETE + "|" + EDIT) private String subject; @Constraints.Required private String lineItemId; @Constraints.Min(0) private Long quantity; public LineItemQuantityFormData() { } public String getSubject() { return subject; } public void setSubject(final String subject) { this.subject = subject; } public String getLineItemId() { return lineItemId; } public void setLineItemId(final String lineItemId) { this.lineItemId = lineItemId; } public Long getQuantity() { return quantity; } public void setQuantity(final Long quantity) { this.quantity = quantity; } } }