diff --git a/docs/reference/Translations/index.md b/docs/reference/Translations/index.md index 6de1bb77b..8c39f7d54 100644 --- a/docs/reference/Translations/index.md +++ b/docs/reference/Translations/index.md @@ -1249,6 +1249,9 @@ Translation keys for the `Contractor.Address` i18n namespace. | `validations.street1` | `"Street address is required"` | | `validations.zip` | `"Please provide valid zip code"` | | `validations.zipInvalid` | `"Please enter a valid ZIP code"` | +| `w9EditWarning` | | +| `w9EditWarning.body` | `"This contractor has already signed a form W-9. If you are making corrections, you’re also required to update and retain a new signed version of Form W-9 reflecting the corrected information."` | +| `w9EditWarning.label` | `"Changes will require an updated Form W-9"` | | `zip` | `"Zip"` | *** @@ -1697,8 +1700,8 @@ Translation keys for the `Contractor.Profile` i18n namespace. | `buttons.cancel` | `"Cancel"` | | `buttons.create` | `"Create Contractor"` | | `buttons.creating` | `"Creating…"` | -| `buttons.update` | `"Update Contractor"` | -| `buttons.updating` | `"Updating…"` | +| `buttons.update` | `"Continue"` | +| `buttons.updating` | `"Saving…"` | | `fields` | | | `fields.businessName` | | | `fields.businessName.label` | `"Business Name"` | @@ -1748,6 +1751,9 @@ Translation keys for the `Contractor.Profile` i18n namespace. | `validations.ssn` | `"SSN is required for individual contractors"` | | `validations.ssnFormat` | `"SSN must be valid format"` | | `validations.startDate` | `"Start date is required"` | +| `w9EditWarning` | | +| `w9EditWarning.body` | `"This contractor has already signed a form W-9. If you are making corrections, you’re also required to update and retain a new signed version of Form W-9 reflecting the corrected information."` | +| `w9EditWarning.label` | `"Changes will require an updated Form W-9"` | *** diff --git a/e2e/tests/contractor/03-onboarding-edit.spec.ts b/e2e/tests/contractor/03-onboarding-edit.spec.ts index 6f6f0fd91..a6f823fda 100644 --- a/e2e/tests/contractor/03-onboarding-edit.spec.ts +++ b/e2e/tests/contractor/03-onboarding-edit.spec.ts @@ -45,6 +45,6 @@ test.describe('ContractorOnboardingFlow - edit re-entry from list lifecycle', () await expect(page.getByRole('radio', { name: /^business$/i })).toBeChecked() await expect(page.getByLabel(/business name/i)).toHaveValue(/Acme Consulting/i) - await expect(page.getByRole('button', { name: /update contractor/i })).toBeVisible() + await expect(page.getByRole('button', { name: /^continue$/i })).toBeVisible() }) }) diff --git a/src/components/Contractor/Address/Address.test.tsx b/src/components/Contractor/Address/Address.test.tsx index 445b2af32..d23ce555c 100644 --- a/src/components/Contractor/Address/Address.test.tsx +++ b/src/components/Contractor/Address/Address.test.tsx @@ -9,6 +9,10 @@ import { handleGetContractorAddress, handleUpdateContractorAddress, } from '@/test/mocks/apis/contractor_address' +import { + buildContractorDocumentsList, + handleGetContractorDocuments, +} from '@/test/mocks/apis/contractor_documents' import { setupApiTestMocks } from '@/test/mocks/apiServer' import { contractorEvents } from '@/shared/constants' import { renderWithProviders } from '@/test-utils/renderWithProviders' @@ -431,4 +435,42 @@ describe('Contractor/Address', () => { ).toBeInTheDocument() }) }) + + describe('W-9 edit warning', () => { + beforeEach(() => { + setupApiTestMocks() + server.use(handleGetContractorAddress(() => HttpResponse.json(emptyAddressResponse))) + }) + + it('renders the warning when the contractor has a signed W-9 on file', async () => { + server.use( + handleGetContractorDocuments(() => + HttpResponse.json( + buildContractorDocumentsList([ + { + uuid: 'signed-w9-uuid', + title: 'W-9', + name: 'taxpayer_identification_form_w_9', + requires_signing: true, + signed_at: '2025-01-01T00:00:00Z', + }, + ]), + ), + ), + ) + + renderWithProviders(
{}} />) + + expect( + await screen.findByText('Changes will require an updated Form W-9'), + ).toBeInTheDocument() + }) + + it('does not render the warning when the W-9 is unsigned', async () => { + renderWithProviders( {}} />) + + await screen.findByText('Home address') + expect(screen.queryByText('Changes will require an updated Form W-9')).not.toBeInTheDocument() + }) + }) }) diff --git a/src/components/Contractor/Address/Address.tsx b/src/components/Contractor/Address/Address.tsx index baf54795d..1472061c2 100644 --- a/src/components/Contractor/Address/Address.tsx +++ b/src/components/Contractor/Address/Address.tsx @@ -15,6 +15,7 @@ import { useI18n, useComponentDictionary } from '@/i18n' import type { ResourceDictionary } from '@/types/Helpers' import { contractorEvents, type EventType } from '@/shared/constants' import type { OnEventType } from '@/components/Base/useBase' +import { useContractorHasSignedW9 } from '@/components/Contractor/shared/useContractorHasSignedW9' // The hook defaults to the API contract, which treats every address field as // optional. The SDK's address form has always required a complete mailing @@ -78,6 +79,18 @@ export function Address({ onEvent, FallbackComponent, ...rootProps }: AddressPro ) } +function ContractorAddressW9Warning({ contractorId }: { contractorId: string }) { + const hasSignedW9 = useContractorHasSignedW9(contractorId) + const { t } = useTranslation('Contractor.Address') + const Components = useComponentContext() + if (!hasSignedW9) return null + return ( +