add: stripe tax to onboarding tax task (#50989)
This commit is contained in:
parent
f359c20f84
commit
88806aae87
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: update
|
||||
|
||||
Add optional onclick to Plugins component
|
|
@ -19,6 +19,7 @@ type PluginsProps = {
|
|||
response: InstallPluginsResponse
|
||||
) => void;
|
||||
onError: ( errors: unknown, response: InstallPluginsResponse ) => void;
|
||||
onClick?: () => void;
|
||||
onSkip?: () => void;
|
||||
skipText?: string;
|
||||
autoInstall?: boolean;
|
||||
|
@ -37,6 +38,7 @@ export const Plugins = ( {
|
|||
onAbort,
|
||||
onComplete,
|
||||
onError = () => null,
|
||||
onClick = () => null,
|
||||
pluginSlugs = [ 'woocommerce-services' ],
|
||||
onSkip,
|
||||
installText = __( 'Install & enable', 'woocommerce' ),
|
||||
|
@ -159,6 +161,7 @@ export const Plugins = ( {
|
|||
}
|
||||
disabled={ isRequesting && hasBeenClicked }
|
||||
onClick={ () => {
|
||||
onClick();
|
||||
setHasBeenClicked( true );
|
||||
installAndActivate();
|
||||
} }
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: update
|
||||
|
||||
Add stripe tax status to task type
|
|
@ -29,8 +29,10 @@ export type TaskType = {
|
|||
badge?: string;
|
||||
additionalData?: {
|
||||
woocommerceTaxCountries?: string[];
|
||||
stripeTaxCountries?: string[];
|
||||
taxJarActivated?: boolean;
|
||||
avalaraActivated?: boolean;
|
||||
stripeTaxActivated?: boolean;
|
||||
woocommerceTaxActivated?: boolean;
|
||||
woocommerceShippingActivated?: boolean;
|
||||
};
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { getAdminLink } from '@woocommerce/settings';
|
||||
import interpolateComponents from '@automattic/interpolate-components';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { PartnerCard } from '../components/partner-card';
|
||||
import { TaxChildProps } from '../utils';
|
||||
import logo from './logo.png';
|
||||
|
||||
export const Card: React.FC< TaxChildProps > = ( { task } ) => {
|
||||
const { additionalData: { avalaraActivated } = {} } = task;
|
||||
|
||||
return (
|
||||
<PartnerCard
|
||||
name={ __( 'Avalara', 'woocommerce' ) }
|
||||
logo={ logo }
|
||||
description={ __( 'Powerful all-in-one tax tool', 'woocommerce' ) }
|
||||
benefits={ [
|
||||
__( 'Real-time sales tax calculation', 'woocommerce' ),
|
||||
interpolateComponents( {
|
||||
mixedString: __(
|
||||
'{{strong}}Multi{{/strong}}-economic nexus compliance',
|
||||
'woocommerce'
|
||||
),
|
||||
components: {
|
||||
strong: <strong />,
|
||||
},
|
||||
} ),
|
||||
__(
|
||||
'Cross-border and multi-channel compliance',
|
||||
'woocommerce'
|
||||
),
|
||||
__( 'Automate filing & remittance', 'woocommerce' ),
|
||||
__(
|
||||
'Return-ready, jurisdiction-level reporting.',
|
||||
'woocommerce'
|
||||
),
|
||||
] }
|
||||
terms={ '' }
|
||||
actionText={
|
||||
avalaraActivated
|
||||
? __( 'Continue setup', 'woocommerce' )
|
||||
: __( 'Download', 'woocommerce' )
|
||||
}
|
||||
onClick={ () => {
|
||||
recordEvent( 'tasklist_tax_select_option', {
|
||||
selected_option: 'avalara',
|
||||
} );
|
||||
|
||||
if ( avalaraActivated ) {
|
||||
window.location.href = getAdminLink(
|
||||
'/admin.php?page=wc-settings&tab=tax§ion=avatax'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
window.open(
|
||||
new URL(
|
||||
'https://woocommerce.com/products/woocommerce-avatax/'
|
||||
).toString(),
|
||||
'_blank'
|
||||
);
|
||||
} }
|
||||
/>
|
||||
);
|
||||
};
|
Binary file not shown.
Before Width: | Height: | Size: 3.9 KiB |
|
@ -41,7 +41,7 @@
|
|||
|
||||
.woocommerce-tax-partner-card__terms {
|
||||
color: $gray-600;
|
||||
font-size: 9px;
|
||||
font-size: 12px;
|
||||
margin-bottom: $gap-smaller;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@ export const PartnerCard: React.FC< {
|
|||
description: string;
|
||||
benefits: ( string | JSX.Element )[];
|
||||
terms: string | JSX.Element;
|
||||
actionText: string;
|
||||
children?: React.ReactNode;
|
||||
actionText?: string;
|
||||
onClick: () => void;
|
||||
isBusy?: boolean;
|
||||
} > = ( {
|
||||
|
@ -27,6 +28,7 @@ export const PartnerCard: React.FC< {
|
|||
actionText,
|
||||
onClick,
|
||||
isBusy,
|
||||
children,
|
||||
} ) => {
|
||||
return (
|
||||
<div className="woocommerce-tax-partner-card">
|
||||
|
@ -59,14 +61,18 @@ export const PartnerCard: React.FC< {
|
|||
<div className="woocommerce-tax-partner-card__terms">
|
||||
{ terms }
|
||||
</div>
|
||||
<Button
|
||||
isSecondary
|
||||
onClick={ onClick }
|
||||
isBusy={ isBusy }
|
||||
disabled={ isBusy }
|
||||
>
|
||||
{ actionText }
|
||||
</Button>
|
||||
{ children ? (
|
||||
children
|
||||
) : (
|
||||
<Button
|
||||
isSecondary
|
||||
onClick={ onClick }
|
||||
isBusy={ isBusy }
|
||||
disabled={ isBusy }
|
||||
>
|
||||
{ actionText }
|
||||
</Button>
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
useEffect,
|
||||
useState,
|
||||
createElement,
|
||||
useMemo,
|
||||
} from '@wordpress/element';
|
||||
import { WooOnboardingTask } from '@woocommerce/onboarding';
|
||||
|
||||
|
@ -25,6 +26,7 @@ import { WooOnboardingTask } from '@woocommerce/onboarding';
|
|||
*/
|
||||
import { redirectToTaxSettings } from './utils';
|
||||
import { Card as WooCommerceTaxCard } from './woocommerce-tax/card';
|
||||
import { Card as StripeTaxCard } from './stripe-tax/card';
|
||||
import { createNoticesFromResponse } from '../../../lib/notices';
|
||||
import { getCountryCode } from '~/dashboard/utils';
|
||||
import { ManualConfiguration } from './manual-configuration';
|
||||
|
@ -150,20 +152,21 @@ export const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
|
|||
} );
|
||||
}, [ updateOptions ] );
|
||||
|
||||
const getVisiblePartners = () => {
|
||||
const partners = useMemo( () => {
|
||||
const countryCode =
|
||||
getCountryCode( generalSettings?.woocommerce_default_country ) ||
|
||||
'';
|
||||
const {
|
||||
additionalData: {
|
||||
woocommerceTaxCountries = [],
|
||||
stripeTaxCountries = [],
|
||||
taxJarActivated,
|
||||
woocommerceTaxActivated,
|
||||
woocommerceShippingActivated,
|
||||
} = {},
|
||||
} = task;
|
||||
|
||||
const partners = [
|
||||
const allPartners = [
|
||||
{
|
||||
id: 'woocommerce-tax',
|
||||
card: WooCommerceTaxCard,
|
||||
|
@ -174,31 +177,35 @@ export const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
|
|||
! woocommerceShippingActivated &&
|
||||
woocommerceTaxCountries.includes( countryCode ),
|
||||
},
|
||||
{
|
||||
id: 'stripe-tax',
|
||||
card: StripeTaxCard,
|
||||
|
||||
isVisible: stripeTaxCountries.includes( countryCode ),
|
||||
},
|
||||
];
|
||||
|
||||
return partners.filter( ( partner ) => partner.isVisible );
|
||||
};
|
||||
|
||||
const partners = getVisiblePartners();
|
||||
return allPartners.filter( ( partner ) => partner.isVisible );
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- the partner list shouldn't be changing in the middle of interaction. for some reason the country is becoming null in a re-render and causing unexpected behaviour
|
||||
}, [] );
|
||||
|
||||
const { auto } = query;
|
||||
useEffect( () => {
|
||||
const { auto } = query;
|
||||
|
||||
if ( auto === 'true' ) {
|
||||
onAutomate();
|
||||
return;
|
||||
}
|
||||
}, [ auto, onAutomate ] );
|
||||
|
||||
useEffect( () => {
|
||||
if ( query.partner ) {
|
||||
return;
|
||||
}
|
||||
|
||||
recordEvent( 'tasklist_tax_view_options', {
|
||||
options: partners.map( ( partner ) => partner.id ),
|
||||
} );
|
||||
}, [ onAutomate, partners, query ] );
|
||||
}, [ partners, query.partner ] );
|
||||
|
||||
const getCurrentPartner = () => {
|
||||
const currentPartner = useMemo( () => {
|
||||
if ( ! query.partner ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -206,7 +213,7 @@ export const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
|
|||
return (
|
||||
partners.find( ( partner ) => partner.id === query.partner ) || null
|
||||
);
|
||||
};
|
||||
}, [ partners, query.partner ] );
|
||||
|
||||
const childProps = {
|
||||
isPending,
|
||||
|
@ -220,8 +227,6 @@ export const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
|
|||
return <Spinner />;
|
||||
}
|
||||
|
||||
const currentPartner = getCurrentPartner();
|
||||
|
||||
if ( ! partners.length ) {
|
||||
return (
|
||||
<TaskCard>
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { getAdminLink } from '@woocommerce/settings';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { Plugins } from '@woocommerce/components';
|
||||
import { dispatch, useDispatch } from '@wordpress/data';
|
||||
import { SETTINGS_STORE_NAME } from '@woocommerce/data';
|
||||
import { Button } from '@wordpress/components';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { PartnerCard } from '../components/partner-card';
|
||||
import { TaxChildProps } from '../utils';
|
||||
import StripeTaxLogo from './stripe-tax-logo.svg';
|
||||
import { createNoticesFromResponse } from '~/lib/notices';
|
||||
|
||||
const STRIPE_TAX_PLUGIN_SLUG = 'stripe-tax-for-woocommerce';
|
||||
|
||||
const redirectToStripeTaxSettings = () => {
|
||||
window.location.href = getAdminLink(
|
||||
'/admin.php?page=wc-settings&tab=stripe_tax_for_woocommerce'
|
||||
);
|
||||
};
|
||||
|
||||
export const Card: React.FC< TaxChildProps > = ( {
|
||||
task: {
|
||||
additionalData: { stripeTaxActivated } = {
|
||||
stripeTaxActivated: false,
|
||||
},
|
||||
},
|
||||
} ) => {
|
||||
const { createSuccessNotice } = useDispatch( 'core/notices' );
|
||||
|
||||
return (
|
||||
<PartnerCard
|
||||
name={ __( 'Stripe Tax', 'woocommerce' ) }
|
||||
logo={ StripeTaxLogo }
|
||||
description={ __( 'Powerful global tax tool', 'woocommerce' ) }
|
||||
benefits={ [
|
||||
__( 'Real-time sales tax calculation', 'woocommerce' ),
|
||||
__( 'Multi-economic nexus compliance', 'woocommerce' ),
|
||||
__( 'Detailed tax transaction reports', 'woocommerce' ),
|
||||
__( 'Coverage in over 55 countries', 'woocommerce' ),
|
||||
] }
|
||||
terms={ __(
|
||||
'Free to install, then pay as you go.',
|
||||
'woocommerce'
|
||||
) }
|
||||
onClick={ () => {} }
|
||||
>
|
||||
{ stripeTaxActivated ? (
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={ () => {
|
||||
recordEvent(
|
||||
'tasklist_tax_setup_stripe_tax_to_settings'
|
||||
);
|
||||
redirectToStripeTaxSettings();
|
||||
} }
|
||||
>
|
||||
{ __( 'Continue to setttings', 'woocommerce' ) }
|
||||
</Button>
|
||||
) : (
|
||||
<Plugins
|
||||
installText={ __( 'Install for free', 'woocommerce' ) }
|
||||
onClick={ () => {
|
||||
recordEvent( 'tasklist_tax_select_option', {
|
||||
selected_option: STRIPE_TAX_PLUGIN_SLUG,
|
||||
} );
|
||||
} }
|
||||
onComplete={ () => {
|
||||
recordEvent( 'tasklist_tax_install_plugin_success', {
|
||||
selected_option: STRIPE_TAX_PLUGIN_SLUG,
|
||||
} );
|
||||
const { updateAndPersistSettingsForGroup } =
|
||||
dispatch( SETTINGS_STORE_NAME );
|
||||
updateAndPersistSettingsForGroup( 'general', {
|
||||
general: {
|
||||
woocommerce_calc_taxes: 'yes', // Stripe tax requires tax calculation to be enabled so let's do it here to save the user from doing it manually
|
||||
},
|
||||
} ).then( () => {
|
||||
createSuccessNotice(
|
||||
__(
|
||||
"Stripe Tax for Woocommerce has been successfully installed. Let's configure it now.",
|
||||
'woocommerce'
|
||||
)
|
||||
);
|
||||
redirectToStripeTaxSettings();
|
||||
} );
|
||||
} }
|
||||
onError={ ( errors, response ) => {
|
||||
recordEvent( 'tasklist_tax_install_plugin_error', {
|
||||
selected_option: STRIPE_TAX_PLUGIN_SLUG,
|
||||
errors,
|
||||
} );
|
||||
createNoticesFromResponse( response );
|
||||
} }
|
||||
installButtonVariant="secondary"
|
||||
pluginSlugs={ [ STRIPE_TAX_PLUGIN_SLUG ] }
|
||||
/>
|
||||
) }
|
||||
</PartnerCard>
|
||||
);
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 468 222.5" style="enable-background:new 0 0 468 222.5" xml:space="preserve"><style>.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#0a2540}</style><path class="st0" d="M414 113.4c0-25.6-12.4-45.8-36.1-45.8-23.8 0-38.2 20.2-38.2 45.6 0 30.1 17 45.3 41.4 45.3 11.9 0 20.9-2.7 27.7-6.5v-20c-6.8 3.4-14.6 5.5-24.5 5.5-9.7 0-18.3-3.4-19.4-15.2h48.9c0-1.3.2-6.5.2-8.9zm-49.4-9.5c0-11.3 6.9-16 13.2-16 6.1 0 12.6 4.7 12.6 16h-25.8zM301.1 67.6c-9.8 0-16.1 4.6-19.6 7.8l-1.3-6.2h-22v116.6l25-5.3.1-28.3c3.6 2.6 8.9 6.3 17.7 6.3 17.9 0 34.2-14.4 34.2-46.1-.1-29-16.6-44.8-34.1-44.8zm-6 68.9c-5.9 0-9.4-2.1-11.8-4.7l-.1-37.1c2.6-2.9 6.2-4.9 11.9-4.9 9.1 0 15.4 10.2 15.4 23.3 0 13.4-6.2 23.4-15.4 23.4zM223.8 61.7l25.1-5.4V36l-25.1 5.3zM223.8 69.3h25.1v87.5h-25.1zM196.9 76.7l-1.6-7.4h-21.6v87.5h25V97.5c5.9-7.7 15.9-6.3 19-5.2v-23c-3.2-1.2-14.9-3.4-20.8 7.4zM146.9 47.6l-24.4 5.2-.1 80.1c0 14.8 11.1 25.7 25.9 25.7 8.2 0 14.2-1.5 17.5-3.3V135c-3.2 1.3-19 5.9-19-8.9V90.6h19V69.3h-19l.1-21.7zM79.3 94.7c0-3.9 3.2-5.4 8.5-5.4 7.6 0 17.2 2.3 24.8 6.4V72.2c-8.3-3.3-16.5-4.6-24.8-4.6C67.5 67.6 54 78.2 54 95.9c0 27.6 38 23.2 38 35.1 0 4.6-4 6.1-9.6 6.1-8.3 0-18.9-3.4-27.3-8v23.8c9.3 4 18.7 5.7 27.3 5.7 20.8 0 35.1-10.3 35.1-28.2-.1-29.8-38.2-24.5-38.2-35.7z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: update
|
||||
|
||||
Added Stripe tax in onboarding tax task
|
|
@ -129,9 +129,11 @@ class Tax extends Task {
|
|||
return array(
|
||||
'avalara_activated' => PluginsHelper::is_plugin_active( 'woocommerce-avatax' ),
|
||||
'tax_jar_activated' => class_exists( 'WC_Taxjar' ),
|
||||
'stripe_tax_activated' => PluginsHelper::is_plugin_active( 'stripe-tax-for-woocommerce' ),
|
||||
'woocommerce_tax_activated' => PluginsHelper::is_plugin_active( 'woocommerce-tax' ),
|
||||
'woocommerce_shipping_activated' => PluginsHelper::is_plugin_active( 'woocommerce-shipping' ),
|
||||
'woocommerce_tax_countries' => self::get_automated_support_countries(),
|
||||
'stripe_tax_countries' => self::get_stripe_tax_support_countries(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -162,4 +164,54 @@ class Tax extends Task {
|
|||
|
||||
return $tax_supported_countries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of countries that support Stripe tax.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function get_stripe_tax_support_countries() {
|
||||
// https://docs.stripe.com/tax/supported-countries#supported-countries accurate as of 2024-08-26.
|
||||
// countries with remote sales not included.
|
||||
return array(
|
||||
'AU',
|
||||
'AT',
|
||||
'BE',
|
||||
'BG',
|
||||
'CA',
|
||||
'HR',
|
||||
'CY',
|
||||
'CZ',
|
||||
'DK',
|
||||
'EE',
|
||||
'FI',
|
||||
'FR',
|
||||
'DE',
|
||||
'GR',
|
||||
'HK',
|
||||
'HU',
|
||||
'IE',
|
||||
'IT',
|
||||
'JP',
|
||||
'LV',
|
||||
'LT',
|
||||
'LU',
|
||||
'MT',
|
||||
'NL',
|
||||
'NZ',
|
||||
'NO',
|
||||
'PL',
|
||||
'PT',
|
||||
'RO',
|
||||
'SG',
|
||||
'SK',
|
||||
'SI',
|
||||
'ES',
|
||||
'SE',
|
||||
'CH',
|
||||
'AE',
|
||||
'GB',
|
||||
'US',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue