Skip to content

Commit

Permalink
Merge pull request #177 from Adyen/billing_address_separation_PW-2047
Browse files Browse the repository at this point in the history
[PW-2047] : Billing address separation
  • Loading branch information
rkewlani authored May 22, 2020
2 parents 2b5f00f + 36b3b94 commit db468f4
Show file tree
Hide file tree
Showing 18 changed files with 648 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ interface MultiStepCheckout
String Validate3DSecurePaymentPage = ADDON_PREFIX + "pages/checkout/multi/3d-secure-payment-validation";
String HppPaymentPage = ADDON_PREFIX + "pages/checkout/multi/hpp-payment";
String Validate3DS2PaymentPage = ADDON_PREFIX + "pages/checkout/multi/3ds2_payment";
String BillingAddressformPage = ADDON_PREFIX + "pages/checkout/multi/billingAddressForm";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,29 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
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.validation.BindingResult;
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.adyen.service.exception.ApiException;
import com.adyen.v6.constants.AdyenControllerConstants;
import com.adyen.v6.facades.AdyenCheckoutFacade;
import com.adyen.v6.forms.AddressForm;
import com.adyen.v6.forms.AdyenPaymentForm;
import de.hybris.platform.acceleratorstorefrontcommons.annotations.RequireHardLogIn;
import de.hybris.platform.acceleratorstorefrontcommons.checkout.steps.CheckoutStep;
Expand All @@ -49,6 +55,11 @@
import de.hybris.platform.cms2.exceptions.CMSItemNotFoundException;
import de.hybris.platform.cms2.model.pages.ContentPageModel;
import de.hybris.platform.commercefacades.order.data.CartData;
import de.hybris.platform.commercefacades.user.UserFacade;
import de.hybris.platform.commercefacades.user.data.AddressData;
import de.hybris.platform.commercefacades.user.data.CountryData;
import de.hybris.platform.commercefacades.user.data.TitleData;
import static com.adyen.v6.constants.AdyenControllerConstants.Views.Pages.MultiStepCheckout.BillingAddressformPage;
import static com.adyen.v6.facades.DefaultAdyenCheckoutFacade.MODEL_ORIGIN_KEY;
import static de.hybris.platform.acceleratorstorefrontcommons.constants.WebConstants.BREADCRUMBS_KEY;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
Expand All @@ -71,6 +82,23 @@ public class SelectPaymentMethodCheckoutStepController extends AbstractCheckoutS
@Resource(name = "adyenCheckoutFacade")
private AdyenCheckoutFacade adyenCheckoutFacade;

@Resource(name = "userFacade")
private UserFacade userFacade;

@ModelAttribute("billingCountries")
public Collection<CountryData> getBillingCountries() {
return getCheckoutFacade().getBillingCountries();
}

@ModelAttribute("titles")
public Collection<TitleData> getBillingTitleCodes() {
return getUserFacade().getTitles();
}

protected UserFacade getUserFacade() {
return userFacade;
}

@Autowired
private HttpServletRequest httpServletRequest;

Expand All @@ -87,10 +115,12 @@ public String enterStep(final Model model, final RedirectAttributes redirectAttr
model.addAttribute("metaRobots", "noindex,nofollow");
model.addAttribute("hasNoPaymentInfo", getCheckoutFlowFacade().hasNoPaymentInfo());
model.addAttribute(BREADCRUMBS_KEY, getResourceBreadcrumbBuilder().getBreadcrumbs(CHECKOUT_MULTI_PAYMENT_METHOD_BREADCRUMB));
model.addAttribute(ADYEN_PAYMENT_FORM, new AdyenPaymentForm());

if (! model.containsAttribute(ADYEN_PAYMENT_FORM)) {
model.addAttribute(ADYEN_PAYMENT_FORM, new AdyenPaymentForm());
}
model.addAttribute(CSE_GENERATION_TIME, fromCalendar(Calendar.getInstance()));
model.addAttribute(CART_DATA_ATTR, cartData);
model.addAttribute("deliveryAddress", cartData.getDeliveryAddress());
model.addAttribute("expiryYears", getExpiryYears());

try {
Expand All @@ -113,6 +143,40 @@ public String enterStep(final Model model, final RedirectAttributes redirectAttr
return AdyenControllerConstants.Views.Pages.MultiStepCheckout.SelectPaymentMethod;
}


@RequestMapping(value = "/billingaddressform", method = RequestMethod.GET)
public String getCountryAddressForm(@RequestParam("countryIsoCode") final String countryIsoCode,
@RequestParam("useAdyenDeliveryAddress") final boolean useAdyenDeliveryAddress,
final Model model) {

model.addAttribute("supportedCountries", getCountries());
model.addAttribute("regions", getI18NFacade().getRegionsForCountryIso(countryIsoCode));
model.addAttribute("country", countryIsoCode);

final AdyenPaymentForm adyenPaymentForm = new AdyenPaymentForm();
AddressForm addressForm = new AddressForm();

if (useAdyenDeliveryAddress) {
final AddressData deliveryAddress = getCheckoutFacade().getCheckoutCart().getDeliveryAddress();
if (deliveryAddress.getRegion() != null && ! StringUtils.isEmpty(deliveryAddress.getRegion().getIsocode())) {
addressForm.setRegionIso(deliveryAddress.getRegion().getIsocodeShort());
}
addressForm.setTitleCode(deliveryAddress.getTitleCode());
addressForm.setFirstName(deliveryAddress.getFirstName());
addressForm.setLastName(deliveryAddress.getLastName());
addressForm.setLine1(deliveryAddress.getLine1());
addressForm.setLine2(deliveryAddress.getLine2());
addressForm.setTownCity(deliveryAddress.getTown());
addressForm.setPostcode(deliveryAddress.getPostalCode());
addressForm.setCountryIsoCode(deliveryAddress.getCountry().getIsocode());
addressForm.setPhoneNumber(deliveryAddress.getPhone());
}
adyenPaymentForm.setBillingAddress(addressForm);
model.addAttribute("adyenPaymentForm", adyenPaymentForm);
return BillingAddressformPage;
}


@RequestMapping(value = "", method = POST)
@RequireHardLogIn
public String setPaymentMethod(final Model model,
Expand All @@ -122,9 +186,13 @@ public String setPaymentMethod(final Model model,
LOGGER.debug("PaymentForm: " + adyenPaymentForm);

adyenCheckoutFacade.handlePaymentForm(adyenPaymentForm, bindingResult);
if (bindingResult.hasErrors()) {

if (bindingResult.hasGlobalErrors()|| bindingResult.hasErrors()) {
LOGGER.debug(bindingResult.getAllErrors().stream().map(error -> (error.getCode())).reduce((x, y) -> (x = x + y)));
GlobalMessages.addErrorMessage(model, "checkout.error.paymentethod.formentry.invalid");
if (adyenPaymentForm.getBillingAddress() != null) {
adyenPaymentForm.resetFormExceptBillingAddress();
}
return enterStep(model, redirectAttributes);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ checkout.error.authorization.payment.error=An error occured.
checkout.error.authorization.pos.configuration=Error reaching POS terminal. Check the terminal connection/configuration and try again.
checkout.error.authorization.pos.busy=The terminal is busy. Wait for the current transaction to end and try again later.
checkout.error.authorization.pos.pin=The payment is REFUSED. Please check your Card details.
checkout.error.billing.address=Some fields were not filled in correctly. Please check if your details are correct

text.account.storedCards.empty=There are no stored cards
text.account.storedCard.delete=Remove
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<%@ attribute name="supportedCountries" required="false" type="java.util.List" %>
<%@ attribute name="regions" required="false" type="java.util.List" %>
<%@ attribute name="country" required="false" type="java.lang.String" %>
<%@ attribute name="tabindex" required="false" type="java.lang.String" %>
<%@ taglib prefix="formElement" tagdir="/WEB-INF/tags/responsive/formElement" %>
<%@ taglib prefix="address" tagdir="/WEB-INF/tags/addons/adyenv6b2ccheckoutaddon/responsive" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<div id="billingAdyenCountrySelector" data-address-code="${fn:escapeXml(cartData.deliveryAddress.id)}" data-country-iso-code="${fn:escapeXml(cartData.deliveryAddress.country.isocode)}"
data-display-title="false" class="clearfix">
<formElement:formSelectBox idKey="address.country"
labelKey="address.country"
path="billingAddress.countryIsoCode"
mandatory="true"
skipBlank="false"
skipBlankMessageKey="address.selectCountry"
items="${supportedCountries}"
itemValue="isocode"
tabindex="${tabindex}"
selectCSSClass="form-control"/>
</div>

<div id="adyenBillingAddressForm" class="billingAddressForm">
<address:billingAddressFormElements regions="${regions}"
country="${country}"
tabindex="${tabindex + 1}"/>
</div>


Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<%@ attribute name="regions" required="true" type="java.util.List" %>
<%@ attribute name="country" required="false" type="java.lang.String" %>
<%@ attribute name="tabindex" required="false" type="java.lang.Integer" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="formElement" tagdir="/WEB-INF/tags/responsive/formElement" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="theme" tagdir="/WEB-INF/tags/shared/theme" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="ycommerce" uri="http://hybris.com/tld/ycommercetags" %>

<c:choose>
<c:when test="${country == 'US'}">
<formElement:formSelectBox idKey="address.title" labelKey="address.title" path="billingAddress.titleCode" mandatory="true" skipBlank="false" skipBlankMessageKey="address.title.pleaseSelect"
items="${titles}" selectedValue="${addressForm.titleCode}" tabindex="${tabindex + 1}" selectCSSClass="form-control"/>
<formElement:formInputBox idKey="address.firstName" labelKey="address.firstName" path="billingAddress.firstName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 2}"/>
<formElement:formInputBox idKey="address.surname" labelKey="address.surname" path="billingAddress.lastName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 3}"/>
<formElement:formInputBox idKey="address.line1" labelKey="address.line1" path="billingAddress.line1" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 4}"/>
<formElement:formInputBox idKey="address.line2" labelKey="address.line2" path="billingAddress.line2" inputCSS="form-control" mandatory="false" tabindex="${tabindex + 5}"/>
<formElement:formInputBox idKey="address.townCity" labelKey="address.townCity" path="billingAddress.townCity" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 6}"/>
<formElement:formSelectBox idKey="address.region" labelKey="address.regionIso" path="billingAddress.regionIso" mandatory="true" skipBlank="false" skipBlankMessageKey="address.selectState"
items="${regions}" itemValue="isocodeShort" tabindex="${tabindex + 7}" selectCSSClass="form-control"/>
<formElement:formInputBox idKey="address.postcode" labelKey="address.postcode" path="billingAddress.postcode" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 8}"/>
<formElement:formInputBox idKey="address.phone" labelKey="address.phone" path="billingAddress.phoneNumber" inputCSS="form-control" mandatory="false" tabindex="${tabindex + 9}"/>
</c:when>
<c:when test="${country == 'CA'}">
<formElement:formSelectBox idKey="address.title" labelKey="address.title" path="billingAddress.titleCode" mandatory="true" skipBlank="false" skipBlankMessageKey="address.title.pleaseSelect"
items="${titles}" selectedValue="${addressForm.titleCode}" tabindex="${tabindex + 1}" selectCSSClass="form-control"/>
<formElement:formInputBox idKey="address.firstName" labelKey="address.firstName" path="billingAddress.firstName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 2}"/>
<formElement:formInputBox idKey="address.surname" labelKey="address.surname" path="billingAddress.lastName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 3}"/>
<formElement:formInputBox idKey="address.line1" labelKey="address.line1" path="billingAddress.line1" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 4}"/>
<formElement:formInputBox idKey="address.line2" labelKey="address.line2" path="billingAddress.line2" inputCSS="form-control" mandatory="false" tabindex="${tabindex + 5}"/>
<formElement:formInputBox idKey="address.townCity" labelKey="address.townCity" path="billingAddress.townCity" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 6}"/>
<formElement:formSelectBox idKey="address.region" labelKey="address.province" path="billingAddress.regionIso" mandatory="true" skipBlank="false" skipBlankMessageKey="address.selectProvince"
items="${regions}" itemValue="isocodeShort" tabindex="${tabindex + 7}" selectCSSClass="form-control"/>
<formElement:formInputBox idKey="address.postcode" labelKey="address.postcode" path="billingAddress.postcode" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 8}"/>
<formElement:formInputBox idKey="address.phone" labelKey="address.phone" path="billingAddress.phoneNumber" inputCSS="form-control" mandatory="false" tabindex="${tabindex + 9}"/>
</c:when>
<c:when test="${country == 'CN'}">
<formElement:formInputBox idKey="address.postcode" labelKey="address.postcode" path="billingAddress.postcode" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 2}"/>
<formElement:formSelectBox idKey="address.region" labelKey="address.province" path="billingAddress.regionIso" mandatory="true" skipBlank="false" skipBlankMessageKey="address.selectProvince"
items="${regions}" itemValue="isocodeShort" tabindex="${tabindex + 3}" selectCSSClass="form-control"/>
<formElement:formInputBox idKey="address.townCity" labelKey="address.townCity" path="billingAddress.townCity" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 4}"/>
<formElement:formInputBox idKey="address.line1" labelKey="address.district_and_street" path="billingAddress.line1" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 5}"/>
<formElement:formInputBox idKey="address.line2" labelKey="address.building_and_room" path="billingAddress.line2" inputCSS="form-control" mandatory="false" tabindex="${tabindex + 6}"/>
<formElement:formInputBox idKey="address.surname" labelKey="address.surname" path="billingAddress.lastName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 7}"/>
<formElement:formInputBox idKey="address.firstName" labelKey="address.firstName" path="billingAddress.firstName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 8}"/>
<formElement:formSelectBox idKey="address.title" labelKey="address.title" path="billingAddress.titleCode" mandatory="true" skipBlank="false" skipBlankMessageKey="address.title.pleaseSelect"
items="${titles}" selectedValue="${addressForm.titleCode}" tabindex="${tabindex + 1}" selectCSSClass="form-control"/>
<formElement:formInputBox idKey="address.phone" labelKey="address.phone" path="billingAddress.phoneNumber" inputCSS="form-control" mandatory="false" tabindex="${tabindex + 9}"/>
</c:when>
<c:when test="${country == 'JP'}">
<formElement:formSelectBox idKey="address.title" labelKey="address.title" path="billingAddress.titleCode" mandatory="true" skipBlank="false" skipBlankMessageKey="address.title.pleaseSelect"
items="${titles}" selectedValue="${addressForm.titleCode}" tabindex="${tabindex + 1}" selectCSSClass="form-control"/>
<formElement:formInputBox idKey="address.surname" labelKey="address.surname" path="billingAddress.lastName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 2}"/>
<formElement:formInputBox idKey="address.firstName" labelKey="address.firstName" path="billingAddress.firstName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 3}"/>
<formElement:formInputBox idKey="address.postcode" labelKey="address.postcodeJP" path="billingAddress.postcode" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 4}"/>
<formElement:formSelectBox idKey="address.region" labelKey="address.prefecture" path="billingAddress.regionIso" mandatory="true" skipBlank="false" skipBlankMessageKey="address.selectPrefecture"
items="${regions}" itemValue="isocodeShort" tabindex="${tabindex + 5}" selectCSSClass="form-control"/>
<formElement:formInputBox idKey="address.townCity" labelKey="address.townJP" path="billingAddress.townCity" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 6}"/>
<formElement:formInputBox idKey="address.line2" labelKey="address.subarea" path="billingAddress.line2" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 7}"/>
<formElement:formInputBox idKey="address.line1" labelKey="address.furtherSubarea" path="billingAddress.line1" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 8}"/>
<formElement:formInputBox idKey="address.phone" labelKey="address.phone" path="billingAddress.phoneNumber" inputCSS="form-control" mandatory="false" tabindex="${tabindex + 9}"/>
</c:when>
<c:otherwise>
<formElement:formSelectBox idKey="address.title" labelKey="address.title" path="billingAddress.titleCode" mandatory="true" skipBlank="false" skipBlankMessageKey="address.title.pleaseSelect"
items="${titles}" selectedValue="${addressForm.titleCode}" tabindex="${tabindex + 1}" selectCSSClass="form-control"/>
<formElement:formInputBox idKey="address.firstName" labelKey="address.firstName" path="billingAddress.firstName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 2}"/>
<formElement:formInputBox idKey="address.surname" labelKey="address.surname" path="billingAddress.lastName" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 3}"/>
<formElement:formInputBox idKey="address.line1" labelKey="address.line1" path="billingAddress.line1" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 4}"/>
<formElement:formInputBox idKey="address.line2" labelKey="address.line2" path="billingAddress.line2" inputCSS="form-control" mandatory="false" tabindex="${tabindex + 5}"/>
<formElement:formInputBox idKey="address.townCity" labelKey="address.townCity" path="billingAddress.townCity" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 6}"/>
<formElement:formInputBox idKey="address.postcode" labelKey="address.postcode" path="billingAddress.postcode" inputCSS="form-control" mandatory="true" tabindex="${tabindex + 7}"/>
<formElement:formInputBox idKey="address.phone" labelKey="address.phone" path="billingAddress.phoneNumber" inputCSS="form-control" mandatory="false" tabindex="${tabindex + 9}"/>
</c:otherwise>

</c:choose>
Loading

0 comments on commit db468f4

Please sign in to comment.