From c42d9b8c0677473ddb63cae718e335ef2a9b790f Mon Sep 17 00:00:00 2001 From: Niko Pitkonen <78962935+pitkni@users.noreply.github.com> Date: Mon, 25 Sep 2023 08:31:48 +0300 Subject: [PATCH] HAI-1586 Change hanke contact data model (#370) Change hanke contact data model - Split sub contact name to first name and last name. - Remove address information from contacts. - sub contact phone is now mandatory. - Sub contact form should be always visible (if contact is) - You can add many sub contacts. Additional: the ticket does not mention this but ytunnusTaiHetu was changed to just ytunnus. It is visible if contact is not a person. Note: This commit does not fix / change everything that needs to be changed in yhteystieto page. For example, the styling of the page does not figma, but that task is not part of this task. --- cypress/integration/E2E.spec.ts | 2 +- public/mockServiceWorker.js | 6 +- .../components/PreFilledContactSelect.tsx | 6 +- src/domain/forms/components/Contact.tsx | 10 +- src/domain/hanke/edit/HankeForm.test.tsx | 68 ++--- .../hanke/edit/HankeFormYhteystiedot.tsx | 236 +++++++++--------- .../hanke/edit/components/ContactsSummary.tsx | 19 +- src/domain/hanke/edit/hankeSchema.ts | 46 ++-- src/domain/hanke/edit/types.ts | 13 +- src/domain/hanke/hankeView/HankeView.test.tsx | 6 +- src/domain/johtoselvitys/Contacts.test.tsx | 4 +- src/domain/mocks/data/hankkeet-data.ts | 61 ++--- src/domain/types/hanke.ts | 15 +- src/locales/en.json | 3 +- src/locales/fi.json | 3 +- src/locales/sv.json | 3 +- 16 files changed, 255 insertions(+), 246 deletions(-) diff --git a/cypress/integration/E2E.spec.ts b/cypress/integration/E2E.spec.ts index ce16eb681..64af0f89c 100644 --- a/cypress/integration/E2E.spec.ts +++ b/cypress/integration/E2E.spec.ts @@ -76,7 +76,7 @@ const hankeMock: HankeDataDraft = { email: 'harri.hanketest@hankekatu.foo', puhelinnumero: '12341234', tyyppi: 'YKSITYISHENKILO', - ytunnusTaiHetu: 'tunnus', + ytunnus: 'tunnus', }, ], }; diff --git a/public/mockServiceWorker.js b/public/mockServiceWorker.js index 8b1525b56..799b96754 100644 --- a/public/mockServiceWorker.js +++ b/public/mockServiceWorker.js @@ -120,7 +120,7 @@ self.addEventListener('fetch', function (event) { console.warn( '[MSW] Successfully emulated a network error for the "%s %s" request.', request.method, - request.url + request.url, ); return; } @@ -131,9 +131,9 @@ self.addEventListener('fetch', function (event) { [MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`, request.method, request.url, - `${error.name}: ${error.message}` + `${error.name}: ${error.message}`, ); - }) + }), ); }); diff --git a/src/domain/application/components/PreFilledContactSelect.tsx b/src/domain/application/components/PreFilledContactSelect.tsx index 5779a4d53..f472cd627 100644 --- a/src/domain/application/components/PreFilledContactSelect.tsx +++ b/src/domain/application/components/PreFilledContactSelect.tsx @@ -24,7 +24,9 @@ const PreFilledContactSelect: React.FC<{ const preFilledContactOptions: PreFilledContactOption[] = allHankeContacts.flatMap( (hankeContacts) => - hankeContacts ? hankeContacts.map((contact) => ({ label: contact.nimi, value: contact })) : [] + hankeContacts + ? hankeContacts.map((contact) => ({ label: contact.nimi, value: contact })) + : [], ); function handlePreFilledContactChange(option: PreFilledContactOption | undefined) { @@ -43,7 +45,7 @@ const PreFilledContactSelect: React.FC<{ country: 'FI', email: value.email, phone: value.puhelinnumero || '', - registryKey: (isHankeContact(value) && value.ytunnusTaiHetu) || null, + registryKey: (isHankeContact(value) && value.ytunnus) || null, ovt: null, invoicingOperator: null, sapCustomerNumber: null, diff --git a/src/domain/forms/components/Contact.tsx b/src/domain/forms/components/Contact.tsx index d8e209185..17df218fc 100644 --- a/src/domain/forms/components/Contact.tsx +++ b/src/domain/forms/components/Contact.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { Flex } from '@chakra-ui/react'; import { Button, IconCross, IconPlusCircle, Tab, TabList, TabPanel, Tabs } from 'hds-react'; import { useTranslation } from 'react-i18next'; @@ -11,6 +11,7 @@ interface Props { index?: number; onRemoveContact?: UseFieldArrayRemove; renderSubContact?: (subContactIndex: number, remove: UseFieldArrayRemove) => JSX.Element; + showInitialEmpty?: boolean; subContactPath: string; emptySubContact: unknown; children: React.ReactNode; @@ -21,6 +22,7 @@ const Contact = ({ index, onRemoveContact, renderSubContact, + showInitialEmpty = false, subContactPath, emptySubContact, children, @@ -39,6 +41,12 @@ const Contact = ({ appendSubContact(emptySubContact); } + useEffect(() => { + if (subContactFields.length === 0 && showInitialEmpty) { + addSubContact(); + } + }, [subContactFields, showInitialEmpty]); + const renderSubContacts = subContactFields.length > 0 && renderSubContact; const { tabRefs } = useSelectableTabs(subContactFields.length, { selectLastTabOnChange: true }); diff --git a/src/domain/hanke/edit/HankeForm.test.tsx b/src/domain/hanke/edit/HankeForm.test.tsx index 043c6b758..77bf5b64e 100644 --- a/src/domain/hanke/edit/HankeForm.test.tsx +++ b/src/domain/hanke/edit/HankeForm.test.tsx @@ -122,58 +122,60 @@ describe('HankeForm', () => { test('Yhteystiedot can be filled', async () => { const { user } = await setupYhteystiedotPage(); + // Hanke owner await user.click(screen.getByRole('button', { name: /tyyppi/i })); await user.click(screen.getByText(/yritys/i)); - fireEvent.change(screen.getByLabelText(/nimi/i), { - target: { value: 'Olli Omistaja' }, + + fireEvent.change(screen.getByTestId('omistajat.0.nimi'), { + target: { value: 'Omistaja Yritys' }, }); - fireEvent.change(screen.getByLabelText(/y-tunnus tai henkilötunnus/i), { + fireEvent.change(screen.getByLabelText(/y-tunnus/i), { target: { value: 'y-tunnus' }, }); - fireEvent.change(screen.getByLabelText(/katuosoite/i), { - target: { value: 'Testikuja 1' }, - }); - fireEvent.change(screen.getByLabelText(/postinumero/i), { - target: { value: '00000' }, - }); - fireEvent.change(screen.getByLabelText(/postitoimipaikka/i), { - target: { value: 'Testikaupunki' }, - }); - fireEvent.change(screen.getByLabelText(/sähköposti/i), { + fireEvent.change(screen.getByTestId('omistajat.0.email'), { target: { value: 'test@mail.com' }, }); - fireEvent.change(screen.getByLabelText(/puhelinnumero/i), { - target: { value: '0400000000' }, + fireEvent.change(screen.getByTestId('omistajat.0.puhelinnumero'), { + target: { value: '0401234567' }, }); - expect(screen.queryByRole('group', { name: 'Yhteyshenkilö' })).not.toBeInTheDocument(); - await user.click(screen.getByLabelText(/erillinen yhteyshenkilö/i)); - expect(screen.getByRole('group', { name: 'Yhteyshenkilö' })).toBeInTheDocument(); - - fireEvent.change(screen.getAllByLabelText(/nimi/i)[1], { - target: { value: 'Testi Yhteyshenkilö' }, + // Hanke owner contact person + fireEvent.change(screen.getByTestId('omistajat.0.alikontaktit.0.etunimi'), { + target: { value: 'Olli' }, + }); + fireEvent.change(screen.getByTestId('omistajat.0.alikontaktit.0.sukunimi'), { + target: { value: 'Omistaja' }, + }); + fireEvent.change(screen.getByTestId('omistajat.0.alikontaktit.0.email'), { + target: { value: 'foo@bar.com' }, }); - fireEvent.change(screen.getAllByLabelText(/sähköposti/i)[1], { - target: { value: 'yhteyshenkilo@mail.com' }, + fireEvent.change(screen.getByTestId('omistajat.0.alikontaktit.0.puhelinnumero'), { + target: { value: '0507654321' }, }); - await user.click(screen.getByText(/Rakennuttajan tiedot/i)); + // Rakennuttaja + await user.click(screen.getByText(/rakennuttajan tiedot/i)); await user.click(screen.getByText(/lisää rakennuttaja/i)); expect(screen.getAllByText('Rakennuttaja')).toHaveLength(1); - await user.click(screen.getByText(/lisää yhteyshenkilö/i)); - await user.click(screen.getByText(/lisää yhteyshenkilö/i)); - expect(screen.getByRole('tablist').childElementCount).toBe(2); + await user.click(screen.getAllByRole('button', { name: /tyyppi/i })[1]); + await user.click(screen.getByText(/yksityishenkilö/i)); + expect(screen.getAllByLabelText(/y-tunnus/i)[1]).toBeDisabled(); + + await user.click(screen.getAllByText(/lisää yhteyshenkilö/i)[1]); + await user.click(screen.getAllByText(/lisää yhteyshenkilö/i)[1]); + expect(screen.getAllByRole('tablist')[1].childElementCount).toBe(2); // many contacts can be added + + await user.click(screen.getByText(/poista yhteyshenkilö/i)); + expect(screen.queryByText(/poista yhteyshenkilö/i)).not.toBeInTheDocument(); // cannot remove last one await user.click(screen.getByText(/lisää rakennuttaja/i)); expect(screen.getAllByText('Rakennuttaja')).toHaveLength(2); - await user.click(screen.getAllByText(/poista rakennuttaja/i)[1]); - expect(screen.getAllByText('Rakennuttaja')).toHaveLength(1); + await user.click(screen.getByText(/poista rakennuttaja/i)); - await user.click(screen.getByText(/poista yhteyshenkilö/i)); - expect(screen.getByRole('tablist').childElementCount).toBe(1); - await user.click(screen.getByText(/poista yhteyshenkilö/i)); - expect(screen.queryByText('Yhteyshenkilön tiedot')).not.toBeInTheDocument(); + // Check Other types are present and clickable + await user.click(screen.getByText(/toteuttajan tiedot/i)); + await user.click(screen.getByText(/muiden tahojen tiedot/i)); }); }); diff --git a/src/domain/hanke/edit/HankeFormYhteystiedot.tsx b/src/domain/hanke/edit/HankeFormYhteystiedot.tsx index 2c5cdc072..de65ac45d 100644 --- a/src/domain/hanke/edit/HankeFormYhteystiedot.tsx +++ b/src/domain/hanke/edit/HankeFormYhteystiedot.tsx @@ -1,9 +1,9 @@ -import React, { useState } from 'react'; +import React, { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { $enum } from 'ts-enum-util'; -import { Accordion, Button, Fieldset, IconCross, IconPlusCircle, ToggleButton } from 'hds-react'; -import { useFieldArray } from 'react-hook-form'; -import { CONTACT_FORMFIELD, FORMFIELD, FormProps } from './types'; +import { Accordion, Button, Fieldset, IconCross, IconPlusCircle } from 'hds-react'; +import { useFieldArray, useFormContext } from 'react-hook-form'; +import { CONTACT_FORMFIELD, FORMFIELD, FormProps, SUBCONTACT_FORMFIELD } from './types'; import { HankeContact, CONTACT_TYYPPI, @@ -24,32 +24,16 @@ import './HankeForm.styles.scss'; const CONTACT_FIELDS: Array = [ 'tyyppi', 'nimi', - 'ytunnusTaiHetu', - 'osoite', - 'postinumero', - 'postitoimipaikka', + 'ytunnus', 'email', 'puhelinnumero', ]; -const REQUIRED_CONTACT_FIELDS: Array = [ - 'tyyppi', - 'nimi', - 'ytunnusTaiHetu', - 'email', -]; - -function isRequiredContactField(field: keyof HankeContact) { - return REQUIRED_CONTACT_FIELDS.includes(field); -} function getEmptyContact(): Omit { return { nimi: '', tyyppi: null, - ytunnusTaiHetu: '', - osoite: '', - postinumero: '', - postitoimipaikka: '', + ytunnus: '', email: '', puhelinnumero: '', alikontaktit: [], @@ -70,19 +54,18 @@ function getEmptyOtherContact(): HankeMuuTaho { function getEmptySubContact(): HankeSubContact { return { - nimi: '', - osoite: '', - postinumero: '', - postitoimipaikka: '', + etunimi: '', + sukunimi: '', email: '', puhelinnumero: '', }; } -const SubContactFields: React.FC<{ fieldPath: string; onRemove: () => void }> = ({ - fieldPath, - onRemove, -}) => { +const SubContactFields: React.FC<{ + fieldPath: string; + canBeRemoved: boolean; + onRemove: () => void; +}> = ({ fieldPath, canBeRemoved, onRemove }) => { const { t } = useTranslation(); return ( @@ -93,53 +76,62 @@ const SubContactFields: React.FC<{ fieldPath: string; onRemove: () => void }> = > - - - - + + - + {canBeRemoved && ( + + )} ); }; -const ContactField: React.FC<{ field: keyof HankeContact; fieldName: string }> = ({ - field, - fieldName, -}) => { +const ContactField: React.FC<{ + field: keyof HankeContact; + fieldName: string; + contactType: HankeContactTypeKey; + index: number; +}> = ({ field, fieldName, contactType, index }) => { const { t } = useTranslation(); + const { watch, setValue } = useFormContext(); + const selectedContactType = watch(`${contactType}.${index}.tyyppi`); + const inputDisabled = + field === CONTACT_FORMFIELD.TUNNUS && selectedContactType === CONTACT_TYYPPI.YKSITYISHENKILO; + + useEffect(() => { + if (inputDisabled) { + setValue(`${contactType}.${index}.ytunnus`, null, { + shouldValidate: true, + }); + } + }, [inputDisabled]); - const isRequired = isRequiredContactField(field); const label = t(`form:yhteystiedot:labels:${field}`); if (field === 'tyyppi') { @@ -147,7 +139,6 @@ const ContactField: React.FC<{ field: keyof HankeContact; fieldName: string }> = { @@ -160,7 +151,7 @@ const ContactField: React.FC<{ field: keyof HankeContact; fieldName: string }> = ); } - return ; + return ; }; const HankeFormYhteystiedot: React.FC = () => { @@ -168,8 +159,6 @@ const HankeFormYhteystiedot: React.FC = () => { const { t } = useTranslation(); const locale = useLocale(); - const [separateContact, setSeparateContact] = useState(false); - const { fields: rakennuttajat, append: appendRakennuttaja, @@ -184,15 +173,15 @@ const HankeFormYhteystiedot: React.FC = () => { remove: removeToteuttaja, } = useFieldArray({ name: FORMFIELD.TOTEUTTAJAT }); - const { fields: muutTahot, append: appendMuuTaho, remove: removeMuuTaho } = useFieldArray({ + const { + fields: muutTahot, + append: appendMuuTaho, + remove: removeMuuTaho, + } = useFieldArray({ name: FORMFIELD.MUUTTAHOT, }); - function toggleSeparateContact() { - setSeparateContact((separateContactValue) => !separateContactValue); - } - - const ownerSubContactFieldPath = `${FORMFIELD.OMISTAJAT}.0.${CONTACT_FORMFIELD.ALIKONTAKTIT}.0`; + const ownerSubContactFieldPath = `${FORMFIELD.OMISTAJAT}.0.${CONTACT_FORMFIELD.ALIKONTAKTIT}`; return (
@@ -202,60 +191,46 @@ const HankeFormYhteystiedot: React.FC = () => { {t(`form:yhteystiedot:titles:omistajaInfo`)} -
- - {CONTACT_FIELDS.map((contactField) => { - const fieldName = `${FORMFIELD.OMISTAJAT}.0.${contactField}`; - return ; - })} - -
-
- -
- {separateContact && ( -
- - + contactType={HANKE_CONTACT_TYPE.OMISTAJAT} + subContactPath={ownerSubContactFieldPath} + emptySubContact={getEmptySubContact()} + showInitialEmpty={true} + renderSubContact={(subContactIndex, removeSubContact) => { + const fieldPath = `${ownerSubContactFieldPath}.${subContactIndex}`; + return ( + 0} + onRemove={() => removeSubContact(subContactIndex)} /> - + ); + }} + > +
- - - - - + {CONTACT_FIELDS.map((contactField) => { + const fieldName = `${FORMFIELD.OMISTAJAT}.0.${contactField}`; + return ( + + ); + })}
- )} + + {/* Rakennuttaja */} = () => { return ( 0} onRemove={() => removeSubContact(subContactIndex)} /> ); @@ -288,7 +264,13 @@ const HankeFormYhteystiedot: React.FC = () => { {CONTACT_FIELDS.map((contactField) => { const fieldName = `${FORMFIELD.RAKENNUTTAJAT}.${index}.${contactField}`; return ( - + ); })} @@ -306,6 +288,7 @@ const HankeFormYhteystiedot: React.FC = () => { + {/* Toteuttaja */} = () => { return ( 0} onRemove={() => removeSubContact(subContactIndex)} /> ); @@ -338,7 +322,13 @@ const HankeFormYhteystiedot: React.FC = () => { {CONTACT_FIELDS.map((contactField) => { const fieldName = `${FORMFIELD.TOTEUTTAJAT}.${index}.${contactField}`; return ( - + ); })} @@ -356,6 +346,7 @@ const HankeFormYhteystiedot: React.FC = () => { + {/* Muut tahot */} = () => { return ( 0} onRemove={() => removeSubContact(subContactIndex)} /> ); diff --git a/src/domain/hanke/edit/components/ContactsSummary.tsx b/src/domain/hanke/edit/components/ContactsSummary.tsx index f5ebb8c9f..a4ca5d2e6 100644 --- a/src/domain/hanke/edit/components/ContactsSummary.tsx +++ b/src/domain/hanke/edit/components/ContactsSummary.tsx @@ -13,11 +13,9 @@ const ContactSummary: React.FC<{ contact: HankeContact | HankeMuuTaho }> = ({ co

{t(`form:yhteystiedot:contactType:${contact.tyyppi}`)}

{contact.nimi}

-

{contact.ytunnusTaiHetu}

- {contact.osoite &&

{contact.osoite}

} -

- {contact.postinumero} {contact.postitoimipaikka} -

+

{contact.ytunnus}

+

{contact.email}

+

{contact.puhelinnumero}

); } @@ -33,15 +31,16 @@ const ContactSummary: React.FC<{ contact: HankeContact | HankeMuuTaho }> = ({ co ); }; -const SubContactSummary: React.FC<{ contact: HankeSubContact }> = ({ contact }) => { +const SubContactSummary: React.FC<{ contact: HankeSubContact }> = ({ + contact: { etunimi, sukunimi, email, puhelinnumero }, +}) => { return (
-

{contact.nimi}

-

{contact.email}

- {contact.osoite &&

{contact.osoite}

}

- {contact.postinumero} {contact.postitoimipaikka} + {etunimi} {sukunimi}

+

{email}

+

{puhelinnumero}

); }; diff --git a/src/domain/hanke/edit/hankeSchema.ts b/src/domain/hanke/edit/hankeSchema.ts index 1f174a2a1..d1dc1811f 100644 --- a/src/domain/hanke/edit/hankeSchema.ts +++ b/src/domain/hanke/edit/hankeSchema.ts @@ -10,35 +10,43 @@ import { HANKE_KAISTAPITUUSHAITTA, CONTACT_TYYPPI, } from '../../types/hanke'; -import { FORMFIELD, CONTACT_FORMFIELD } from './types'; +import { FORMFIELD, CONTACT_FORMFIELD, SUBCONTACT_FORMFIELD } from './types'; +import isValidBusinessId from '../../../common/utils/isValidBusinessId'; const subContactSchema = yup .object() .nullable() .default(null) .shape({ - [CONTACT_FORMFIELD.NIMI]: yup.string().max(100).required(), - [CONTACT_FORMFIELD.OSOITE]: yup.string(), - [CONTACT_FORMFIELD.POSTINRO]: yup.string(), - [CONTACT_FORMFIELD.POSTITOIMIPAIKKA]: yup.string(), - [CONTACT_FORMFIELD.EMAIL]: yup.string().email().max(100).required(), - [CONTACT_FORMFIELD.PUHELINNUMERO]: yup.string().nullable().default(null).max(20), + [SUBCONTACT_FORMFIELD.SUKUNIMI]: yup.string().max(50).required(), + [SUBCONTACT_FORMFIELD.ETUNIMI]: yup.string().max(50).required(), + [SUBCONTACT_FORMFIELD.EMAIL]: yup.string().email().max(100).required(), + [SUBCONTACT_FORMFIELD.PUHELINNUMERO]: yup.string().nullable().default(null).max(20).required(), }); -const contactSchema = subContactSchema.shape({ - [CONTACT_FORMFIELD.TYYPPI]: yup.string().oneOf($enum(CONTACT_TYYPPI).getValues()).required(), - [CONTACT_FORMFIELD.TUNNUS]: yup.string().required(), - [CONTACT_FORMFIELD.ALIKONTAKTIT]: yup.array().ensure().of(subContactSchema), -}); +const contactSchema = yup + .object() + .nullable() + .default(null) + .shape({ + [CONTACT_FORMFIELD.NIMI]: yup.string().max(100), + [CONTACT_FORMFIELD.TYYPPI]: yup.string().oneOf($enum(CONTACT_TYYPPI).getValues()), + [CONTACT_FORMFIELD.TUNNUS]: yup + .string() + .nullable() + .when('tyyppi', { + is: (value: string) => value === CONTACT_TYYPPI.YRITYS || value === CONTACT_TYYPPI.YHTEISO, + then: (schema) => + schema.test('is-business-id', 'Is not valid business id', isValidBusinessId), + otherwise: (schema) => schema, + }), + [CONTACT_FORMFIELD.EMAIL]: yup.string().email().max(100), + [CONTACT_FORMFIELD.PUHELINNUMERO]: yup.string().nullable().default(null).max(20), + [CONTACT_FORMFIELD.ALIKONTAKTIT]: yup.array().ensure().of(subContactSchema), + }); const otherPartySchema = contactSchema - .omit([ - CONTACT_FORMFIELD.TYYPPI, - CONTACT_FORMFIELD.TUNNUS, - CONTACT_FORMFIELD.OSOITE, - CONTACT_FORMFIELD.POSTINRO, - CONTACT_FORMFIELD.POSTITOIMIPAIKKA, - ]) + .omit([CONTACT_FORMFIELD.TYYPPI, CONTACT_FORMFIELD.TUNNUS]) .shape({ [CONTACT_FORMFIELD.ROOLI]: yup.string().required(), [CONTACT_FORMFIELD.ORGANISAATIO]: yup.string(), diff --git a/src/domain/hanke/edit/types.ts b/src/domain/hanke/edit/types.ts index a33bb23ec..9003e6ae5 100644 --- a/src/domain/hanke/edit/types.ts +++ b/src/domain/hanke/edit/types.ts @@ -36,10 +36,7 @@ export enum CONTACT_FORMFIELD { TYYPPI = 'tyyppi', ROOLI = 'rooli', NIMI = 'nimi', - TUNNUS = 'ytunnusTaiHetu', - OSOITE = 'osoite', - POSTINRO = 'postinumero', - POSTITOIMIPAIKKA = 'postitoimipaikka', + TUNNUS = 'ytunnus', EMAIL = 'email', PUHELINNUMERO = 'puhelinnumero', ORGANISAATIO = 'organisaatioNimi', @@ -47,6 +44,14 @@ export enum CONTACT_FORMFIELD { ALIKONTAKTIT = 'alikontaktit', } +export enum SUBCONTACT_FORMFIELD { + ID = 'id', + ETUNIMI = 'etunimi', + SUKUNIMI = 'sukunimi', + EMAIL = 'email', + PUHELINNUMERO = 'puhelinnumero', +} + export interface HankeAlueFormState extends HankeAlue { feature?: Feature; // "virtualField" } diff --git a/src/domain/hanke/hankeView/HankeView.test.tsx b/src/domain/hanke/hankeView/HankeView.test.tsx index 0700cfe39..db44e8c64 100644 --- a/src/domain/hanke/hankeView/HankeView.test.tsx +++ b/src/domain/hanke/hankeView/HankeView.test.tsx @@ -82,9 +82,9 @@ test('Correct information about hanke should be displayed', async () => { // Data in contacts tab expect(screen.queryByText('Yritys')).toBeInTheDocument(); expect(screen.queryByText('Kauppisen maansiirtofirma KY')).toBeInTheDocument(); - expect(screen.queryByText('y-1234567')).toBeInTheDocument(); - expect(screen.queryByText('Lahdenkatu 3')).toBeInTheDocument(); - expect(screen.queryByText('42100 Lahti')).toBeInTheDocument(); + expect(screen.queryByText('5341034-5')).toBeInTheDocument(); + expect(screen.queryByText('toimisto@testi.com')).toBeInTheDocument(); + expect(screen.queryByText('0501234567')).toBeInTheDocument(); }); test('It is possible to delete hanke if it has no active applications', async () => { diff --git a/src/domain/johtoselvitys/Contacts.test.tsx b/src/domain/johtoselvitys/Contacts.test.tsx index 0b6484cd5..4e14e3b82 100644 --- a/src/domain/johtoselvitys/Contacts.test.tsx +++ b/src/domain/johtoselvitys/Contacts.test.tsx @@ -39,9 +39,7 @@ test('Contacts can be filled with hanke contact info', async () => { expect(screen.getAllByRole('button', { name: /tyyppi/i })[0]).toHaveTextContent('Yritys'); expect(screen.getAllByRole('textbox', { name: /nimi/i })[0]).toHaveValue(hankeOwner.nimi); - expect(screen.getAllByRole('textbox', { name: /Y-tunnus/i })[0]).toHaveValue( - hankeOwner.ytunnusTaiHetu, - ); + expect(screen.getAllByRole('textbox', { name: /Y-tunnus/i })[0]).toHaveValue(hankeOwner.ytunnus); expect(screen.getAllByRole('textbox', { name: /sähköposti/i })[0]).toHaveValue(hankeOwner.email); expect(screen.getAllByRole('textbox', { name: /puhelinnumero/i })[0]).toHaveValue( hankeOwner.puhelinnumero, diff --git a/src/domain/mocks/data/hankkeet-data.ts b/src/domain/mocks/data/hankkeet-data.ts index 875c014f3..b3f5738a9 100644 --- a/src/domain/mocks/data/hankkeet-data.ts +++ b/src/domain/mocks/data/hankkeet-data.ts @@ -66,20 +66,15 @@ const hankkeet: HankeDataDraft[] = [ id: 1, tyyppi: 'YRITYS', nimi: 'Yritys Oy', - ytunnusTaiHetu: 'y-1234567', - osoite: 'Yrityskuja 5', - postinumero: '00100', - postitoimipaikka: 'Helsinki', + ytunnus: '6006332-9', email: 'yritys@testi.com', puhelinnumero: '0000000000', alikontaktit: [ { - nimi: 'Esa Kauppinen', - osoite: 'Lehdenkatu 3', - postinumero: '42100', - postitoimipaikka: 'Lahti', + etunimi: 'Esa', + sukunimi: 'Kauppinen', email: 'esa.kauppinen@maansiirtofirma.com', - puhelinnumero: '', + puhelinnumero: '0000000000', }, ], }, @@ -89,28 +84,21 @@ const hankkeet: HankeDataDraft[] = [ id: 1, tyyppi: 'YRITYS', nimi: 'Yritys 2 Oy', - ytunnusTaiHetu: 'y-1234567', - osoite: '', - postinumero: '', - postitoimipaikka: '', + ytunnus: '6502327-0', email: 'yritys2@testi.com', - puhelinnumero: '', + puhelinnumero: '1111111111', alikontaktit: [ { - nimi: 'Matti Meikäläinen', - osoite: 'Katukuja 6', - postinumero: '', - postitoimipaikka: '', + etunimi: 'Matti', + sukunimi: 'Meikäläinen', email: 'matti.meikalainen@testi.com', - puhelinnumero: '', + puhelinnumero: '1111111111', }, { - nimi: 'Esa Kauppinen', - osoite: 'Lehdenkatu 3', - postinumero: '42100', - postitoimipaikka: 'Lahti', + etunimi: 'Esa', + sukunimi: 'Kauppinen', email: 'esa.kauppinen@maansiirtofirma.com', - puhelinnumero: '', + puhelinnumero: '1111111111', }, ], }, @@ -121,17 +109,15 @@ const hankkeet: HankeDataDraft[] = [ rooli: 'Isännöitsijä', nimi: 'Yritys 3 Oy', email: 'yritys3@testi.com', - puhelinnumero: '', + puhelinnumero: '2222222222', organisaatioNimi: 'Organisaatio', osasto: '', alikontaktit: [ { - nimi: 'Matti Meikäläinen', - osoite: 'Katukuja 6', - postinumero: '', - postitoimipaikka: '', + etunimi: 'Matti', + sukunimi: 'Meikäläinen', email: 'matti.meikalainen@testi.com', - puhelinnumero: '', + puhelinnumero: '2222222222', }, ], }, @@ -260,12 +246,17 @@ const hankkeet: HankeDataDraft[] = [ id: 1, tyyppi: 'YRITYS', nimi: 'Kauppisen maansiirtofirma KY', - ytunnusTaiHetu: 'y-1234567', - osoite: 'Lahdenkatu 3', - postinumero: '42100', - postitoimipaikka: 'Lahti', + ytunnus: '5341034-5', email: 'toimisto@testi.com', - puhelinnumero: '', + puhelinnumero: '0501234567', + alikontaktit: [ + { + etunimi: 'Esa', + sukunimi: 'Kauppinen', + email: 'esa.kauppinen@maansiirtofirma.com', + puhelinnumero: '0507654321', + }, + ], }, ], rakennuttajat: [], diff --git a/src/domain/types/hanke.ts b/src/domain/types/hanke.ts index 11f8adb03..ea9a0da5f 100644 --- a/src/domain/types/hanke.ts +++ b/src/domain/types/hanke.ts @@ -111,18 +111,19 @@ export type HankeContactTypeKey = | HANKE_CONTACT_TYPE.MUUTTAHOT; export interface HankeSubContact { - nimi: string; - osoite?: string; - postinumero?: string; - postitoimipaikka?: string; + etunimi: string; + sukunimi: string; email: string; puhelinnumero: string; } -export interface HankeContact extends HankeSubContact { +export interface HankeContact { id: number | null; tyyppi: keyof typeof CONTACT_TYYPPI | null; - ytunnusTaiHetu: string; + nimi: string; + email: string; + puhelinnumero: string; + ytunnus: string | null; alikontaktit?: HankeSubContact[]; } @@ -139,7 +140,7 @@ export type HankeMuuTaho = { export type HankeContacts = Array<(HankeContact | HankeMuuTaho)[] | undefined>; export function isHankeContact(contact: HankeContact | HankeMuuTaho): contact is HankeContact { - return (contact as HankeContact).ytunnusTaiHetu !== undefined; + return (contact as HankeContact).ytunnus !== undefined; } export enum CONTACT_TYYPPI { diff --git a/src/locales/en.json b/src/locales/en.json index 1099f9351..b0fae3726 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -163,7 +163,8 @@ "labels": { "tyyppi": "Type", "nimi": "Name", - "ytunnusTaiHetu": "Business ID or personal identity code", + "etunimi": "First name", + "sukunimi": "Last name", "ytunnus": "Business ID", "osoite": "Street address", "postinumero": "Postal code", diff --git a/src/locales/fi.json b/src/locales/fi.json index f9ccb1e90..b4bd78eba 100644 --- a/src/locales/fi.json +++ b/src/locales/fi.json @@ -172,7 +172,8 @@ "labels": { "tyyppi": "Tyyppi", "nimi": "Nimi", - "ytunnusTaiHetu": "Y-tunnus tai henkilötunnus", + "etunimi": "Etunimi", + "sukunimi": "Sukunimi", "ytunnus": "Y-tunnus", "osoite": "Katuosoite", "postinumero": "Postinumero", diff --git a/src/locales/sv.json b/src/locales/sv.json index 482cdc482..a51ac743e 100644 --- a/src/locales/sv.json +++ b/src/locales/sv.json @@ -163,7 +163,8 @@ "labels": { "tyyppi": "Typ", "nimi": "Namn", - "ytunnusTaiHetu": "FO-nummer eller personbeteckning", + "etunimi": "Förnamn", + "sukunimi": "Efternamn", "ytunnus": "FO-nummer", "osoite": "Gatuadress", "postinumero": "Postnummer",