Show notice if merchant has legacy local pickup enabled alongside the new pickup (https://github.com/woocommerce/woocommerce-blocks/pull/7842)
* add notice when there are existing enabled legacy local pickups * Fix PHP warning * Link though to the settings page * Fix setting save * Enabling this will produce duplicate options at checkout. Co-authored-by: Mike Jolley <mike.jolley@me.com>
This commit is contained in:
parent
f2318060e1
commit
3c824053d7
|
@ -2,6 +2,7 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { createInterpolateElement, useState } from '@wordpress/element';
|
||||||
import { ADMIN_URL } from '@woocommerce/settings';
|
import { ADMIN_URL } from '@woocommerce/settings';
|
||||||
import { CHECKOUT_PAGE_ID } from '@woocommerce/block-settings';
|
import { CHECKOUT_PAGE_ID } from '@woocommerce/block-settings';
|
||||||
import {
|
import {
|
||||||
|
@ -9,8 +10,9 @@ import {
|
||||||
SelectControl,
|
SelectControl,
|
||||||
TextControl,
|
TextControl,
|
||||||
ExternalLink,
|
ExternalLink,
|
||||||
|
Notice,
|
||||||
} from '@wordpress/components';
|
} from '@wordpress/components';
|
||||||
import { useState } from '@wordpress/element';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -35,13 +37,39 @@ const GeneralSettingsDescription = () => (
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const StyledNotice = styled( Notice )`
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
`;
|
||||||
|
|
||||||
const GeneralSettings = () => {
|
const GeneralSettings = () => {
|
||||||
const { settings, setSettingField } = useSettingsContext();
|
const { settings, setSettingField, readOnlySettings } =
|
||||||
|
useSettingsContext();
|
||||||
const [ showCosts, setShowCosts ] = useState( !! settings.cost );
|
const [ showCosts, setShowCosts ] = useState( !! settings.cost );
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingsSection Description={ GeneralSettingsDescription }>
|
<SettingsSection Description={ GeneralSettingsDescription }>
|
||||||
<SettingsCard>
|
<SettingsCard>
|
||||||
|
{ readOnlySettings.hasLegacyPickup && (
|
||||||
|
<StyledNotice status="warning" isDismissible={ false }>
|
||||||
|
{ createInterpolateElement(
|
||||||
|
__(
|
||||||
|
'Enabling this will produce duplicate options at checkout. Remove the local pickup shipping method from your <a>shipping zones</a>.',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
),
|
||||||
|
{
|
||||||
|
a: (
|
||||||
|
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||||
|
<a
|
||||||
|
href={ `${ ADMIN_URL }admin.php?page=wc-settings&tab=shipping` }
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
) }
|
||||||
|
</StyledNotice>
|
||||||
|
) }
|
||||||
<CheckboxControl
|
<CheckboxControl
|
||||||
checked={ settings.enabled }
|
checked={ settings.enabled }
|
||||||
name="local_pickup_enabled"
|
name="local_pickup_enabled"
|
||||||
|
|
|
@ -25,11 +25,14 @@ import type {
|
||||||
import {
|
import {
|
||||||
defaultSettings,
|
defaultSettings,
|
||||||
getInitialSettings,
|
getInitialSettings,
|
||||||
|
defaultReadyOnlySettings,
|
||||||
|
readOnlySettings,
|
||||||
getInitialPickupLocations,
|
getInitialPickupLocations,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
const SettingsContext = createContext< SettingsContextType >( {
|
const SettingsContext = createContext< SettingsContextType >( {
|
||||||
settings: defaultSettings,
|
settings: defaultSettings,
|
||||||
|
readOnlySettings: defaultReadyOnlySettings,
|
||||||
setSettingField: () => () => void null,
|
setSettingField: () => () => void null,
|
||||||
pickupLocations: [],
|
pickupLocations: [],
|
||||||
setPickupLocations: () => void null,
|
setPickupLocations: () => void null,
|
||||||
|
@ -155,6 +158,7 @@ export const SettingsProvider = ( {
|
||||||
const settingsData = {
|
const settingsData = {
|
||||||
settings,
|
settings,
|
||||||
setSettingField,
|
setSettingField,
|
||||||
|
readOnlySettings,
|
||||||
pickupLocations,
|
pickupLocations,
|
||||||
setPickupLocations,
|
setPickupLocations,
|
||||||
toggleLocation,
|
toggleLocation,
|
||||||
|
|
|
@ -30,8 +30,13 @@ export type ShippingMethodSettings = {
|
||||||
cost: string;
|
cost: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ReadOnlySettings = {
|
||||||
|
hasLegacyPickup: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export type SettingsContextType = {
|
export type SettingsContextType = {
|
||||||
settings: ShippingMethodSettings;
|
settings: ShippingMethodSettings;
|
||||||
|
readOnlySettings: ReadOnlySettings;
|
||||||
setSettingField: (
|
setSettingField: (
|
||||||
field: keyof ShippingMethodSettings
|
field: keyof ShippingMethodSettings
|
||||||
) => ( value: unknown ) => void;
|
) => ( value: unknown ) => void;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { cleanForSlug } from '@wordpress/url';
|
import { cleanForSlug } from '@wordpress/url';
|
||||||
import { getSetting } from '@woocommerce/settings';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -25,20 +24,35 @@ export const indexLocationsById = (
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultSettings = {
|
export const defaultSettings = {
|
||||||
enabled: 'yes',
|
enabled: true,
|
||||||
title: '',
|
title: '',
|
||||||
tax_status: 'taxable',
|
tax_status: 'taxable',
|
||||||
cost: '',
|
cost: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const defaultReadyOnlySettings = {
|
||||||
|
hasLegacyPickup: false,
|
||||||
|
};
|
||||||
|
declare global {
|
||||||
|
const hydratedScreenSettings: {
|
||||||
|
pickupLocationSettings: {
|
||||||
|
enabled: string;
|
||||||
|
title: string;
|
||||||
|
tax_status: string;
|
||||||
|
cost: string;
|
||||||
|
};
|
||||||
|
pickupLocations: PickupLocation[];
|
||||||
|
readonlySettings: typeof defaultReadyOnlySettings;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const getInitialSettings = (): ShippingMethodSettings => {
|
export const getInitialSettings = (): ShippingMethodSettings => {
|
||||||
const settings = getSetting(
|
const settings = hydratedScreenSettings.pickupLocationSettings;
|
||||||
'pickupLocationSettings',
|
|
||||||
defaultSettings
|
|
||||||
) as typeof defaultSettings;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
enabled: settings?.enabled === 'yes',
|
enabled: settings?.enabled
|
||||||
|
? settings?.enabled === 'yes'
|
||||||
|
: defaultSettings.enabled,
|
||||||
title: settings?.title || defaultSettings.title,
|
title: settings?.title || defaultSettings.title,
|
||||||
tax_status: settings?.tax_status || defaultSettings.tax_status,
|
tax_status: settings?.tax_status || defaultSettings.tax_status,
|
||||||
cost: settings?.cost || defaultSettings.cost,
|
cost: settings?.cost || defaultSettings.cost,
|
||||||
|
@ -46,4 +60,7 @@ export const getInitialSettings = (): ShippingMethodSettings => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getInitialPickupLocations = (): SortablePickupLocation[] =>
|
export const getInitialPickupLocations = (): SortablePickupLocation[] =>
|
||||||
indexLocationsById( getSetting( 'pickupLocations', [] ) );
|
indexLocationsById( hydratedScreenSettings.pickupLocations || [] );
|
||||||
|
|
||||||
|
export const readOnlySettings =
|
||||||
|
hydratedScreenSettings.readonlySettings || defaultReadyOnlySettings;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { Card, CardBody } from '@wordpress/components';
|
import { Card, CardBody } from '@wordpress/components';
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
const StyledCard = styled( Card )`
|
const StyledCard = styled( Card )`
|
||||||
|
@ -9,6 +10,8 @@ const StyledCard = styled( Card )`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledCardBody = styled( CardBody )`
|
const StyledCardBody = styled( CardBody )`
|
||||||
|
padding: 24px;
|
||||||
|
|
||||||
// increasing the specificity of the styles to override the Gutenberg ones
|
// increasing the specificity of the styles to override the Gutenberg ones
|
||||||
&.is-size-medium.is-size-medium {
|
&.is-size-medium.is-size-medium {
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
|
@ -21,7 +24,7 @@ const StyledCardBody = styled( CardBody )`
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1.5em;
|
||||||
|
|
||||||
// fixing the spacing on the inputs and their help text, to ensure it is consistent
|
// fixing the spacing on the inputs and their help text, to ensure it is consistent
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
@ -52,7 +55,7 @@ const SettingsCard = ( {
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
children: ( JSX.Element | null )[];
|
children: ReactNode;
|
||||||
} ): JSX.Element => (
|
} ): JSX.Element => (
|
||||||
<StyledCard>
|
<StyledCard>
|
||||||
<StyledCardBody { ...props }>{ children }</StyledCardBody>
|
<StyledCardBody { ...props }>{ children }</StyledCardBody>
|
||||||
|
|
|
@ -40,29 +40,6 @@ class ShippingController {
|
||||||
* Initialization method.
|
* Initialization method.
|
||||||
*/
|
*/
|
||||||
public function init() {
|
public function init() {
|
||||||
// @todo This should be moved inline for the settings page only.
|
|
||||||
$this->asset_data_registry->add(
|
|
||||||
'pickupLocationSettings',
|
|
||||||
get_option( 'woocommerce_pickup_location_settings', [] ),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
$this->asset_data_registry->add(
|
|
||||||
'pickupLocations',
|
|
||||||
function() {
|
|
||||||
$locations = get_option( 'pickup_location_pickup_locations', [] );
|
|
||||||
$formatted = [];
|
|
||||||
foreach ( $locations as $location ) {
|
|
||||||
$formatted[] = [
|
|
||||||
'name' => $location['name'],
|
|
||||||
'address' => $location['address'],
|
|
||||||
'details' => $location['details'],
|
|
||||||
'enabled' => wc_string_to_bool( $location['enabled'] ),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return $formatted;
|
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
if ( is_admin() ) {
|
if ( is_admin() ) {
|
||||||
$this->asset_data_registry->add(
|
$this->asset_data_registry->add(
|
||||||
'countryStates',
|
'countryStates',
|
||||||
|
@ -74,6 +51,7 @@ class ShippingController {
|
||||||
}
|
}
|
||||||
add_action( 'rest_api_init', [ $this, 'register_settings' ] );
|
add_action( 'rest_api_init', [ $this, 'register_settings' ] );
|
||||||
add_action( 'admin_enqueue_scripts', [ $this, 'admin_scripts' ] );
|
add_action( 'admin_enqueue_scripts', [ $this, 'admin_scripts' ] );
|
||||||
|
add_action( 'admin_enqueue_scripts', [ $this, 'hydrate_client_settings' ] );
|
||||||
add_action( 'woocommerce_load_shipping_methods', array( $this, 'register_local_pickup' ) );
|
add_action( 'woocommerce_load_shipping_methods', array( $this, 'register_local_pickup' ) );
|
||||||
add_filter( 'woocommerce_local_pickup_methods', array( $this, 'register_local_pickup_method' ) );
|
add_filter( 'woocommerce_local_pickup_methods', array( $this, 'register_local_pickup_method' ) );
|
||||||
add_filter( 'woocommerce_customer_taxable_address', array( $this, 'filter_taxable_address' ) );
|
add_filter( 'woocommerce_customer_taxable_address', array( $this, 'filter_taxable_address' ) );
|
||||||
|
@ -170,6 +148,65 @@ class ShippingController {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hydrate client settings
|
||||||
|
*/
|
||||||
|
public function hydrate_client_settings() {
|
||||||
|
$locations = get_option( 'pickup_location_pickup_locations', [] );
|
||||||
|
|
||||||
|
$formatted_pickup_locations = [];
|
||||||
|
foreach ( $locations as $location ) {
|
||||||
|
$formatted_pickup_locations[] = [
|
||||||
|
'name' => $location['name'],
|
||||||
|
'address' => $location['address'],
|
||||||
|
'details' => $location['details'],
|
||||||
|
'enabled' => wc_string_to_bool( $location['enabled'] ),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$has_legacy_pickup = false;
|
||||||
|
|
||||||
|
// Get all shipping zones.
|
||||||
|
$shipping_zones = \WC_Shipping_Zones::get_zones( 'admin' );
|
||||||
|
$international_shipping_zone = new \WC_Shipping_Zone( 0 );
|
||||||
|
|
||||||
|
// Loop through each shipping zone.
|
||||||
|
foreach ( $shipping_zones as $shipping_zone ) {
|
||||||
|
// Get all registered rates for this shipping zone.
|
||||||
|
$shipping_methods = $shipping_zone['shipping_methods'];
|
||||||
|
// Loop through each registered rate.
|
||||||
|
foreach ( $shipping_methods as $shipping_method ) {
|
||||||
|
if ( 'local_pickup' === $shipping_method->id && 'yes' === $shipping_method->enabled ) {
|
||||||
|
$has_legacy_pickup = true;
|
||||||
|
break 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $international_shipping_zone->get_shipping_methods( true ) as $shipping_method ) {
|
||||||
|
if ( 'local_pickup' === $shipping_method->id ) {
|
||||||
|
$has_legacy_pickup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$settings = array(
|
||||||
|
'pickupLocationSettings' => get_option( 'woocommerce_pickup_location_settings', [] ),
|
||||||
|
'pickupLocations' => $formatted_pickup_locations,
|
||||||
|
'readonlySettings' => array(
|
||||||
|
'hasLegacyPickup' => $has_legacy_pickup,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_add_inline_script(
|
||||||
|
'wc-shipping-method-pickup-location',
|
||||||
|
sprintf(
|
||||||
|
'var hydratedScreenSettings = %s;',
|
||||||
|
wp_json_encode( $settings )
|
||||||
|
),
|
||||||
|
'before'
|
||||||
|
);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Load admin scripts.
|
* Load admin scripts.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue