From 55a96a83eb4ae6c036ef7b03ee1c874a7527e716 Mon Sep 17 00:00:00 2001 From: alessandrogelmi Date: Fri, 14 Feb 2025 13:03:52 +0100 Subject: [PATCH 1/8] fix: remove useless payment properties and refactor set of payments of new notification --- .../src/__mocks__/NewNotification.mock.ts | 90 ++++++++++--------- .../NewNotification/PaymentMethods.tsx | 8 +- .../src/models/NewNotification.ts | 19 +++- .../newNotification/__test__/reducers.test.ts | 10 +-- .../src/redux/newNotification/reducers.ts | 35 +++----- .../src/utility/notification.utility.ts | 67 +++++--------- 6 files changed, 107 insertions(+), 122 deletions(-) diff --git a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts index 63b62612ad..b636f4f096 100644 --- a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts +++ b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts @@ -10,7 +10,6 @@ import { NewNotificationDocument, NewNotificationRecipient, NotificationFeePolicy, - PaymentModel, } from '../models/NewNotification'; import { UserGroup } from '../models/user'; import { newNotificationMapper } from '../utility/notification.utility'; @@ -35,6 +34,42 @@ export const newNotificationGroups: Array = [ }, ]; +const newNotificationPagoPa: NewNotificationDocument = { + id: 'mocked-pagopa-id', + idx: 0, + name: 'mocked-name', + contentType: 'application/pdf', + file: { + data: new File([''], 'mocked-name', { type: 'application/pdf' }), + sha256: { + hashBase64: 'mocked-pa-sha256', + hashHex: '', + }, + }, + ref: { + key: '', + versionToken: '', + }, +}; + +const newNotificationF24Standard: NewNotificationDocument = { + id: 'mocked-f24standard-id', + idx: 0, + name: 'mocked-name', + contentType: 'application/pdf', + file: { + data: new File([''], 'mocked-name', { type: 'application/pdf' }), + sha256: { + hashBase64: 'mocked-f24standard-sha256', + hashHex: '', + }, + }, + ref: { + key: '', + versionToken: '', + }, +}; + const newNotificationRecipients: Array = [ { id: 'recipient.0', @@ -53,6 +88,11 @@ const newNotificationRecipients: Array = [ municipalityDetails: '', province: 'Roma', foreignState: 'Italia', + payments: [ + { + pagoPA: { ...newNotificationPagoPa }, + }, + ], }, { id: 'recipient.1', @@ -71,6 +111,12 @@ const newNotificationRecipients: Array = [ municipalityDetails: '', province: 'Roma', foreignState: 'Italia', + payments: [ + { + pagoPA: { ...newNotificationPagoPa }, + f24: { ...newNotificationF24Standard }, + }, + ], }, ]; @@ -115,42 +161,6 @@ const newNotificationDocuments: Array = [ }, ]; -const newNotificationPagoPa: NewNotificationDocument = { - id: 'mocked-pagopa-id', - idx: 0, - name: 'mocked-name', - contentType: 'application/pdf', - file: { - data: new File([''], 'mocked-name', { type: 'application/pdf' }), - sha256: { - hashBase64: 'mocked-pa-sha256', - hashHex: '', - }, - }, - ref: { - key: '', - versionToken: '', - }, -}; - -const newNotificationF24Standard: NewNotificationDocument = { - id: 'mocked-f24standard-id', - idx: 0, - name: 'mocked-name', - contentType: 'application/pdf', - file: { - data: new File([''], 'mocked-name', { type: 'application/pdf' }), - sha256: { - hashBase64: 'mocked-f24standard-sha256', - hashHex: '', - }, - }, - ref: { - key: '', - versionToken: '', - }, -}; - export const payments = { [newNotificationRecipients[0].taxId]: { pagoPa: { ...newNotificationPagoPa }, @@ -168,7 +178,6 @@ export const newNotification: NewNotification = { recipients: newNotificationRecipients, documents: newNotificationDocuments, physicalCommunicationType: PhysicalCommunicationType.REGISTERED_LETTER_890, - paymentMode: PaymentModel.NOTHING, group: newNotificationGroups[2].id, taxonomyCode: '010801N', notificationFeePolicy: NotificationFeePolicy.FLAT_RATE, @@ -185,12 +194,9 @@ export const newNotificationEmpty: NewNotification = { subject: '', recipients: [], documents: [], - payment: {}, - physicalCommunicationType: '' as PhysicalCommunicationType, - paymentMode: '' as PaymentModel, + physicalCommunicationType: PhysicalCommunicationType.REGISTERED_LETTER_890, group: '', taxonomyCode: '', - notificationFeePolicy: '' as NotificationFeePolicy, senderDenomination: userResponse.organization.name, }; diff --git a/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx b/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx index cfd93625c8..e35fb22ae7 100644 --- a/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx +++ b/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx @@ -175,7 +175,7 @@ const PaymentMethods: React.FC = ({ const handlePreviousStep = () => { if (onPreviousStep) { - dispatch(setPaymentDocuments({ paymentDocuments: formatPaymentDocuments() })); + dispatch(setPaymentDocuments({ recipients: notification.recipients })); onPreviousStep(); } }; @@ -221,7 +221,7 @@ const PaymentMethods: React.FC = ({ // Maybe now the form is empty, but in the previous time the user went back // from the payments step the form wasn't empty. // Just in case, we clean the payment info from the Redux store - dispatch(setPaymentDocuments({ paymentDocuments: {} })); + // dispatch(setPaymentDocuments({ paymentDocuments: {} })); dispatch(setIsCompleted()); } else { // Beware! - @@ -283,10 +283,10 @@ const PaymentMethods: React.FC = ({ useImperativeHandle(forwardedRef, () => ({ confirm() { - dispatch(setPaymentDocuments({ paymentDocuments: formatPaymentDocuments() })); + dispatch(setPaymentDocuments({ recipients: notification.recipients })); }, })); - + return (
; } +export interface NewNotificationPayment { + pagoPA?: NewNotificationDocument; + f24?: NewNotificationDocument; +} + // New Notification export interface NewNotificationRecipient { id: string; @@ -56,6 +67,7 @@ export interface NewNotificationRecipient { municipalityDetails?: string; province: string; foreignState: string; + payments?: Array; } export interface NewNotificationDocument { @@ -77,10 +89,11 @@ export interface NewNotificationDocument { } export interface NewNotification extends BaseNewNotification, NewNotificationBilingualism { - paymentMode?: PaymentModel; recipients: Array; documents: Array; - payment?: { [key: string]: PaymentObject }; + paFee?: number; + vat?: number; + pagoPaIntMode?: PagoPaIntegrationMode; } export interface NewNotificationBilingualism { 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 96d513b9c2..9bb9061fec 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 @@ -34,12 +34,9 @@ const initialState = { subject: '', recipients: [], documents: [], - payment: {}, - physicalCommunicationType: '', - paymentMode: '', + physicalCommunicationType: 'REGISTERED_LETTER_890', group: '', taxonomyCode: '', - notificationFeePolicy: '', senderDenomination: '', }, groups: [], @@ -173,9 +170,9 @@ describe('New notification redux state tests', () => { }); it('Should be able to save payment documents', () => { - const action = store.dispatch(setPaymentDocuments({ paymentDocuments: payments })); + const action = store.dispatch(setPaymentDocuments({ recipients: newNotification.recipients })); expect(action.type).toBe('newNotificationSlice/setPaymentDocuments'); - expect(action.payload).toEqual({ paymentDocuments: payments }); + expect(action.payload).toEqual({ recipients: newNotification.recipients }); }); it('Should be able to upload payment document', async () => { @@ -272,6 +269,7 @@ describe('New notification redux state tests', () => { idempotenceToken: 'mocked-idempotenceToken', }; const mappedNotification = newNotificationMapper(newNotification); + mock.onPost('/bff/v1/notifications/sent', mappedNotification).reply(200, mockResponse); const action = await store.dispatch(createNewNotification(newNotification)); expect(action.type).toBe('createNewNotification/fulfilled'); diff --git a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts index 992f74d7bd..0ebb1d2193 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts @@ -5,9 +5,6 @@ import { NewNotification, NewNotificationDocument, NewNotificationRecipient, - NotificationFeePolicy, - PaymentModel, - PaymentObject, } from '../../models/NewNotification'; import { UserGroup } from '../../models/user'; import { getConfiguration } from '../../services/configuration.service'; @@ -19,22 +16,26 @@ import { } from './actions'; import { PreliminaryInformationsPayload } from './types'; -const initialState = { +type NewNotificationInitialState = { + loading: boolean; + notification: NewNotification; + groups: Array; + isCompleted: boolean; +}; + +const initialState: NewNotificationInitialState = { loading: false, notification: { paProtocolNumber: '', subject: '', recipients: [], documents: [], - payment: {}, - physicalCommunicationType: '' as PhysicalCommunicationType, + physicalCommunicationType: PhysicalCommunicationType.REGISTERED_LETTER_890, group: '', taxonomyCode: '', - paymentMode: '' as PaymentModel, - notificationFeePolicy: '' as NotificationFeePolicy, senderDenomination: '', - } as NewNotification, - groups: [] as Array, + }, + groups: [], isCompleted: false, }; @@ -54,19 +55,9 @@ const newNotificationSlice = createSlice({ state.notification.senderTaxId = action.payload.senderTaxId; }, setPreliminaryInformations: (state, action: PayloadAction) => { - // TODO: capire la logica di set della fee policy sia corretta state.notification = { ...state.notification, ...action.payload, - // PN-1835 - // in questa fase la notificationFeePolicy viene assegnata di default a FLAT_RATE - // Carlotta Dimatteo 10/08/2022 - notificationFeePolicy: NotificationFeePolicy.FLAT_RATE, - // reset payment data if payment mode has changed - payment: - state.notification.paymentMode !== action.payload.paymentMode - ? {} - : state.notification.payment, }; }, saveRecipients: ( @@ -86,11 +77,11 @@ const newNotificationSlice = createSlice({ }, setPaymentDocuments: ( state, - action: PayloadAction<{ paymentDocuments: { [key: string]: PaymentObject } }> + action: PayloadAction<{ recipients: Array }> ) => { state.notification = { ...state.notification, - payment: action.payload.paymentDocuments, + recipients: action.payload.recipients, }; }, setIsCompleted: (state) => { diff --git a/packages/pn-pa-webapp/src/utility/notification.utility.ts b/packages/pn-pa-webapp/src/utility/notification.utility.ts index 9ab808985b..7da3d6dfc6 100644 --- a/packages/pn-pa-webapp/src/utility/notification.utility.ts +++ b/packages/pn-pa-webapp/src/utility/notification.utility.ts @@ -14,9 +14,8 @@ import { NewNotificationDTO, NewNotificationDocument, NewNotificationLangOther, + NewNotificationPayment, NewNotificationRecipient, - PaymentModel, - PaymentObject, } from '../models/NewNotification'; const checkPhysicalAddress = (recipient: NewNotificationRecipient) => { @@ -51,8 +50,7 @@ const checkPhysicalAddress = (recipient: NewNotificationRecipient) => { }; const newNotificationRecipientsMapper = ( - recipients: Array, - paymentMethod?: PaymentModel + recipients: Array ): Array => recipients.map((recipient) => { const digitalDomicile = recipient.digitalDomicile @@ -74,12 +72,9 @@ const newNotificationRecipientsMapper = ( // eslint-disable-next-line functional/immutable-data parsedRecipient.digitalDomicile = digitalDomicile; } - if (paymentMethod !== PaymentModel.NOTHING) { + if (recipient.payments) { // eslint-disable-next-line functional/immutable-data - // parsedRecipient.payment = { - // creditorTaxId: recipient.creditorTaxId, - // noticeCode: recipient.noticeCode, - // }; + parsedRecipient.payments = newNotificationPaymentDocumentsMapper(recipient.payments); } return parsedRecipient; }); @@ -101,48 +96,41 @@ const newNotificationAttachmentsMapper = ( documents.map((document) => newNotificationDocumentMapper(document)); const newNotificationPaymentDocumentsMapper = ( - recipients: Array, - paymentDocuments: { [key: string]: PaymentObject } -): Array => - recipients.map((r) => { - const payment: NotificationDetailPayment = {}; + recipientPayments: Array +): Array => + recipientPayments.map((payment) => { + const mappedPayment: NotificationDetailPayment = {}; + /* eslint-disable functional/immutable-data */ - if ( - paymentDocuments[r.taxId].pagoPa && - paymentDocuments[r.taxId].pagoPa.file.sha256.hashBase64 !== '' - ) { - payment.pagoPa = { + if (payment.pagoPA && payment.pagoPA.file.sha256.hashBase64 !== '') { + mappedPayment.pagoPa = { creditorTaxId: '', noticeCode: '', - attachment: newNotificationDocumentMapper(paymentDocuments[r.taxId].pagoPa), + attachment: newNotificationDocumentMapper(payment.pagoPA), applyCost: false, }; } - if ( - paymentDocuments[r.taxId].f24 && - paymentDocuments[r.taxId].f24?.file.sha256.hashBase64 !== '' - ) { - payment.f24 = { - title: paymentDocuments[r.taxId].f24!.name, + + if (payment.f24 && payment.f24.file.sha256.hashBase64 !== '') { + mappedPayment.f24 = { + title: payment.f24.name, applyCost: true, metadataAttachment: { digests: { - sha256: paymentDocuments[r.taxId].f24!.file.sha256.hashBase64, + sha256: payment.f24.file.sha256.hashBase64, }, - contentType: paymentDocuments[r.taxId].f24!.contentType, - ref: paymentDocuments[r.taxId].f24!.ref, + contentType: payment.f24.contentType, + ref: payment.f24.ref, }, }; } - r.payments = [payment]; /* eslint-enable functional/immutable-data */ - return r; + + return mappedPayment; }); export function newNotificationMapper(newNotification: NewNotification): NewNotificationDTO { const clonedNotification = _.omit(_.cloneDeep(newNotification), [ - 'paymentMode', - 'payment', 'additionalAbstract', 'additionalLang', 'additionalSubject', @@ -179,20 +167,9 @@ export function newNotificationMapper(newNotification: NewNotification): NewNoti } // format recipients - newNotificationParsed.recipients = newNotificationRecipientsMapper( - newNotification.recipients, - newNotification.paymentMode - ); + newNotificationParsed.recipients = newNotificationRecipientsMapper(newNotification.recipients); // format attachments newNotificationParsed.documents = newNotificationAttachmentsMapper(newNotification.documents); - // format payments - if (newNotification.payment && Object.keys(newNotification.payment).length > 0) { - newNotificationParsed.recipients = newNotificationPaymentDocumentsMapper( - newNotificationParsed.recipients, - newNotification.payment - ); - } - /* eslint-enable functional/immutable-data */ return newNotificationParsed; } From b1bea6bbf513ad5517498c025875a454770d24a3 Mon Sep 17 00:00:00 2001 From: alessandrogelmi Date: Fri, 14 Feb 2025 16:20:20 +0100 Subject: [PATCH 2/8] fix: uploadNotificationPaymentDocument action --- .../src/redux/newNotification/actions.ts | 72 ++++++++++--------- .../src/redux/newNotification/reducers.ts | 2 +- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/packages/pn-pa-webapp/src/redux/newNotification/actions.ts b/packages/pn-pa-webapp/src/redux/newNotification/actions.ts index e6442509a8..41a285ef5b 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/actions.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/actions.ts @@ -13,8 +13,8 @@ import { import { NewNotification, NewNotificationDocument, + NewNotificationRecipient, NewNotificationResponse, - PaymentObject, } from '../../models/NewNotification'; import { GroupStatus, UserGroup } from '../../models/user'; import { newNotificationMapper } from '../../utility/notification.utility'; @@ -132,49 +132,57 @@ export const uploadNotificationDocument = createAsyncThunk< } ); -const getPaymentDocumentsToUpload = (items: { - [key: string]: PaymentObject; -}): Array> => { +const getPaymentDocumentsToUpload = ( + recipients: Array +): Array> => { const documentsArr: Array> = []; - for (const item of Object.values(items)) { - /* eslint-disable functional/immutable-data */ - if (item.pagoPa && !item.pagoPa.ref.key && !item.pagoPa.ref.versionToken) { - documentsArr.push(createPayloadToUpload(item.pagoPa)); - } - if (item.f24 && !item.f24.ref.key && !item.f24.ref.versionToken) { - documentsArr.push(createPayloadToUpload(item.f24)); - } - /* eslint-enable functional/immutable-data */ - } + /* eslint-disable functional/immutable-data */ + recipients.map((recipient) => { + recipient.payments?.map((payment) => { + if (payment.pagoPA && !payment.pagoPA.ref.key && !payment.pagoPA.ref.versionToken) { + documentsArr.push(createPayloadToUpload(payment.pagoPA)); + } + + if (payment.f24 && !payment.f24.ref.key && !payment.f24.ref.versionToken) { + documentsArr.push(createPayloadToUpload(payment.f24)); + } + }); + }); + /* eslint-enable functional/immutable-data */ + return documentsArr; }; export const uploadNotificationPaymentDocument = createAsyncThunk< - { [key: string]: PaymentObject }, - { [key: string]: PaymentObject } + Array, + Array >( NEW_NOTIFICATION_ACTIONS.UPLOAD_PAYMENT_DOCUMENT, - async (items: { [key: string]: PaymentObject }, { rejectWithValue }) => { + async (recipients: Array, { rejectWithValue }) => { try { // before upload, filter out documents already uploaded - const documentsToUpload = await Promise.all(getPaymentDocumentsToUpload(items)); + const documentsToUpload = await Promise.all(getPaymentDocumentsToUpload(recipients)); if (documentsToUpload.length === 0) { - return items; + return recipients; } const documentsUploaded = await uploadNotificationDocumentCbk(documentsToUpload); - const updatedItems = _.cloneDeep(items); - for (const item of Object.values(updatedItems)) { - /* eslint-disable functional/immutable-data */ - if (item.pagoPa && documentsUploaded[item.pagoPa.id]) { - item.pagoPa.ref.key = documentsUploaded[item.pagoPa.id].key; - item.pagoPa.ref.versionToken = documentsUploaded[item.pagoPa.id].versionToken; - } - if (item.f24 && documentsUploaded[item.f24.id]) { - item.f24.ref.key = documentsUploaded[item.f24.id].key; - item.f24.ref.versionToken = documentsUploaded[item.f24.id].versionToken; - } - /* eslint-enable functional/immutable-data */ - } + const updatedItems = _.cloneDeep(recipients); + + updatedItems.map((items) => { + items.payments?.map((payment) => { + /* eslint-disable functional/immutable-data */ + if (payment.pagoPA && documentsUploaded[payment.pagoPA.id]) { + payment.pagoPA.ref.key = documentsUploaded[payment.pagoPA.id].key; + payment.pagoPA.ref.versionToken = documentsUploaded[payment.pagoPA.id].versionToken; + } + if (payment.f24 && documentsUploaded[payment.f24.id]) { + payment.f24.ref.key = documentsUploaded[payment.f24.id].key; + payment.f24.ref.versionToken = documentsUploaded[payment.f24.id].versionToken; + } + /* eslint-enable functional/immutable-data */ + }); + }); + return updatedItems; } catch (e) { return rejectWithValue(parseError(e)); diff --git a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts index 0ebb1d2193..062a180d17 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts @@ -98,7 +98,7 @@ const newNotificationSlice = createSlice({ state.isCompleted = !getConfiguration().IS_PAYMENT_ENABLED; }); builder.addCase(uploadNotificationPaymentDocument.fulfilled, (state, action) => { - state.notification.payment = action.payload; + state.notification.recipients = action.payload; state.isCompleted = true; }); builder.addCase(createNewNotification.rejected, (state) => { From 41d756481ab7a9b8e425a513e0fb4285c319550e Mon Sep 17 00:00:00 2001 From: alessandrogelmi Date: Fri, 14 Feb 2025 16:40:30 +0100 Subject: [PATCH 3/8] fix: use for instead of map --- .../src/redux/newNotification/actions.ts | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/pn-pa-webapp/src/redux/newNotification/actions.ts b/packages/pn-pa-webapp/src/redux/newNotification/actions.ts index 41a285ef5b..2ccecd285e 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/actions.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/actions.ts @@ -137,8 +137,12 @@ const getPaymentDocumentsToUpload = ( ): Array> => { const documentsArr: Array> = []; /* eslint-disable functional/immutable-data */ - recipients.map((recipient) => { - recipient.payments?.map((payment) => { + for (const recipient of recipients) { + if (!recipient.payments) { + continue; + } + + for (const payment of recipient.payments) { if (payment.pagoPA && !payment.pagoPA.ref.key && !payment.pagoPA.ref.versionToken) { documentsArr.push(createPayloadToUpload(payment.pagoPA)); } @@ -146,8 +150,8 @@ const getPaymentDocumentsToUpload = ( if (payment.f24 && !payment.f24.ref.key && !payment.f24.ref.versionToken) { documentsArr.push(createPayloadToUpload(payment.f24)); } - }); - }); + } + } /* eslint-enable functional/immutable-data */ return documentsArr; @@ -168,8 +172,12 @@ export const uploadNotificationPaymentDocument = createAsyncThunk< const documentsUploaded = await uploadNotificationDocumentCbk(documentsToUpload); const updatedItems = _.cloneDeep(recipients); - updatedItems.map((items) => { - items.payments?.map((payment) => { + for (const updatedItem of updatedItems) { + if (!updatedItem.payments) { + continue; + } + + for (const payment of updatedItem.payments) { /* eslint-disable functional/immutable-data */ if (payment.pagoPA && documentsUploaded[payment.pagoPA.id]) { payment.pagoPA.ref.key = documentsUploaded[payment.pagoPA.id].key; @@ -180,8 +188,8 @@ export const uploadNotificationPaymentDocument = createAsyncThunk< payment.f24.ref.versionToken = documentsUploaded[payment.f24.id].versionToken; } /* eslint-enable functional/immutable-data */ - }); - }); + } + } return updatedItems; } catch (e) { From 0ec721ea1a704278ec3389400ca070a8576a9ae8 Mon Sep 17 00:00:00 2001 From: alessandrogelmi Date: Fri, 14 Feb 2025 16:53:34 +0100 Subject: [PATCH 4/8] fix: mock rename --- .../pn-pa-webapp/src/__mocks__/NewNotification.mock.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts index b636f4f096..d488e16d21 100644 --- a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts +++ b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts @@ -52,11 +52,11 @@ const newNotificationPagoPa: NewNotificationDocument = { }, }; -const newNotificationF24Standard: NewNotificationDocument = { +const newNotificationF24: NewNotificationDocument = { id: 'mocked-f24standard-id', idx: 0, name: 'mocked-name', - contentType: 'application/pdf', + contentType: 'application/json', file: { data: new File([''], 'mocked-name', { type: 'application/pdf' }), sha256: { @@ -114,7 +114,7 @@ const newNotificationRecipients: Array = [ payments: [ { pagoPA: { ...newNotificationPagoPa }, - f24: { ...newNotificationF24Standard }, + f24: { ...newNotificationF24 }, }, ], }, @@ -167,7 +167,7 @@ export const payments = { }, [newNotificationRecipients[1].taxId]: { pagoPa: { ...newNotificationPagoPa }, - f24: { ...newNotificationF24Standard }, + f24: { ...newNotificationF24 }, }, }; From 568eb6dcdd9762275bc05d392013c9bb1f343180 Mon Sep 17 00:00:00 2001 From: alessandrogelmi Date: Fri, 14 Feb 2025 16:54:04 +0100 Subject: [PATCH 5/8] fix: rename setPaymentDocuments with setPayments --- .../src/components/NewNotification/PaymentMethods.tsx | 8 ++++---- .../src/redux/newNotification/__test__/reducers.test.ts | 6 +++--- .../pn-pa-webapp/src/redux/newNotification/reducers.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx b/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx index e35fb22ae7..be98875a39 100644 --- a/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx +++ b/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx @@ -14,7 +14,7 @@ import { } from '../../models/NewNotification'; import { useAppDispatch } from '../../redux/hooks'; import { uploadNotificationPaymentDocument } from '../../redux/newNotification/actions'; -import { setIsCompleted, setPaymentDocuments } from '../../redux/newNotification/reducers'; +import { setIsCompleted, setPayments } from '../../redux/newNotification/reducers'; import NewNotificationCard from './NewNotificationCard'; type PaymentBoxProps = { @@ -175,7 +175,7 @@ const PaymentMethods: React.FC = ({ const handlePreviousStep = () => { if (onPreviousStep) { - dispatch(setPaymentDocuments({ recipients: notification.recipients })); + dispatch(setPayments({ recipients: notification.recipients })); onPreviousStep(); } }; @@ -221,7 +221,7 @@ const PaymentMethods: React.FC = ({ // Maybe now the form is empty, but in the previous time the user went back // from the payments step the form wasn't empty. // Just in case, we clean the payment info from the Redux store - // dispatch(setPaymentDocuments({ paymentDocuments: {} })); + // dispatch(setPayments({ paymentDocuments: {} })); dispatch(setIsCompleted()); } else { // Beware! - @@ -283,7 +283,7 @@ const PaymentMethods: React.FC = ({ useImperativeHandle(forwardedRef, () => ({ confirm() { - dispatch(setPaymentDocuments({ recipients: notification.recipients })); + dispatch(setPayments({ recipients: notification.recipients })); }, })); 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 9bb9061fec..a2d945e54a 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 @@ -21,7 +21,7 @@ import { setAttachments, setCancelledIun, setIsCompleted, - setPaymentDocuments, + setPayments, setPreliminaryInformations, setSenderInfos, } from '../reducers'; @@ -170,8 +170,8 @@ describe('New notification redux state tests', () => { }); it('Should be able to save payment documents', () => { - const action = store.dispatch(setPaymentDocuments({ recipients: newNotification.recipients })); - expect(action.type).toBe('newNotificationSlice/setPaymentDocuments'); + const action = store.dispatch(setPayments({ recipients: newNotification.recipients })); + expect(action.type).toBe('newNotificationSlice/setPayments'); expect(action.payload).toEqual({ recipients: newNotification.recipients }); }); diff --git a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts index 062a180d17..0f4355d8be 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts @@ -75,7 +75,7 @@ const newNotificationSlice = createSlice({ ) => { state.notification.documents = action.payload.documents; }, - setPaymentDocuments: ( + setPayments: ( state, action: PayloadAction<{ recipients: Array }> ) => { @@ -113,7 +113,7 @@ export const { setPreliminaryInformations, saveRecipients, setAttachments, - setPaymentDocuments, + setPayments, resetState, setIsCompleted, } = newNotificationSlice.actions; From 7c77c8b1252ed324890415f769e592eb6cf0fa69 Mon Sep 17 00:00:00 2001 From: alessandrogelmi Date: Mon, 17 Feb 2025 12:23:11 +0100 Subject: [PATCH 6/8] fix: refactor types and fix tests --- .../src/__mocks__/NewNotification.mock.ts | 12 +++- .../NewNotification/PaymentMethods.tsx | 2 +- .../src/models/NewNotification.ts | 59 ++++++++++------ .../newNotification/__test__/reducers.test.ts | 70 +++++++++++-------- .../src/redux/newNotification/actions.ts | 15 ++-- .../src/redux/newNotification/reducers.ts | 2 + .../src/utility/notification.utility.ts | 25 +++++-- 7 files changed, 121 insertions(+), 64 deletions(-) diff --git a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts index 4f47f550ec..ad08df054c 100644 --- a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts +++ b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts @@ -10,6 +10,8 @@ import { NewNotification, NewNotificationDigitalAddressType, NewNotificationDocument, + NewNotificationF24Payment, + NewNotificationPagoPaPayment, NewNotificationRecipient, NotificationFeePolicy, } from '../models/NewNotification'; @@ -35,11 +37,14 @@ export const newNotificationGroups: Array = [ }, ]; -const newNotificationPagoPa: NewNotificationDocument = { +const newNotificationPagoPa: NewNotificationPagoPaPayment = { id: 'mocked-pagopa-id', idx: 0, name: 'mocked-name', contentType: 'application/pdf', + creditorTaxId: 'mocked-creditor-taxid', + noticeCode: 'mocked-noticecode', + applyCost: true, file: { data: new File([''], 'mocked-name', { type: 'application/pdf' }), sha256: { @@ -53,11 +58,12 @@ const newNotificationPagoPa: NewNotificationDocument = { }, }; -const newNotificationF24: NewNotificationDocument = { +const newNotificationF24: NewNotificationF24Payment = { id: 'mocked-f24standard-id', idx: 0, name: 'mocked-name', contentType: 'application/json', + applyCost: false, file: { data: new File([''], 'mocked-name', { type: 'application/pdf' }), sha256: { @@ -71,7 +77,7 @@ const newNotificationF24: NewNotificationDocument = { }, }; -const newNotificationRecipients: Array = [ +export const newNotificationRecipients: Array = [ { id: 'recipient.0', idx: 0, diff --git a/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx b/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx index be98875a39..22affdb1d0 100644 --- a/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx +++ b/packages/pn-pa-webapp/src/components/NewNotification/PaymentMethods.tsx @@ -238,7 +238,7 @@ const PaymentMethods: React.FC = ({ // -------------------------------------- // Carlos Lombardi, 2023.01.19 const paymentData = await dispatch( - uploadNotificationPaymentDocument(formatPaymentDocuments()) + uploadNotificationPaymentDocument(notification.recipients) ); const paymentPayload = paymentData.payload as { [key: string]: PaymentObject }; if (paymentPayload) { diff --git a/packages/pn-pa-webapp/src/models/NewNotification.ts b/packages/pn-pa-webapp/src/models/NewNotification.ts index 9cb6ffa325..9fcab42f7a 100644 --- a/packages/pn-pa-webapp/src/models/NewNotification.ts +++ b/packages/pn-pa-webapp/src/models/NewNotification.ts @@ -24,9 +24,46 @@ enum PagoPaIntegrationMode { ASYNC = 'ASYNC', } +interface BaseNewNotificationDocument { + id: string; + idx: number; + name: string; + contentType: string; +} + +interface NewNotificationDocumentFile { + data?: File; + sha256: { + hashBase64: string; + hashHex: string; + }; +} + +interface NewNotificationDocumentRef { + key: string; + versionToken: string; +} + +export interface NewNotificationDocument extends BaseNewNotificationDocument { + file: NewNotificationDocumentFile; + ref: NewNotificationDocumentRef; +} + +export interface NewNotificationPagoPaPayment extends BaseNewNotificationDocument { + creditorTaxId: string; + noticeCode: string; + applyCost: boolean; + file?: NewNotificationDocumentFile; + ref?: NewNotificationDocumentRef; +} + +export interface NewNotificationF24Payment extends NewNotificationDocument { + applyCost: boolean; +} + export interface NewNotificationPayment { - pagoPA?: NewNotificationDocument; - f24?: NewNotificationDocument; + pagoPA?: NewNotificationPagoPaPayment; + f24?: NewNotificationF24Payment; } // New Notification @@ -50,24 +87,6 @@ export interface NewNotificationRecipient { payments?: Array; } -export interface NewNotificationDocument { - id: string; - idx: number; - name: string; - contentType: string; - file: { - data?: File; - sha256: { - hashBase64: string; - hashHex: string; - }; - }; - ref: { - key: string; - versionToken: string; - }; -} - export interface NewNotification extends NewNotificationBilingualism { notificationFeePolicy: NotificationFeePolicy; idempotenceToken?: 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 61c8a190ab..ca212f276a 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 @@ -3,9 +3,14 @@ import MockAdapter from 'axios-mock-adapter'; import { PhysicalCommunicationType } from '@pagopa-pn/pn-commons'; import { mockAuthentication } from '../../../__mocks__/Auth.mock'; -import { newNotification, payments } from '../../../__mocks__/NewNotification.mock'; +import { + newNotification, + newNotificationRecipients, + payments, +} from '../../../__mocks__/NewNotification.mock'; import { apiClient, externalClient } from '../../../api/apiClients'; -import { PaymentModel, PaymentObject, PreliminaryInformationsPayload } from '../../../models/NewNotification'; +import { NotificationFeePolicy } from '../../../generated-client/notifications'; +import { PaymentModel, PreliminaryInformationsPayload } from '../../../models/NewNotification'; import { GroupStatus } from '../../../models/user'; import { newNotificationMapper } from '../../../utility/notification.utility'; import { store } from '../../store'; @@ -29,6 +34,7 @@ import { const initialState = { loading: false, notification: { + notificationFeePolicy: NotificationFeePolicy.FlatRate, paProtocolNumber: '', subject: '', recipients: [], @@ -37,7 +43,7 @@ const initialState = { group: '', taxonomyCode: '', senderDenomination: '', - senderTaxId:'' + senderTaxId: '', }, groups: [], isCompleted: false, @@ -183,7 +189,7 @@ describe('New notification redux state tests', () => { if (elem.pagoPa) { arr.push({ contentType: elem.pagoPa.contentType, - sha256: elem.pagoPa.file.sha256.hashBase64, + sha256: elem.pagoPa.file?.sha256.hashBase64, }); } if (elem.f24) { @@ -218,7 +224,7 @@ describe('New notification redux state tests', () => { const extMock = new MockAdapter(externalClient); for (const payment of Object.values(payments)) { if (payment.pagoPa) { - extMock.onPost(`https://mocked-url.com`).reply(200, payment.pagoPa.file.data, { + extMock.onPost(`https://mocked-url.com`).reply(200, payment.pagoPa.file?.data, { 'x-amz-version-id': 'mocked-versionToken', }); } @@ -228,31 +234,37 @@ describe('New notification redux state tests', () => { }); } } - const action = await store.dispatch(uploadNotificationPaymentDocument(payments)); + const action = await store.dispatch( + uploadNotificationPaymentDocument(newNotificationRecipients) + ); expect(action.type).toBe('uploadNotificationPaymentDocument/fulfilled'); - const response: { [key: string]: PaymentObject } = {}; - for (const [key, value] of Object.entries(payments)) { - response[key] = {} as PaymentObject; - if (value.pagoPa) { - response[key].pagoPa = { - ...value.pagoPa, - ref: { - key: 'mocked-preload-key', - versionToken: 'mocked-versionToken', - }, - }; - } - if (value.f24) { - response[key].f24 = { - ...value.f24, - ref: { - key: 'mocked-preload-key', - versionToken: 'mocked-versionToken', - }, - }; - } - } - expect(action.payload).toEqual(response); + + const expectedResponse = newNotificationRecipients.map((recipient) => ({ + ...recipient, + payments: recipient.payments?.map((payment) => ({ + ...payment, + pagoPA: payment.pagoPA + ? { + ...payment.pagoPA, + ref: { + key: 'mocked-preload-key', + versionToken: 'mocked-versionToken', + }, + } + : undefined, + f24: payment.f24 + ? { + ...payment.f24, + ref: { + key: 'mocked-preload-key', + versionToken: 'mocked-versionToken', + }, + } + : undefined, + })), + })); + + expect(action.payload).toEqual(expectedResponse); extMock.restore(); }); diff --git a/packages/pn-pa-webapp/src/redux/newNotification/actions.ts b/packages/pn-pa-webapp/src/redux/newNotification/actions.ts index 47b9dff8a5..4619e9a97e 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/actions.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/actions.ts @@ -14,12 +14,14 @@ import { import { NewNotification, NewNotificationDocument, + NewNotificationF24Payment, + NewNotificationPagoPaPayment, NewNotificationRecipient, UploadDocumentParams, UploadDocumentsResponse, } from '../../models/NewNotification'; import { GroupStatus, UserGroup } from '../../models/user'; -import { newNotificationMapper } from '../../utility/notification.utility'; +import { hasPagoPaDocument, newNotificationMapper } from '../../utility/notification.utility'; export enum NEW_NOTIFICATION_ACTIONS { GET_USER_GROUPS = 'getUserGroups', @@ -44,7 +46,7 @@ export const getUserGroups = createAsyncThunk( ); const createPayloadToUpload = async ( - item: NewNotificationDocument + item: NewNotificationDocument | Required | NewNotificationF24Payment ): Promise => { const unit8Array = await calcUnit8Array(item.file.data); return { @@ -144,7 +146,12 @@ const getPaymentDocumentsToUpload = ( } for (const payment of recipient.payments) { - if (payment.pagoPA && !payment.pagoPA.ref.key && !payment.pagoPA.ref.versionToken) { + if ( + payment.pagoPA && + hasPagoPaDocument(payment.pagoPA) && + !payment.pagoPA.ref.key && + !payment.pagoPA.ref.versionToken + ) { documentsArr.push(createPayloadToUpload(payment.pagoPA)); } @@ -180,7 +187,7 @@ export const uploadNotificationPaymentDocument = createAsyncThunk< for (const payment of updatedItem.payments) { /* eslint-disable functional/immutable-data */ - if (payment.pagoPA && documentsUploaded[payment.pagoPA.id]) { + if (payment.pagoPA && payment.pagoPA.ref && documentsUploaded[payment.pagoPA.id]) { payment.pagoPA.ref.key = documentsUploaded[payment.pagoPA.id].key; payment.pagoPA.ref.versionToken = documentsUploaded[payment.pagoPA.id].versionToken; } diff --git a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts index bd7f23f7d2..06fa39c89b 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/reducers.ts @@ -5,6 +5,7 @@ import { NewNotification, NewNotificationDocument, NewNotificationRecipient, + NotificationFeePolicy, PreliminaryInformationsPayload, } from '../../models/NewNotification'; import { UserGroup } from '../../models/user'; @@ -26,6 +27,7 @@ type NewNotificationInitialState = { const initialState: NewNotificationInitialState = { loading: false, notification: { + notificationFeePolicy: NotificationFeePolicy.FLAT_RATE, paProtocolNumber: '', subject: '', recipients: [], diff --git a/packages/pn-pa-webapp/src/utility/notification.utility.ts b/packages/pn-pa-webapp/src/utility/notification.utility.ts index 676c9daa3a..34d9e8804c 100644 --- a/packages/pn-pa-webapp/src/utility/notification.utility.ts +++ b/packages/pn-pa-webapp/src/utility/notification.utility.ts @@ -15,7 +15,9 @@ import { import { NewNotification, NewNotificationDocument, + NewNotificationF24Payment, NewNotificationLangOther, + NewNotificationPagoPaPayment, NewNotificationPayment, NewNotificationRecipient, } from '../models/NewNotification'; @@ -69,7 +71,10 @@ const newNotificationRecipientsMapper = ( }); const newNotificationDocumentMapper = ( - document: NewNotificationDocument + document: + | NewNotificationDocument + | Required + | NewNotificationF24Payment ): NotificationDetailDocument => ({ digests: { sha256: document.file.sha256.hashBase64, @@ -84,6 +89,10 @@ const newNotificationAttachmentsMapper = ( ): Array => documents.map((document) => newNotificationDocumentMapper(document)); +export const hasPagoPaDocument = ( + document: NewNotificationPagoPaPayment +): document is Required => !!document.file && !!document.ref; + const newNotificationPaymentDocumentsMapper = ( recipientPayments: Array ): Array => @@ -91,19 +100,21 @@ const newNotificationPaymentDocumentsMapper = ( const mappedPayment: NotificationDetailPayment = {}; /* eslint-disable functional/immutable-data */ - if (payment.pagoPA && payment.pagoPA.file.sha256.hashBase64 !== '') { + if (payment.pagoPA && payment.pagoPA.file?.sha256.hashBase64 !== '') { mappedPayment.pagoPa = { - creditorTaxId: '', - noticeCode: '', - attachment: newNotificationDocumentMapper(payment.pagoPA), - applyCost: false, + creditorTaxId: payment.pagoPA.creditorTaxId, + noticeCode: payment.pagoPA.noticeCode, + attachment: hasPagoPaDocument(payment.pagoPA) + ? newNotificationDocumentMapper(payment.pagoPA) + : undefined, + applyCost: payment.pagoPA.applyCost, }; } if (payment.f24 && payment.f24.file.sha256.hashBase64 !== '') { mappedPayment.f24 = { title: payment.f24.name, - applyCost: true, + applyCost: payment.f24.applyCost, metadataAttachment: { digests: { sha256: payment.f24.file.sha256.hashBase64, From 8a2e6983a3c729ce39c79e36e2a07e65be7e3960 Mon Sep 17 00:00:00 2001 From: Andrea Cimini Date: Mon, 17 Feb 2025 15:41:29 +0100 Subject: [PATCH 7/8] small fixes --- packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts | 2 +- .../src/redux/newNotification/__test__/reducers.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts index ad08df054c..05b3387549 100644 --- a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts +++ b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts @@ -65,7 +65,7 @@ const newNotificationF24: NewNotificationF24Payment = { contentType: 'application/json', applyCost: false, file: { - data: new File([''], 'mocked-name', { type: 'application/pdf' }), + data: new File([''], 'mocked-name', { type: 'application/json' }), sha256: { hashBase64: 'mocked-f24standard-sha256', hashHex: '', 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 ca212f276a..31c955b6b8 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 @@ -39,7 +39,7 @@ const initialState = { subject: '', recipients: [], documents: [], - physicalCommunicationType: 'REGISTERED_LETTER_890', + physicalCommunicationType: PhysicalCommunicationType.REGISTERED_LETTER_890, group: '', taxonomyCode: '', senderDenomination: '', From da2fc0dac7aa82416ad9057affc3887c9f0f635f Mon Sep 17 00:00:00 2001 From: Andrea Cimini Date: Mon, 17 Feb 2025 16:42:27 +0100 Subject: [PATCH 8/8] small fixes --- .../src/__mocks__/NewNotification.mock.ts | 53 ++++++++++++-- .../__test__/PreliminaryInformations.test.tsx | 6 +- .../src/models/NewNotification.ts | 25 ++++--- .../newNotification/__test__/reducers.test.ts | 4 +- .../src/redux/newNotification/actions.ts | 22 +++--- .../src/utility/notification.utility.ts | 72 +++++++++++-------- 6 files changed, 114 insertions(+), 68 deletions(-) diff --git a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts index 05b3387549..31791f287f 100644 --- a/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts +++ b/packages/pn-pa-webapp/src/__mocks__/NewNotification.mock.ts @@ -2,9 +2,11 @@ import { PhysicalCommunicationType, RecipientType } from '@pagopa-pn/pn-commons' import { BffNewNotificationRequest, + F24Payment, NotificationDigitalAddressTypeEnum, NotificationDocument, NotificationRecipientV23, + PagoPaPayment, } from '../generated-client/notifications'; import { NewNotification, @@ -40,7 +42,6 @@ export const newNotificationGroups: Array = [ const newNotificationPagoPa: NewNotificationPagoPaPayment = { id: 'mocked-pagopa-id', idx: 0, - name: 'mocked-name', contentType: 'application/pdf', creditorTaxId: 'mocked-creditor-taxid', noticeCode: 'mocked-noticecode', @@ -58,8 +59,24 @@ const newNotificationPagoPa: NewNotificationPagoPaPayment = { }, }; +const newNotificationPagoPaForBff: PagoPaPayment = { + creditorTaxId: 'mocked-creditor-taxid', + noticeCode: 'mocked-noticecode', + applyCost: true, + attachment: { + contentType: 'application/pdf', + digests: { + sha256: 'mocked-pa-sha256', + }, + ref: { + key: '', + versionToken: '', + }, + }, +}; + const newNotificationF24: NewNotificationF24Payment = { - id: 'mocked-f24standard-id', + id: 'mocked-f24-id', idx: 0, name: 'mocked-name', contentType: 'application/json', @@ -67,7 +84,7 @@ const newNotificationF24: NewNotificationF24Payment = { file: { data: new File([''], 'mocked-name', { type: 'application/json' }), sha256: { - hashBase64: 'mocked-f24standard-sha256', + hashBase64: 'mocked-f24-sha256', hashHex: '', }, }, @@ -77,6 +94,21 @@ const newNotificationF24: NewNotificationF24Payment = { }, }; +const newNotificationF24ForBff: F24Payment = { + title: 'mocked-name', + applyCost: false, + metadataAttachment: { + contentType: 'application/json', + digests: { + sha256: 'mocked-f24-sha256', + }, + ref: { + key: '', + versionToken: '', + }, + }, +}; + export const newNotificationRecipients: Array = [ { id: 'recipient.0', @@ -97,7 +129,7 @@ export const newNotificationRecipients: Array = [ foreignState: 'Italia', payments: [ { - pagoPA: { ...newNotificationPagoPa }, + pagoPa: { ...newNotificationPagoPa }, }, ], }, @@ -120,7 +152,7 @@ export const newNotificationRecipients: Array = [ foreignState: 'Italia', payments: [ { - pagoPA: { ...newNotificationPagoPa }, + pagoPa: { ...newNotificationPagoPa }, f24: { ...newNotificationF24 }, }, ], @@ -143,6 +175,11 @@ const newNotificationRecipientsForBff: Array = [ province: 'Roma', foreignState: 'Italia', }, + payments: [ + { + pagoPa: newNotificationPagoPaForBff, + }, + ], }, { taxId: '12345678901', @@ -155,6 +192,12 @@ const newNotificationRecipientsForBff: Array = [ province: 'Roma', foreignState: 'Italia', }, + payments: [ + { + pagoPa: newNotificationPagoPaForBff, + f24: newNotificationF24ForBff, + }, + ], }, ]; diff --git a/packages/pn-pa-webapp/src/components/NewNotification/__test__/PreliminaryInformations.test.tsx b/packages/pn-pa-webapp/src/components/NewNotification/__test__/PreliminaryInformations.test.tsx index 98c3b487f5..9bc56d434a 100644 --- a/packages/pn-pa-webapp/src/components/NewNotification/__test__/PreliminaryInformations.test.tsx +++ b/packages/pn-pa-webapp/src/components/NewNotification/__test__/PreliminaryInformations.test.tsx @@ -187,7 +187,7 @@ describe('PreliminaryInformations Component', async () => { expect(button).toBeDisabled(); await populateForm(form); expect(button).toBeEnabled(); - + fireEvent.click(button); await waitFor(() => { const state = testStore.getState(); @@ -198,17 +198,15 @@ describe('PreliminaryInformations Component', async () => { taxonomyCode: newNotification.taxonomyCode, group: newNotificationGroups[1].id, notificationFeePolicy: NotificationFeePolicy.FLAT_RATE, - payment: {}, documents: [], recipients: [], physicalCommunicationType: PhysicalCommunicationType.AR_REGISTERED_LETTER, - paymentMode: '', senderDenomination: newNotification.senderDenomination, lang: 'it', additionalAbstract: '', additionalLang: '', additionalSubject: '', - senderTaxId: '' + senderTaxId: '', }); }); expect(confirmHandlerMk).toHaveBeenCalledTimes(1); diff --git a/packages/pn-pa-webapp/src/models/NewNotification.ts b/packages/pn-pa-webapp/src/models/NewNotification.ts index 9fcab42f7a..12c64bc883 100644 --- a/packages/pn-pa-webapp/src/models/NewNotification.ts +++ b/packages/pn-pa-webapp/src/models/NewNotification.ts @@ -24,14 +24,7 @@ enum PagoPaIntegrationMode { ASYNC = 'ASYNC', } -interface BaseNewNotificationDocument { - id: string; - idx: number; - name: string; - contentType: string; -} - -interface NewNotificationDocumentFile { +export interface NewNotificationDocumentFile { data?: File; sha256: { hashBase64: string; @@ -39,17 +32,24 @@ interface NewNotificationDocumentFile { }; } -interface NewNotificationDocumentRef { +export interface NewNotificationDocumentRef { key: string; versionToken: string; } -export interface NewNotificationDocument extends BaseNewNotificationDocument { +export interface NewNotificationDocument { + id: string; + idx: number; + contentType: string; + name: string; file: NewNotificationDocumentFile; ref: NewNotificationDocumentRef; } -export interface NewNotificationPagoPaPayment extends BaseNewNotificationDocument { +export interface NewNotificationPagoPaPayment { + id: string; + idx: number; + contentType: string; creditorTaxId: string; noticeCode: string; applyCost: boolean; @@ -62,7 +62,7 @@ export interface NewNotificationF24Payment extends NewNotificationDocument { } export interface NewNotificationPayment { - pagoPA?: NewNotificationPagoPaPayment; + pagoPa?: NewNotificationPagoPaPayment; f24?: NewNotificationF24Payment; } @@ -132,7 +132,6 @@ export interface PreliminaryInformationsPayload extends NewNotificationBilingual export interface UploadDocumentParams { id: string; - key: string; contentType: string; file: Uint8Array | undefined; sha256: 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 31c955b6b8..e420192b1f 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 @@ -243,9 +243,9 @@ describe('New notification redux state tests', () => { ...recipient, payments: recipient.payments?.map((payment) => ({ ...payment, - pagoPA: payment.pagoPA + pagoPa: payment.pagoPa ? { - ...payment.pagoPA, + ...payment.pagoPa, ref: { key: 'mocked-preload-key', versionToken: 'mocked-versionToken', diff --git a/packages/pn-pa-webapp/src/redux/newNotification/actions.ts b/packages/pn-pa-webapp/src/redux/newNotification/actions.ts index 4619e9a97e..702ca244df 100644 --- a/packages/pn-pa-webapp/src/redux/newNotification/actions.ts +++ b/packages/pn-pa-webapp/src/redux/newNotification/actions.ts @@ -7,7 +7,6 @@ import { apiClient } from '../../api/apiClients'; import { NotificationsApi } from '../../api/notifications/Notifications.api'; import { InfoPaApiFactory } from '../../generated-client/info-pa'; import { - BffNewNotificationRequest, BffNewNotificationResponse, NotificationSentApiFactory, } from '../../generated-client/notifications'; @@ -51,7 +50,6 @@ const createPayloadToUpload = async ( const unit8Array = await calcUnit8Array(item.file.data); return { id: item.id, - key: item.name, contentType: item.contentType, file: unit8Array, sha256: item.file.sha256.hashBase64, @@ -147,12 +145,12 @@ const getPaymentDocumentsToUpload = ( for (const payment of recipient.payments) { if ( - payment.pagoPA && - hasPagoPaDocument(payment.pagoPA) && - !payment.pagoPA.ref.key && - !payment.pagoPA.ref.versionToken + payment.pagoPa && + hasPagoPaDocument(payment.pagoPa) && + !payment.pagoPa.ref.key && + !payment.pagoPa.ref.versionToken ) { - documentsArr.push(createPayloadToUpload(payment.pagoPA)); + documentsArr.push(createPayloadToUpload(payment.pagoPa)); } if (payment.f24 && !payment.f24.ref.key && !payment.f24.ref.versionToken) { @@ -187,9 +185,9 @@ export const uploadNotificationPaymentDocument = createAsyncThunk< for (const payment of updatedItem.payments) { /* eslint-disable functional/immutable-data */ - if (payment.pagoPA && payment.pagoPA.ref && documentsUploaded[payment.pagoPA.id]) { - payment.pagoPA.ref.key = documentsUploaded[payment.pagoPA.id].key; - payment.pagoPA.ref.versionToken = documentsUploaded[payment.pagoPA.id].versionToken; + if (payment.pagoPa?.ref && documentsUploaded[payment.pagoPa.id]) { + payment.pagoPa.ref.key = documentsUploaded[payment.pagoPa.id].key; + payment.pagoPa.ref.versionToken = documentsUploaded[payment.pagoPa.id].versionToken; } if (payment.f24 && documentsUploaded[payment.f24.id]) { payment.f24.ref.key = documentsUploaded[payment.f24.id].key; @@ -216,9 +214,7 @@ export const createNewNotification = createAsyncThunk - | NewNotificationF24Payment -): NotificationDetailDocument => ({ +const newNotificationDocumentMapper = (document: { + file: NewNotificationDocumentFile; + ref: NewNotificationDocumentRef; + contentType: string; +}): NotificationDetailDocument => ({ digests: { sha256: document.file.sha256.hashBase64, }, contentType: document.contentType, ref: document.ref, - title: document.name, }); const newNotificationAttachmentsMapper = ( documents: Array -): Array => - documents.map((document) => newNotificationDocumentMapper(document)); +): Array => + documents.map((document) => ({ + ...newNotificationDocumentMapper({ + file: document.file, + ref: document.ref, + contentType: document.contentType, + }), + title: document.name, + })); export const hasPagoPaDocument = ( document: NewNotificationPagoPaPayment @@ -95,33 +98,40 @@ export const hasPagoPaDocument = ( const newNotificationPaymentDocumentsMapper = ( recipientPayments: Array -): Array => +): Array => recipientPayments.map((payment) => { - const mappedPayment: NotificationDetailPayment = {}; + const mappedPayment: NotificationPaymentItem = {}; /* eslint-disable functional/immutable-data */ - if (payment.pagoPA && payment.pagoPA.file?.sha256.hashBase64 !== '') { + if (payment.pagoPa) { mappedPayment.pagoPa = { - creditorTaxId: payment.pagoPA.creditorTaxId, - noticeCode: payment.pagoPA.noticeCode, - attachment: hasPagoPaDocument(payment.pagoPA) - ? newNotificationDocumentMapper(payment.pagoPA) - : undefined, - applyCost: payment.pagoPA.applyCost, + creditorTaxId: payment.pagoPa.creditorTaxId, + noticeCode: payment.pagoPa.noticeCode, + applyCost: payment.pagoPa.applyCost, }; + + if ( + payment.pagoPa.file && + payment.pagoPa.ref && + payment.pagoPa.file?.sha256.hashBase64 !== '' + ) { + mappedPayment.pagoPa.attachment = newNotificationDocumentMapper({ + file: payment.pagoPa.file, + ref: payment.pagoPa.ref, + contentType: payment.pagoPa.contentType, + }); + } } if (payment.f24 && payment.f24.file.sha256.hashBase64 !== '') { mappedPayment.f24 = { title: payment.f24.name, applyCost: payment.f24.applyCost, - metadataAttachment: { - digests: { - sha256: payment.f24.file.sha256.hashBase64, - }, - contentType: payment.f24.contentType, + metadataAttachment: newNotificationDocumentMapper({ + file: payment.f24.file, ref: payment.f24.ref, - }, + contentType: payment.f24.contentType, + }), }; } /* eslint-enable functional/immutable-data */