diff --git a/packages/pn-pa-webapp/public/locales/it/notifiche.json b/packages/pn-pa-webapp/public/locales/it/notifiche.json index 32ec8e760c..653bf2ef4c 100644 --- a/packages/pn-pa-webapp/public/locales/it/notifiche.json +++ b/packages/pn-pa-webapp/public/locales/it/notifiche.json @@ -395,6 +395,7 @@ "title": "Informazioni preliminari", "protocol-number": "Numero di protocollo", "subject": "Oggetto della notifica", + "sender-denomination": "Ente mittente", "abstract": "Descrizione", "group": "Gruppo", "no-groups": "Non ci sono gruppi per questo prodotto", diff --git a/packages/pn-pa-webapp/src/__mocks__/Auth.mock.ts b/packages/pn-pa-webapp/src/__mocks__/Auth.mock.ts index 9cf6f3973c..9381f01fea 100644 --- a/packages/pn-pa-webapp/src/__mocks__/Auth.mock.ts +++ b/packages/pn-pa-webapp/src/__mocks__/Auth.mock.ts @@ -68,3 +68,24 @@ export const userResponse: User = { }, desired_exp: calcExpirationDate(), }; +export const longOrganizationNameUserResponse: User = { + sessionToken: 'mocked-session-token', + name: 'giuseppe', + family_name: 'rossini', + fiscal_number: 'RSSGPP80B02G273H', + email: 'giuseppe.rossini@gmail.com', + uid: '00000000-0000-0000-0000-000000000000', + organization: { + id: '5b994d4a-0fa8-47ac-9c7b-354f1d44a1ce', + name: 'Comune di Palermo - Commissario Straordinario del Governo ZES Sicilia Occidentale', + roles: [ + { + partyRole: PartyRole.MANAGER, + role: PNRole.ADMIN, + }, + ], + fiscal_code: '80016350821', + hasGroups: false, + }, + desired_exp: calcExpirationDate(), +}; diff --git a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts index a15b03d606..871150c1f2 100644 --- a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts +++ b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts @@ -204,6 +204,7 @@ export const newNotificationEmpty: NewNotification = { group: '', taxonomyCode: '', notificationFeePolicy: '' as NotificationFeePolicy, + senderDenomination: userResponse.organization.name, }; export const newNotificationDTO: NewNotificationDTO = newNotificationMapper(newNotification); diff --git a/packages/pn-pa-webapp/src/components/NewNotification/PreliminaryInformations.tsx b/packages/pn-pa-webapp/src/components/NewNotification/PreliminaryInformations.tsx index 8420e946d6..275cbd666f 100644 --- a/packages/pn-pa-webapp/src/components/NewNotification/PreliminaryInformations.tsx +++ b/packages/pn-pa-webapp/src/components/NewNotification/PreliminaryInformations.tsx @@ -54,6 +54,14 @@ const PreliminaryInformations = ({ notification, onConfirm }: Props) => { (state: RootState) => state.userState.user.organization.hasGroups ); + const senderDenomination = useAppSelector((state: RootState) => + state.userState.user.organization.rootParent?.description + ? state.userState.user.organization.rootParent?.description + + ' - ' + + state.userState.user.organization.name + : state.userState.user.organization.name + ); + const { t } = useTranslation(['notifiche'], { keyPrefix: 'new-notification.steps.preliminary-informations', }); @@ -64,6 +72,7 @@ const PreliminaryInformations = ({ notification, onConfirm }: Props) => { () => ({ paProtocolNumber: notification.paProtocolNumber || '', subject: notification.subject || '', + senderDenomination, abstract: notification.abstract ?? '', group: notification.group ?? '', taxonomyCode: notification.taxonomyCode || '', @@ -76,6 +85,10 @@ const PreliminaryInformations = ({ notification, onConfirm }: Props) => { const validationSchema = yup.object({ paProtocolNumber: requiredStringFieldValidation(tc, 256), subject: requiredStringFieldValidation(tc, 134, 10), + senderDenomination: yup + .string() + .required(`${t('sender-denomination')} ${tc('required')}`) + .max(80, tc('too-long-field-error', { maxLength: 80 })), abstract: yup .string() .max(1024, tc('too-long-field-error', { maxLength: 1024 })) @@ -125,6 +138,7 @@ const PreliminaryInformations = ({ notification, onConfirm }: Props) => { fetchGroups(); }, [fetchGroups]); + const isLessThan80Chars = (field: string): boolean => (field ? field.length < 80 : false); return ( { size="small" margin="normal" /> + { }; }); -const populateForm = async (form: HTMLFormElement, hasPayment: boolean) => { +const populateForm = async ( + form: HTMLFormElement, + hasPayment: boolean, + organizationName: string = userResponse.organization.name +) => { await testInput(form, 'paProtocolNumber', newNotification.paProtocolNumber); await testInput(form, 'subject', newNotification.subject); await testInput(form, 'taxonomyCode', newNotification.taxonomyCode); + await testInput(form, 'senderDenomination', organizationName); await testSelect( form, 'group', @@ -119,6 +125,7 @@ describe('PreliminaryInformations component with payment enabled', async () => { testFormElements(form, 'abstract', 'abstract'); testFormElements(form, 'group', 'group'); testFormElements(form, 'taxonomyCode', 'taxonomy-id*'); + testFormElements(form, 'senderDenomination', 'sender-denomination*'); testRadio(form, 'comunicationTypeRadio', ['registered-letter-890', 'simple-registered-letter']); testRadio(form, 'paymentMethodRadio', [ 'pagopa-notice', @@ -196,6 +203,7 @@ describe('PreliminaryInformations component with payment enabled', async () => { recipients: [], physicalCommunicationType: PhysicalCommunicationType.AR_REGISTERED_LETTER, paymentMode: PaymentModel.PAGO_PA_NOTICE_F24_FLATRATE, + senderDenomination: newNotification.senderDenomination, }); }); expect(confirmHandlerMk).toBeCalledTimes(1); @@ -227,12 +235,12 @@ describe('PreliminaryInformations component with payment enabled', async () => { // set invalid values // paProtocolNumber await testInput(form, 'paProtocolNumber', ''); - const potrocolNumberError = form.querySelector('#paProtocolNumber-helper-text'); - expect(potrocolNumberError).toHaveTextContent('required-field'); + const protocolNumberError = form.querySelector('#paProtocolNumber-helper-text'); + expect(protocolNumberError).toHaveTextContent('required-field'); await testInput(form, 'paProtocolNumber', ' text-with-spaces '); - expect(potrocolNumberError).toHaveTextContent('no-spaces-at-edges'); + expect(protocolNumberError).toHaveTextContent('no-spaces-at-edges'); await testInput(form, 'paProtocolNumber', randomString(257)); - expect(potrocolNumberError).toHaveTextContent('too-long-field-error'); + expect(protocolNumberError).toHaveTextContent('too-long-field-error'); // subject await testInput(form, 'subject', ''); const subjectError = form.querySelector('#subject-helper-text'); @@ -255,6 +263,16 @@ describe('PreliminaryInformations component with payment enabled', async () => { expect(taxonomyCodeError).toHaveTextContent('taxonomy-id required'); await testInput(form, 'taxonomyCode', randomString(4)); expect(taxonomyCodeError).toHaveTextContent('taxonomy-id invalid'); + // senderDenomination + await testInput(form, 'senderDenomination', ''); + const senderDenominationError = form.querySelector('#senderDenomination-helper-text'); + expect(senderDenominationError).toHaveTextContent('sender-denomination required'); + await testInput( + form, + 'senderDenomination', + 'Comune di Palermo - Commissario Straordinario del Governo ZES Sicilia Occidentale' + ); + expect(senderDenominationError).toHaveTextContent('too-long-field-error'); // check submit button state const button = within(form).getByTestId('step-submit'); expect(button).toBeDisabled(); @@ -271,6 +289,7 @@ describe('PreliminaryInformations component with payment enabled', async () => { user: { organization: { hasGroup: true, + name: 'Comune di Palermo', }, }, }, @@ -289,6 +308,12 @@ describe('PreliminaryInformations component with payment enabled', async () => { testFormElements(form, 'abstract', 'abstract', newNotification.abstract); testFormElements(form, 'group', 'group', newNotification.group); testFormElements(form, 'taxonomyCode', 'taxonomy-id*', newNotification.taxonomyCode); + testFormElements( + form, + 'senderDenomination', + 'sender-denomination*', + userResponse.organization.name + ); const physicalCommunicationType = form.querySelector( `input[name="physicalCommunicationType"][value="${newNotification.physicalCommunicationType}"]` ); @@ -420,8 +445,25 @@ describe('PreliminaryInformations Component with payment disabled', async () => recipients: [], physicalCommunicationType: PhysicalCommunicationType.AR_REGISTERED_LETTER, paymentMode: PaymentModel.NOTHING, + senderDenomination: newNotification.senderDenomination, }); }); expect(confirmHandlerMk).toBeCalledTimes(1); }); + + it('set senderDenomination longer than 80 characters', async () => { + mock.onGet(GET_USER_GROUPS(GroupStatus.ACTIVE)).reply(200, newNotificationGroups); + await act(async () => { + result = render( + + ); + }); + const form = result.getByTestId('preliminaryInformationsForm') as HTMLFormElement; + await testInput(form, 'senderDenomination', longOrganizationNameUserResponse.organization.name); + const senderDenominationError = form.querySelector('#senderDenomination-helper-text'); + expect(senderDenominationError).toHaveTextContent('too-long-field-error'); + const button = within(form).getByTestId('step-submit'); + // check submit button state + expect(button).toBeDisabled(); + }); }); diff --git a/packages/pn-pa-webapp/src/models/NewNotification.ts b/packages/pn-pa-webapp/src/models/NewNotification.ts index ac36869f78..8202e02e0b 100644 --- a/packages/pn-pa-webapp/src/models/NewNotification.ts +++ b/packages/pn-pa-webapp/src/models/NewNotification.ts @@ -1,10 +1,10 @@ import { DigitalDomicileType, + NotificationDetailDocument, NotificationDetailRecipient, NotificationFeePolicy, PhysicalCommunicationType, RecipientType, - NotificationDetailDocument, } from '@pagopa-pn/pn-commons'; export enum PaymentModel { @@ -22,7 +22,7 @@ interface BaseNewNotification { abstract?: string; cancelledIun?: string; physicalCommunicationType: PhysicalCommunicationType; - senderDenomination?: string; + senderDenomination: string; senderTaxId?: string; group?: string; taxonomyCode: string; diff --git a/packages/pn-pa-webapp/src/pages/NewNotification.page.tsx b/packages/pn-pa-webapp/src/pages/NewNotification.page.tsx index 475fb0debc..69b8cc2406 100644 --- a/packages/pn-pa-webapp/src/pages/NewNotification.page.tsx +++ b/packages/pn-pa-webapp/src/pages/NewNotification.page.tsx @@ -91,8 +91,8 @@ const NewNotification = () => { useEffect(() => { dispatch( setSenderInfos({ - senderDenomination: organization.parentDescription - ? organization.parentDescription + ' - ' + organization.name + senderDenomination: organization.rootParent?.description + ? organization.rootParent?.description + ' - ' + organization.name : organization.name, senderTaxId: organization.fiscal_code, }) diff --git a/packages/pn-pa-webapp/src/redux/auth/reducers.ts b/packages/pn-pa-webapp/src/redux/auth/reducers.ts index 762c67ac2e..26dc1c8438 100644 --- a/packages/pn-pa-webapp/src/redux/auth/reducers.ts +++ b/packages/pn-pa-webapp/src/redux/auth/reducers.ts @@ -35,7 +35,6 @@ const organizationMatcher: yup.SchemaOf = yup.object({ groups: yup.array().of(yup.string()).notRequired(), name: yup.string().required(), hasGroups: yup.boolean(), - parentDescription: yup.string().notRequired(), aooParent: yup.string().notRequired(), subUnitCode: yup.string().notRequired(), subUnitType: yup.string().notRequired(), @@ -45,6 +44,7 @@ const organizationMatcher: yup.SchemaOf = yup.object({ description: yup.string().notRequired(), }) .notRequired(), + ipaCode: yup.string().notRequired() }); const userDataMatcher = yup diff --git a/packages/pn-pa-webapp/src/redux/auth/types.ts b/packages/pn-pa-webapp/src/redux/auth/types.ts index 81e442a0e6..72a7deebd7 100644 --- a/packages/pn-pa-webapp/src/redux/auth/types.ts +++ b/packages/pn-pa-webapp/src/redux/auth/types.ts @@ -8,7 +8,6 @@ export interface User extends BasicUser { } export interface Organization { - parentDescription?: string; id: string; roles: Array; fiscal_code: string; // organization fiscal code @@ -18,6 +17,7 @@ export interface Organization { subUnitCode?: string; subUnitType?: string; aooParent?: string; + ipaCode?: string; rootParent?: { id?: string; description?: string; diff --git a/packages/pn-pa-webapp/src/redux/newNotification/__test__/reducers.test.ts b/packages/pn-pa-webapp/src/redux/newNotification/__test__/reducers.test.ts index fc0f5dbd8c..afd9fb4d9f 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/__test__/reducers.test.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/__test__/reducers.test.ts @@ -44,6 +44,7 @@ const initialState = { group: '', taxonomyCode: '', notificationFeePolicy: '', + senderDenomination: '', }, groups: [], isCompleted: false, diff --git a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts index 54536893ab..8a4a59cd04 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts @@ -31,6 +31,7 @@ const initialState = { taxonomyCode: '', paymentMode: '' as PaymentModel, notificationFeePolicy: '' as NotificationFeePolicy, + senderDenomination: '', } as NewNotification, groups: [] as Array, isCompleted: false,