Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AD-247 Implement Conditional Region/State Field in Shipping Address f… #445

Merged
merged 1 commit into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package com.adyen.commerce.controllers.api;

import com.adyen.commerce.response.ConfigurationResponse;
import com.adyen.commerce.response.RegionResponse;
import de.hybris.platform.commercefacades.i18n.I18NFacade;
import de.hybris.platform.commercefacades.order.CheckoutFacade;
import de.hybris.platform.commercefacades.user.UserFacade;
import de.hybris.platform.commercefacades.user.data.RegionData;
import de.hybris.platform.commerceservices.enums.CountryType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/api/configuration")
public class AdyenConfigurationController {
Expand All @@ -20,15 +27,30 @@ public class AdyenConfigurationController {
@Autowired
private UserFacade userFacade;

@Autowired
private I18NFacade i18NFacade;

@GetMapping("/shipping-address")
public ResponseEntity<ConfigurationResponse> getConfiguration() {
public ResponseEntity<ConfigurationResponse> getConfiguration(Map map) {
ConfigurationResponse configurationResponse = new ConfigurationResponse();

configurationResponse.setCountries(checkoutFacade.getCountries(CountryType.SHIPPING));
configurationResponse.setTitles(userFacade.getTitles());
configurationResponse.setAnonymous(userFacade.isAnonymousUser());
configurationResponse.setRegions(mapRegions(i18NFacade.getRegionsForAllCountries()));

return ResponseEntity.ok(configurationResponse);
}

private List<RegionResponse> mapRegions(final Map<String, List<RegionData>> regions) {
List<RegionResponse> result = new ArrayList<>();

regions.forEach((k, v) -> {
RegionResponse regionResponse = new RegionResponse(k, v);
result.add(regionResponse);
});

return result;
}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.adyen.commerce.response;

import de.hybris.platform.commercefacades.user.data.CountryData;
import de.hybris.platform.commercefacades.user.data.RegionData;
import de.hybris.platform.commercefacades.user.data.TitleData;

import java.util.List;
import java.util.Map;

public class ConfigurationResponse {
private boolean isAnonymous;
private List<CountryData> countries;
private List<TitleData> titles;
private List<RegionResponse> regions;

public boolean isAnonymous() {
return isAnonymous;
Expand All @@ -33,4 +36,12 @@ public List<TitleData> getTitles() {
public void setTitles(List<TitleData> titles) {
this.titles = titles;
}

public List<RegionResponse> getRegions() {
return regions;
}

public void setRegions(List<RegionResponse> regions) {
this.regions = regions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.adyen.commerce.response;

import de.hybris.platform.commercefacades.user.data.RegionData;

import java.util.List;

public class RegionResponse {
String countryCode;
List<RegionData> regionData;

public RegionResponse(){}

public RegionResponse(String countryCode, List<RegionData> regionData) {
this.countryCode = countryCode;
this.regionData = regionData;
}

public String getCountryCode() {
return countryCode;
}

public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}

public List<RegionData> getRegionData() {
return regionData;
}

public void setRegionData(List<RegionData> regionData) {
this.regionData = regionData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {InputDropdown} from "../controls/InputDropdown";
import {InputText} from "../controls/InputText";
import React from "react";
import {AddressConfigModel} from "../../reducers/addressConfigReducer";
import {AddressModel} from "../../reducers/types";
import {AddressModel, CodeValueItem} from "../../reducers/types";
import {translationsStore} from "../../store/translationsStore";

interface Props {
Expand All @@ -11,6 +11,7 @@ interface Props {
errorFieldCodes: string[]
errorFieldCodePrefix: string
onCountryCodeChange: (countryCode: string) => void,
onRegionCodeChange: (regionCode: string) => void,
onTitleCodeChange: (titleCode: string) => void,
onFirstNameChange: (firstName: string) => void,
onLastNameChange: (lastName: string) => void,
Expand All @@ -23,6 +24,33 @@ interface Props {

export class AddressForm extends React.Component<Props, any> {

private renderRegions() {
let regions = this.getRegionsByCountryCode(this.props.address.countryCode)

if (regions.length > 0) {
return <InputDropdown testId={"address.region"}
values={regions}
fieldName={translationsStore.get("address.state")}
onChange={(regionCode) => this.props.onRegionCodeChange(regionCode)}
selectedValue={this.props.address.regionCode}
placeholderText={translationsStore.get("address.selectState")}
placeholderDisabled={true}
fieldErrorId={this.props.errorFieldCodePrefix + "regionIso"}
fieldErrorTextCode="address.regionIso.invalid"
fieldErrors={this.props.errorFieldCodes}/>
}

return <></>
}

private getRegionsByCountryCode(countryCode: string): CodeValueItem[] {
let region = this.props.addressConfig.regions.find((region) => region.countryCode === countryCode);
if (region) {
return region.regions
}
return []
}

render() {
return <>
<InputDropdown testId={"address.country"}
Expand Down Expand Up @@ -77,6 +105,7 @@ export class AddressForm extends React.Component<Props, any> {
fieldErrorId={this.props.errorFieldCodePrefix + "townCity"}
fieldErrorTextCode="address.townCity.invalid"
fieldErrors={this.props.errorFieldCodes}/>
{this.renderRegions()}
<InputText testId={"address.postcode"}
fieldName={translationsStore.get("address.postcode")}
onChange={(postCode) => this.props.onPostCodeChange(postCode)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface ComponentProps {
onSelectAddress: (address: AddressModel) => void

onCountryCodeChange: (countryCode: string) => void,
onRegionCodeChange: (regionCode: string) => void,
onTitleCodeChange: (titleCode: string) => void,
onFirstNameChange: (firstName: string) => void,
onLastNameChange: (lastName: string) => void,
Expand Down Expand Up @@ -99,6 +100,7 @@ class AddressSection extends React.Component<Props, State> {
<br/>
<AddressForm addressConfig={this.props.addressConfig}
onCountryCodeChange={(countryCode) => this.props.onCountryCodeChange(countryCode)}
onRegionCodeChange={(regionCode) => this.props.onRegionCodeChange(regionCode)}
address={this.props.address}
errorFieldCodes={this.props.errorFieldCodes}
errorFieldCodePrefix={this.props.errorFieldCodePrefix}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ interface DispatchProps {
setFirstName: (firstName: string) => void
setLastName: (lastName: string) => void
setCountryCode: (countryCode: string) => void
setRegionCode: (countryCode: string) => void
setTitleCode: (titleCode: string) => void
setLine1: (line1: string) => void
setLine2: (line2: string) => void
Expand Down Expand Up @@ -225,6 +226,7 @@ class Payment extends React.Component<Props, State> {
errorFieldCodes={this.state.errorFieldCodes}
errorFieldCodePrefix={"billingAddress."}
onCountryCodeChange={(countryCode) => this.props.setCountryCode(countryCode)}
onRegionCodeChange={(regionCode) => this.props.setRegionCode(regionCode)}
onTitleCodeChange={(titleCode) => this.props.setTitleCode(titleCode)}
onFirstNameChange={(firstName) => this.props.setFirstName(firstName)}
onLastNameChange={(lastName) => this.props.setLastName(lastName)}
Expand Down Expand Up @@ -304,6 +306,10 @@ function mapDispatchToProps(dispatch: StoreDispatch): DispatchProps {
type: "billingAddress/setCountryCode",
payload: country
}),
setRegionCode: (country: string) => dispatch({
type: "billingAddress/setRegionCode",
payload: country
}),
setTitleCode: (title: string) => dispatch({type: "billingAddress/setTitleCode", payload: title}),
setLine1: (line1: string) => dispatch({type: "billingAddress/setLine1", payload: line1}),
setLine2: (line2: string) => dispatch({type: "billingAddress/setLine2", payload: line2}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class AddressBookSelector extends React.Component<AddressBookSelectorProps, null
<br/>
{address.line1}&nbsp;{address.line2}
<br/>
{address.city}
{address.city}{isNotEmpty(address.region)? '\xa0' + address.region : ''}
<br/>
{address.country}&nbsp;{address.postalCode}
<br/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface DispatchProps {
setFirstName: (firstName: string) => void
setLastName: (lastName: string) => void
setCountryCode: (countryCode: string) => void
setRegionCode: (regionCode: string) => void
setTitleCode: (titleCode: string) => void
setLine1: (line1: string) => void
setLine2: (line2: string) => void
Expand Down Expand Up @@ -89,6 +90,7 @@ class ShippingAddress extends React.Component<ShippingAddressProps, ShippingAddr
errorFieldCodes={this.state.errorFieldCodes}
errorFieldCodePrefix=""
onCountryCodeChange={(countryCode) => this.props.setCountryCode(countryCode)}
onRegionCodeChange={(regionCode) => this.props.setRegionCode(regionCode)}
onTitleCodeChange={(titleCode) => this.props.setTitleCode(titleCode)}
onFirstNameChange={(firstName) => this.props.setFirstName(firstName)}
onLastNameChange={(lastName) => this.props.setLastName(lastName)}
Expand Down Expand Up @@ -118,6 +120,7 @@ const mapDispatchToProps = (dispatch: StoreDispatch): DispatchProps => ({
setFirstName: (firstName: string) => dispatch({type: "shippingAddress/setFirstName", payload: firstName}),
setLastName: (lastName: string) => dispatch({type: "shippingAddress/setLastName", payload: lastName}),
setCountryCode: (country: string) => dispatch({type: "shippingAddress/setCountryCode", payload: country}),
setRegionCode: (regionCode: string) => dispatch({type: "shippingAddress/setRegionCode", payload: regionCode}),
setTitleCode: (title: string) => dispatch({type: "shippingAddress/setTitleCode", payload: title}),
setLine1: (line1: string) => dispatch({type: "shippingAddress/setLine1", payload: line1}),
setLine2: (line2: string) => dispatch({type: "shippingAddress/setLine2", payload: line2}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export const translationKeys: string[] = [
"address.selectCountry",
"address.title.none",
"address.country",
"address.state",
"address.selectState",
"address.title",
"address.firstName",
"address.surname",
Expand Down Expand Up @@ -82,5 +84,6 @@ export const translationKeys: string[] = [
"address.line1.invalid",
"address.line2.invalid",
"address.townCity.invalid",
"address.postcode.invalid"
"address.postcode.invalid",
"address.regionIso.invalid"
]
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {PayloadAction, RootAction} from "./rootReducer";
import {CodeValueItem} from "./types";
import {CodeValueItem, RegionModel} from "./types";

export const addressConfigInitialState: AddressConfigModel = {
titles: [],
countries: [],
regions: [],
anonymousUser: false
}

Expand All @@ -28,6 +29,7 @@ export function addressConfigReducer(addressConfigState: AddressConfigModel, act
export interface AddressConfigModel {
titles: CodeValueItem[]
countries: CodeValueItem[]
regions: RegionModel[]
anonymousUser: boolean
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ export function billingAddressReducer(addressState: AddressModel, action: RootAc
case "billingAddress/setCountryCode":
return {
...addressState,
countryCode: action.payload
countryCode: action.payload,
regionCode: null
}

case "billingAddress/setRegionCode":
return {
...addressState,
regionCode: action.payload
}

case "billingAddress/setTitleCode":
Expand Down Expand Up @@ -76,6 +83,9 @@ interface SetBALastNameAction extends PayloadAction<"billingAddress/setLastName"
interface SetBACountryCodeAction extends PayloadAction<"billingAddress/setCountryCode"> {
}

interface SetBARegionCodeAction extends PayloadAction<"billingAddress/setRegionCode"> {
}

interface SetBATitleCodeAction extends PayloadAction<"billingAddress/setTitleCode"> {
}

Expand All @@ -102,6 +112,7 @@ export type BillingAddressAction =
SetBAFirstNameAction
| SetBALastNameAction
| SetBACountryCodeAction
| SetBARegionCodeAction
| SetBATitleCodeAction
| SetBALine1Action
| SetBALine2Action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export const addressInitialState: AddressModel = {
city: "",
country: "",
countryCode: "",
regionCode: null,
region: "",
lastName: "",
phoneNumber: "",
postalCode: "",
Expand All @@ -34,7 +36,14 @@ export function shippingAddressReducer(addressState: AddressModel, action: RootA
case "shippingAddress/setCountryCode":
return {
...addressState,
countryCode: action.payload
countryCode: action.payload,
regionCode: null
}

case "shippingAddress/setRegionCode":
return {
...addressState,
regionCode: action.payload
}

case "shippingAddress/setTitleCode":
Expand Down Expand Up @@ -91,6 +100,9 @@ interface SetSALastNameAction extends PayloadAction<"shippingAddress/setLastName
interface SetSACountryCodeAction extends PayloadAction<"shippingAddress/setCountryCode"> {
}

interface SetSARegionCodeAction extends PayloadAction<"shippingAddress/setRegionCode"> {
}

interface SetSATitleCodeAction extends PayloadAction<"shippingAddress/setTitleCode"> {
}

Expand All @@ -117,6 +129,7 @@ export type ShippingAddressAction =
SetSAFirstNameAction
| SetSALastNameAction
| SetSACountryCodeAction
| SetSARegionCodeAction
| SetSATitleCodeAction
| SetSALine1Action
| SetSALine2Action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export interface AddressModel {
id: string
country: string
countryCode: string
region: string
regionCode: string
title: string
titleCode: string
firstName: string
Expand All @@ -16,6 +18,11 @@ export interface AddressModel {
phoneNumber: string
}

export interface RegionModel {
countryCode: string
regions: CodeValueItem[]
}

export interface ShippingMethodState {
selectedShippingMethodCode: string,
shippingMethods: ShippingMethodModel[]
Expand Down
Loading
Loading