woocommerce/plugins/woocommerce-admin/client/task-lists/fills/tax/index.tsx

271 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { Card, CardBody, Spinner } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { getAdminLink } from '@woocommerce/settings';
import {
OPTIONS_STORE_NAME,
SETTINGS_STORE_NAME,
TaskType,
} from '@woocommerce/data';
import { queueRecordEvent, recordEvent } from '@woocommerce/tracks';
import { registerPlugin } from '@wordpress/plugins';
import {
useCallback,
useEffect,
useState,
createElement,
useMemo,
} from '@wordpress/element';
import { WooOnboardingTask } from '@woocommerce/onboarding';
/**
* Internal dependencies
*/
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';
import { Partners } from './components/partners';
import { WooCommerceTax } from './woocommerce-tax';
const TaskCard: React.FC = ( { children } ) => {
return (
<Card className="woocommerce-task-card">
<CardBody>{ children }</CardBody>
</Card>
);
};
export type TaxProps = {
onComplete: () => void;
query: Record< string, string >;
task: TaskType;
};
export const Tax: React.FC< TaxProps > = ( { onComplete, query, task } ) => {
const [ isPending, setIsPending ] = useState( false );
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
const { createNotice } = useDispatch( 'core/notices' );
const { updateAndPersistSettingsForGroup } =
useDispatch( SETTINGS_STORE_NAME );
const { generalSettings, isResolving, taxSettings } = useSelect(
( select ) => {
const { getSettings, hasFinishedResolution } =
select( SETTINGS_STORE_NAME );
return {
generalSettings: getSettings( 'general' ).general,
isResolving: ! hasFinishedResolution( 'getSettings', [
'general',
] ),
taxSettings: getSettings( 'tax' ).tax || {},
};
}
);
const onManual = useCallback( async () => {
setIsPending( true );
if ( generalSettings?.woocommerce_calc_taxes !== 'yes' ) {
updateAndPersistSettingsForGroup( 'tax', {
tax: {
...taxSettings,
wc_connect_taxes_enabled: 'no',
},
} );
updateAndPersistSettingsForGroup( 'general', {
general: {
...generalSettings,
woocommerce_calc_taxes: 'yes',
},
} )
.then( () => redirectToTaxSettings() )
.catch( ( error: unknown ) => {
setIsPending( false );
createNoticesFromResponse( error );
} );
} else {
redirectToTaxSettings();
}
}, [ generalSettings, taxSettings, updateAndPersistSettingsForGroup ] );
const onAutomate = useCallback( async () => {
setIsPending( true );
try {
await Promise.all( [
updateAndPersistSettingsForGroup( 'tax', {
tax: {
...taxSettings,
wc_connect_taxes_enabled: 'yes',
},
} ),
updateAndPersistSettingsForGroup( 'general', {
general: {
...generalSettings,
woocommerce_calc_taxes: 'yes',
},
} ),
] );
} catch ( error: unknown ) {
setIsPending( false );
createNotice(
'error',
__(
'There was a problem setting up automated taxes. Please try again.',
'woocommerce'
)
);
return;
}
createNotice(
'success',
__(
'Youre awesome! One less item on your to-do list ✅',
'woocommerce'
)
);
onComplete();
}, [
createNotice,
generalSettings,
onComplete,
taxSettings,
updateAndPersistSettingsForGroup,
] );
const onDisable = useCallback( () => {
setIsPending( true );
queueRecordEvent( 'tasklist_tax_connect_store', {
connect: false,
no_tax: true,
} );
updateOptions( {
woocommerce_no_sales_tax: true,
woocommerce_calc_taxes: 'no',
} ).then( () => {
window.location.href = getAdminLink( 'admin.php?page=wc-admin' );
} );
}, [ updateOptions ] );
const partners = useMemo( () => {
const countryCode =
getCountryCode( generalSettings?.woocommerce_default_country ) ||
'';
const {
additionalData: {
woocommerceTaxCountries = [],
stripeTaxCountries = [],
taxJarActivated,
woocommerceTaxActivated,
woocommerceShippingActivated,
} = {},
} = task;
const allPartners = [
{
id: 'woocommerce-tax',
card: WooCommerceTaxCard,
component: WooCommerceTax,
isVisible:
! taxJarActivated && // WCS integration doesn't work with the official TaxJar plugin.
! woocommerceTaxActivated &&
! woocommerceShippingActivated &&
woocommerceTaxCountries.includes( countryCode ),
},
{
id: 'stripe-tax',
card: StripeTaxCard,
isVisible: stripeTaxCountries.includes( countryCode ),
},
];
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( () => {
if ( auto === 'true' ) {
onAutomate();
}
}, [ auto, onAutomate ] );
useEffect( () => {
if ( query.partner ) {
return;
}
recordEvent( 'tasklist_tax_view_options', {
options: partners.map( ( partner ) => partner.id ),
} );
}, [ partners, query.partner ] );
const currentPartner = useMemo( () => {
if ( ! query.partner ) {
return null;
}
return (
partners.find( ( partner ) => partner.id === query.partner ) || null
);
}, [ partners, query.partner ] );
const childProps = {
isPending,
onAutomate,
onManual,
onDisable,
task,
};
if ( isResolving ) {
return <Spinner />;
}
if ( ! partners.length ) {
return (
<TaskCard>
<ManualConfiguration { ...childProps } />
</TaskCard>
);
}
if ( currentPartner ) {
return (
<TaskCard>
{ currentPartner.component &&
createElement( currentPartner.component, childProps ) }
</TaskCard>
);
}
return (
<Partners { ...childProps }>
{ partners.map(
( partner ) =>
partner.card &&
createElement( partner.card, {
key: partner.id,
...childProps,
} )
) }
</Partners>
);
};
registerPlugin( 'wc-admin-onboarding-task-tax', {
// @ts-expect-error @types/wordpress__plugins need to be updated
scope: 'woocommerce-tasks',
render: () => (
<WooOnboardingTask id="tax">
{ ( { onComplete, query, task }: TaxProps ) => (
<Tax onComplete={ onComplete } query={ query } task={ task } />
) }
</WooOnboardingTask>
),
} );